Variabel $ _SERVER mana yang aman?

97

Variabel apa pun yang dapat dikontrol oleh pengguna, juga dapat dikontrol oleh penyerang dan oleh karena itu merupakan sumber serangan. Ini disebut variabel "tercemar", dan tidak aman.

Saat menggunakan $_SERVER, banyak variabel dapat dikontrol. PHP_SELF, HTTP_USER_AGENT, HTTP_X_FORWARDED_FOR, HTTP_ACCEPT_LANGUAGEDan banyak lainnya adalah bagian dari header permintaan HTTP yang dikirim oleh klien.

Adakah yang tahu tentang "daftar aman" atau daftar $_SERVERvariabel yang tidak ternoda ?

benteng
sumber
8
Tergantung bagaimana Anda mendefinisikan "aman". Semua nilai aman sebagaimana adanya, hanya tergantung untuk apa Anda menggunakannya.
menipu
6
Saya rasa dalam konteks ini, Rook mengatakan "Variabel server mana yang tidak dapat dipalsukan oleh pengguna", seperti REMOTE_ADDR.
vcsjones
6
Apa pun yang diawali dengan HTTP_adalah header permintaan dan dapat disetel oleh browser atau proxy di antaranya. Saya akan menganggapnya sebagai masukan pengguna lainnya.
dataage
3
@ bob-the-destroyer REMOTE_ADDR ditarik langsung dari soket TCP apache, nilai ini tidak dapat dipalsukan melalui Internet karena jabat tangan tiga arah.
Benteng
2
@ Benteng: poin bagus. Saya kira dengan penyebutan "spoofing", saya lebih condong ke tindakan lama ip spoofing itu sendiri, daripada memalsukan nilai sebenarnya REMOTE_ADDR. Dan itu berada di luar cakupan pertanyaan ini. Bagus untuk mendapatkan beberapa wawasan tentang bagaimana nilai ini ditetapkan, jadi terima kasih.
bob-the-destroyer

Jawaban:

147

Tidak ada yang namanya nilai "aman" atau "tidak aman". Hanya ada nilai-nilai yang dikendalikan oleh server dan nilai-nilai yang dikontrol oleh pengguna dan Anda perlu mengetahui dari mana suatu nilai berasal dan karenanya dapat dipercaya untuk tujuan tertentu. $_SERVER['HTTP_FOOBAR']misalnya sepenuhnya aman untuk disimpan dalam database, tetapi saya pasti tidak akan evalmelakukannya.

Karena itu, mari bagi nilai-nilai itu menjadi tiga kategori:

Server dikendalikan

Variabel ini ditetapkan oleh lingkungan server dan bergantung sepenuhnya pada konfigurasi server.

  • 'GATEWAY_INTERFACE'
  • 'SERVER_ADDR'
  • 'SERVER_SOFTWARE'
  • 'DOCUMENT_ROOT'
  • 'SERVER_ADMIN'
  • 'SERVER_SIGNATURE'

Sebagian terkontrol server

Variabel ini bergantung pada permintaan khusus yang dikirim klien, tetapi hanya dapat mengambil nilai valid dalam jumlah terbatas, karena semua nilai yang tidak valid harus ditolak oleh server web dan tidak menyebabkan pemanggilan skrip untuk memulai. Karenanya mereka dapat dianggap dapat diandalkan .

  • 'HTTPS'
  • 'REQUEST_TIME'
  • 'REMOTE_ADDR' *
  • 'REMOTE_HOST' *
  • 'REMOTE_PORT' *
  • 'SERVER_PROTOCOL'
  • 'HTTP_HOST'
  • 'SERVER_NAME'
  • 'SCRIPT_FILENAME'
  • 'SERVER_PORT'
  • 'SCRIPT_NAME'

* REMOTE_Nilai dijamin menjadi alamat klien yang valid, seperti yang diverifikasi oleh jabat tangan TCP / IP. Ini adalah alamat di mana tanggapan akan dikirim. REMOTE_HOSTbergantung pada pencarian DNS terbalik dan karenanya dapat dipalsukan oleh serangan DNS terhadap server Anda (dalam hal ini Anda tetap memiliki masalah yang lebih besar). Nilai ini mungkin proxy, yang merupakan realitas sederhana dari protokol TCP / IP dan tidak ada yang dapat Anda lakukan.

† Jika server web Anda merespons permintaan apa pun tanpa memandang HOSTheader, ini juga dianggap tidak aman. Lihat Seberapa amankah $ _SERVER [“HTTP_HOST”]? .
Lihat juga http://shiflett.org/blog/2006/mar/server-name-versus-http-host .

‡ Lihat https://bugs.php.net/bug.php?id=64457 , http://httpd.apache.org/docs/current/mod/core.html#usecanonicalphysicalport , http: //httpd.apache. org / docs / 2.4 / mod / core.html # comment_999

