Hangi $ _SERVER değişkenleri güvenlidir?


97

Bir kullanıcının kontrol edebileceği herhangi bir değişkeni, bir saldırgan da kontrol edebilir ve bu nedenle bir saldırı kaynağıdır. Buna "bozuk" değişken denir ve güvensizdir.

Kullanılırken $_SERVER, değişkenlerin çoğu kontrol edilebilir. PHP_SELF, HTTP_USER_AGENT, HTTP_X_FORWARDED_FOR, HTTP_ACCEPT_LANGUAGEÇok ve diğerleri istemci tarafından gönderilen HTTP istek başlığının bir parçasıdır.

"Güvenli bir liste" veya $_SERVERdeğişkenlerin temizlenmemiş bir listesini bilen var mı ?


8
"Güvenli" i nasıl tanımladığınıza bağlıdır. Değerler oldukları gibi güvenlidir , yalnızca onları ne için kullandığınıza bağlıdır.
kestirmek

6
Sanırım bu bağlamda Rook, "Hangi sunucu değişkenleri kullanıcı tarafından yanıltılamaz" gibi REMOTE_ADDR.
vcsjones

6
Önünde bulunan her şey HTTP_bir istek başlığıdır ve aradaki tarayıcı veya proxy tarafından ayarlanabilir. Bunları başka herhangi bir kullanıcı girdisi olarak kabul ediyorum.
datasage

3
@ bob-the-destroyer REMOTE_ADDR, apache'nin TCP soketinden doğrudan çekilir, bu değer , üç yönlü el sıkışması nedeniyle İnternet üzerinden yanıltılamaz .
kale

2
@Rook: iyi nokta. Sanırım "sahtekarlıktan" bahsetmekle, gerçek değerini herhangi bir şekilde taklit etmektense, eski ip sahtekarlığı eylemine daha çok eğildim REMOTE_ADDR. Ve bu, bu sorunun kapsamı dışında olacaktır. Yine de bu değerin nasıl belirlendiğine dair biraz fikir edinmek güzel, bu yüzden teşekkürler.
bob-the-destroyer

Yanıtlar:


147

"Güvenli" veya "güvensiz" değerler diye bir şey yoktur. Yalnızca sunucunun kontrol ettiği ve kullanıcının kontrol ettiği değerler vardır ve bir değerin nereden geldiğinin ve dolayısıyla belirli bir amaç için ona güvenilip güvenilmeyeceğinin farkında olmanız gerekir. $_SERVER['HTTP_FOOBAR']örneğin bir veritabanında saklamak tamamen güvenlidir, ama kesinlikle istemezdim eval.

Bu nedenle, bu değerleri üç kategoriye ayıralım:

Sunucu kontrollü

Bu değişkenler sunucu ortamı tarafından belirlenir ve tamamen sunucu yapılandırmasına bağlıdır.

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

Kısmen sunucu kontrollü

Bu değişkenler, istemcinin gönderdiği özel isteğe bağlıdır, ancak yalnızca sınırlı sayıda geçerli değer alabilir, çünkü tüm geçersiz değerler web sunucusu tarafından reddedilmelidir ve komut dosyasının başlatılmasına neden olmamalıdır. Dolayısıyla güvenilir oldukları düşünülebilir .

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

* REMOTE_Değerlerin, bir TCP / IP el sıkışmasıyla doğrulanan, istemcinin geçerli adresi olduğu garanti edilir. Bu, herhangi bir yanıtın gönderileceği adrestir. REMOTE_HOSTyine de ters DNS aramalarına dayanır ve bu nedenle sunucunuza yapılan DNS saldırıları tarafından yanıltılabilir (bu durumda yine de daha büyük sorunlarınız olur). Bu değer, TCP / IP protokolünün basit bir gerçeği olan ve hakkında hiçbir şey yapamayacağınız bir proxy olabilir.

† Web sunucunuz başlıktan bağımsız olarak herhangi bir isteğe yanıt HOSTverirse, bunun da güvenli olmadığı düşünülmelidir. Bkz güvenli $ _SERVER [ “HTTP_HOST”] ne kadar? .
Ayrıca http://shiflett.org/blog/2006/mar/server-name-versus-http-host'a bakın .

‡ Bkz. 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

Tamamen rastgele kullanıcı kontrollü değerler

Bu değerler hiç kontrol edilmez ve herhangi bir sunucu yapılandırmasına bağlı değildir, tamamen istemci tarafından gönderilen rastgele bilgilerdir.

  • 'argv', 'argc'(yalnızca CLI çağrısı için geçerlidir, genellikle web sunucuları için bir sorun değildir)
  • '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' (bozuk veriler içerebilir)
  • 'PHP_SELF' (bozuk veriler içerebilir)
  • 'PATH_TRANSLATED'
  • başka herhangi bir 'HTTP_'değer

§ Web sunucusu yalnızca belirli istek yöntemlerine izin verdiği sürece güvenilir olarak kabul edilebilir.

‖ Kimlik doğrulama tamamen web sunucusu tarafından yapılıyorsa güvenilir kabul edilebilir .

Süper küresel $_SERVERayrıca birkaç çevre değişkenini de içerir. Bunların "güvenli" olup olmadığı, nasıl (ve nerede) tanımlandıklarına bağlıdır. Tamamen sunucu denetiminden tamamen kullanıcı denetimine kadar değişebilir.


3
@Rook Ama dediğim gibi, kesinlikle onu nasıl kullandığınıza bağlı . Değerler kendi başlarına ne güvenli ne de güvensizdir, onları ne için kullandığınıza bağlıdır . Kötü niyetli bir kullanıcıdan gönderilen veriler bile, onunla güvenliğinizi tehlikeye atabilecek hiçbir şey yapmadığınız sürece tamamen güvenlidir.
deceze

2
@Rook: "güvenli" fikriniz bu soruyu biraz keyfi gösteriyor, özellikle de tamamen belirsiz bir uzantıya veya PHP'nin özel sürümüne bağlı olduğu için. "Kalçadan çekim" yaklaşımı olmamalı "derken, aslında herhangi bir yanıt, bu değerlerin nasıl ayarlandığını bulmak için PHP kaynak koduna en az aşina olmayı gerektiriyor gibi görünüyor. PHP geliştiricilerine e-posta göndermek, bir yanıt bulmak için daha iyi bir yaklaşım olmaz mı?
bob-the-destroyer

2
@Rook: Yanlış iletişim. Deceze'in ima ettiği gibi, "ne amaçla güvenli". Bahsettiğim gibi, amacınız bilinmiyor ve ayrıca $_SERVERdosyanın nasıl sunulduğuna bağlı olarak başka belgelenmemiş değerler de var. Bence belgelenmiş olanlar gerçek kaynağı açıklamıyor. Aksi takdirde bu soruyu sormayacağına inanıyorum. Kullanabileceğin bir listeye sahip olmana sevindim. Ancak yine de bir hata raporu göndermenizi (hata siteleri düzeltildiğinde), doküman bakıcılarına bir e-posta göndermenizi veya dokümanları kendiniz güncellemenizi (bağlantıya bilginiz varsa) öneririm. Bu bilgiyi bilmek topluluğun yararına olacaktır.
bob-the-destroyer

3
SERVER_NAMEsunucu tarafından kontrol edilmesi gerekmez. Ağ geçidine ve ayarlara bağlı olarak, kopyalanabilir HTTP_HOSTve dolayısıyla aynı uyarıya tabi olabilir .
bobince

1
@deceze @Rook SERVER_PORTO küçük haça mı ihtiyacınız var? bugs.php.net/bug.php?id=64457
Dejan Marjanović

12

PHP'de $_SERVERile başlayan her değişken HTTP_kullanıcı tarafından etkilenebilir. Örneğin, değişken $_SERVER['HTTP_REINERS'], HTTP başlığını REINERSHTTP isteğinde rastgele bir değere ayarlayarak lekelenebilir .


yeniden "keyfi"; Bir biçime uydukları için tamamen keyfi değil. Örneğin, $_SERVER['HTTP_REINERS'] çoğu sapisin altında yeni satır karakterleri içeremez.
Pacerier
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.