Nilai yang dikontrol pengguna sepenuhnya sewenang-wenang

Nilai-nilai ini tidak diperiksa sama sekali dan tidak bergantung pada konfigurasi server apa pun, mereka sepenuhnya merupakan informasi sewenang-wenang yang dikirim oleh klien.

  • 'argv', 'argc'(hanya berlaku untuk permintaan CLI, biasanya bukan masalah server web)
  • 'REQUEST_METHOD' §
  • 'QUERY_STRING'
  • 'HTTP_ACCEPT'
  • 'HTTP_ACCEPT_CHARSET'
  • 'HTTP_ACCEPT_ENCODING'
  • 'HTTP_ACCEPT_LANGUAGE'
  • 'HTTP_CONNECTION'
  • 'HTTP_REFERER'
  • 'HTTP_USER_AGENT'
  • 'AUTH_TYPE'
  • 'PHP_AUTH_DIGEST'
  • 'PHP_AUTH_USER'
  • 'PHP_AUTH_PW'
  • 'PATH_INFO'
  • 'ORIG_PATH_INFO'
  • 'REQUEST_URI' (mungkin berisi data tercemar)
  • 'PHP_SELF' (mungkin berisi data tercemar)
  • 'PATH_TRANSLATED'
  • 'HTTP_'nilai lainnya

§ Dapat dianggap dapat diandalkan selama web server hanya mengizinkan metode permintaan tertentu.

‖ Dapat dianggap andal jika otentikasi ditangani sepenuhnya oleh server web.

Superglobal $_SERVERjuga mencakup beberapa variabel lingkungan. Apakah ini "aman" atau tidak tergantung pada bagaimana (dan di mana) mereka didefinisikan. Mereka dapat berkisar dari sepenuhnya dikendalikan server hingga sepenuhnya dikendalikan oleh pengguna.

menipu
sumber
3
@ Rook Tapi seperti yang saya katakan, itu benar-benar tergantung pada bagaimana Anda menggunakannya . Nilai dengan sendirinya tidak aman atau tidak aman, itu tergantung pada tujuan Anda menggunakannya . Bahkan data yang dikirim dari pengguna jahat sangat aman selama Anda tidak melakukan apa pun yang dapat membahayakan keamanan Anda.
menipu
2
@Rook: ide Anda tentang "aman" membuat pertanyaan ini tampak agak sewenang-wenang, terutama karena ini sepenuhnya terkait dengan ekstensi yang tidak jelas atau versi khusus PHP. Meskipun Anda mengatakan "seharusnya tidak memiliki" pendekatan "tembak dari pinggul", jawaban apa pun sebenarnya tampaknya memerlukan minimal keakraban dengan kode sumber PHP untuk mengetahui bagaimana nilai-nilai ini ditetapkan. Akankah mengirim email pengembang PHP bukan pendekatan yang lebih baik untuk menemukan jawaban?
bob-the-destroyer
2
@ Benteng: Miskomunikasi. Seperti tipuan yang diisyaratkan, "aman untuk tujuan apa". Seperti yang saya nyatakan, tujuan Anda tidak diketahui, dan selain itu ada beberapa $_SERVERnilai tidak terdokumentasi lainnya tergantung pada bagaimana file tersebut disajikan. Menurut saya, yang terdokumentasi tidak menjelaskan sumber sebenarnya. Jika tidak, saya yakin Anda tidak akan menanyakan pertanyaan ini. Senang Anda punya daftar yang bisa Anda gunakan. Tetapi saya tetap menyarankan untuk mengirimkan laporan bug (ketika situs bug mereka diperbaiki), mengirim email kepada pengelola dokumen, atau memperbarui dokumen sendiri (jika Anda mengetahui rahasia tautan tersebut). Akan bermanfaat bagi komunitas untuk mengetahui info ini.
bob-the-destroyer
3
SERVER_NAMEtidak selalu dikontrol oleh server. Tergantung pada gateway dan pengaturannya, ini dapat diduplikasi dari HTTP_HOSTdan karenanya tunduk pada peringatan yang sama.
bobince
1
@ Deceze @ Rook Apakah SERVER_PORTperlu salib kecil itu? bugs.php.net/bug.php?id=64457
Dejan Marjanović
12

Dalam PHP setiap $_SERVERvariabel yang dimulai dengan HTTP_dapat dipengaruhi oleh pengguna. Misalnya variabel $_SERVER['HTTP_REINERS']dapat dinodai dengan menyetel header HTTP REINERSke nilai arbitrer dalam permintaan HTTP.

Reiners
sumber
kembali "sewenang-wenang"; Tidak seluruhnya sewenang-wenang karena sesuai dengan format. Misalnya, $_SERVER['HTTP_REINERS'] tidak dapat berisi karakter baris baru di bawah kebanyakan sapis.
Pacerier