$ _SERVER ['SERVER_NAME'] vs PHP $ _SERVER ['HTTP_HOST'], Ben doğru man sayfalarını anlama ben?

7 Cevap php

Ben arama yaptım ve aynı zamanda PHP $ _SERVER man sayfasını okuyun. Ben benim site genelinde kullanılan basit bağlantı tanımları için benim PHP komut için kullanmak konusunda bu hakkı var mı?

$_SERVER['SERVER_NAME'] web servers 'config dosyasında (benim durumumda Apache2) dayalı, ve birkaç direktiflerine bağlı olarak değişir: vb (1) VirtualHostuna, (2) ServerName, (3) UseCanonicalName,

$_SERVER['HTTP_HOST'] istemciden istek dayanmaktadır.

Bu nedenle, $_SERVER['HTTP_HOST'] olacağını uygun bir sürede benim komut olarak uyumlu hale getirmek için kullanmak bana görünüyor. Bu varsayım doğru mudur?

Followup comments:

Ben bu makaleyi okuyarak ve birisi "onlar $ _SERVER vars herhangi güven olmaz" dedi belirterek sonra biraz paranoyak var sanırım:

http://markjaquith.wordpress.com/2009/09/21/php-server-vars-not-safe-in-forms-or-links/

ve ayrıca:

http://www.php.net/manual/en/reserved.variables.server.php (Yorum: Vladimir masalları 14-Mar-2009 01:06)

Görünüşe tartışma $_SERVER['PHP_SELF'] esas hakkında ve neden uygun XSS saldırıları önlemek için kaçan olmadan form eylemi niteliğinde kullanmak gerekir.

Yukarıda benim özgün soru hakkında benim vardığım sonuç bu "güvenli" şekillerde kullanılan bile, XSS saldırıları hakkında endişelenmenize gerek kalmadan bir sitedeki tüm bağlantılar için $_SERVER['HTTP_HOST'] kullanmaktır olmasıdır.

Yanılıyorsam lütfen beni düzeltin.

7 Cevap

Muhtemelen herkesin ilk düşünce. Ama bu biraz daha zor. Chris Shiflett’s article SERVER_NAME HTTP_HOST Karşı bakınız.

Hiçbir gümüş mermi olduğunu görünüyor. Eğer force Apache to use the canonical name hep birlikte doğru sunucu adını alacak sadece SERVER_NAME.

Yani bu ile gitmek ya da bir beyaz liste karşı ana bilgisayar adını kontrol edin:

$allowed_hosts = array('foo.example.com', 'bar.example.com');
if (!isset($_SERVER['HTTP_HOST']) || !in_array($_SERVER['HTTP_HOST'], $allowed_hosts)) {
    header($_SERVER['SERVER_PROTOCOL'].' 400 Bad Request');
    exit;
}

Bu en iyi uygulama için mümkün olan her şekilde gelen hostname almak için çalışır Symfony çerçevesinde kullanılan bir yöntem PHP çıplak benim çevirisi şöyledir:

function get_host() {
    if ($host = $_SERVER['HTTP_X_FORWARDED_HOST'])
    {
        $elements = explode(',', $host);

        $host = trim(end($elements));
    }
    else
    {
        if (!$host = $_SERVER['HTTP_HOST'])
        {
            if (!$host = $_SERVER['SERVER_NAME'])
            {
                $host = !empty($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '';
            }
        }
    }

    // Remove port number from host
    $host = preg_replace('/:\d+$/', '', $host);

    return trim($host);
}

Sadece ek bir not - server SERVER_NAME yok iken daha sonra HTTP_HOST, port içeren (bir kalkınma / intranet makinede ortak olabilir gibi) 80 dışında bir bağlantı noktasında çalışıyorsa.

$_SERVER['HTTP_HOST'] == 'localhost:8080'
$_SERVER['SERVER_NAME'] == 'localhost'

(En azından ben Apache port tabanlı VirtualHosts fark buydu)

Mike aşağıda belirtildiği gibi, HTTP_HOST not içermiyor :443 Eğer standart olmayan bir port üzerinde çalışan sürece, (HTTPS üzerinde çalışırken ki ben cenneti ' t) test edilmiştir.

Ya kullanın. Birçok durumda SERVER_NAME sadece zaten HTTP_HOST doldurulur Onlar, güvenli (in) ikisi de eşit derecede vardır. Kullanıcı onlar başladı kesin host adı kalır ki ben normalde, HTTP_HOST için gidin. Ben bir. Com ve. Org etki aynı site varsa Örneğin, ben onlar giriş üzerinde belirteçleri olabilir, özellikle eğer. Com için. Org dan birini göndermek istemiyorum. Org gönderilen eğer kaybetmek istiyorum ki diğer etki alanı.

Her iki şekilde de, sadece webapp sadece hiç bilinen-iyi etki için cevap verecektir emin olmak gerekir. Bu da yapılabilir (a) Gumbo ait, ya da benzeri bir uygulama tarafı çek ile (b) alan adı (lar) üzerinde bir sanal konak kullanarak istediğiniz o does not respond bilinmeyen bir ana vermek istekleri başlık.

Bunun nedeni sizin site herhangi eski adı altında erişilmesine izin verirseniz, size hostname, sonra IP başka bir sitenin host noktaları, kullanıcı saldırganın konak ile sitenizi erişir burada (DNS yeniden bağlama saldırıları kendinizi açık yattı yani onunla kurabiye / auth alarak, saldırganın IP taşınır) ve bir saldırganın yerinde kendi hostname işaret ve arama motorları) 'en iyi' birincil konak ismi olarak görmek yapmak için çalışır arama motoru kaçırma (.

Görünüşe tartışma ağırlıklı yaklaşık $ _SERVER ['PHP_SELF'] ve XSS saldırıları önlemek için doğru kaçan olmadan form eylemi niteliğinde kullanmak gerekir nedeni budur.

Pfft. Peki htmlspecialchars($string, ENT_QUOTES) ile kaçan olmadan any niteliğinde anything kullanmak gerekir, bu yüzden orada sunucu değişkenleri hakkında özel bir şey yok.

İkisi arasındaki temel fark, $_SERVER['HTTP_HOST'], bir kullanıcı kontrollü değeri ise $_SERVER['SERVER_NAME'], bir sunucu kontrol edilen değişken olmasıdır.

Başparmak kuralı böylece $_SERVER['SERVER_NAME'] daha iyi bir seçimdir, kullanıcıdan asla güven değerlerini etmektir.

Bamya işaret olarak UseCanonicalName On set yoksa, Apache kullanıcı tarafından sağlanan değerlerden SERVER_NAME inşa edecek.

Edit: site isme dayalı sanal konak kullanarak ise tüm söyledikten sonra, HTTP Host başlığı varsayılan site olmayan sitelere ulaşmak için tek yoldur.

Ben emin değilim ve istemci başlığında bağlıdır çünkü gerçekten $_SERVER['HTTP_HOST'] güvenmiyorum. Istemci tarafından istenen bir etki benimki bir değil başka bir yolla, onlar benim site içine doğru hedefe çünkü DNS ve TCP / IP protokolü nokta bu oluyor olmaz. DNS, ağ ya da Apache sunucusunu kaçırmak mümkün olmadığını ancak ben bilmiyorum. Güvende olmak için, ben ortamında host adını tanımlamak ve $_SERVER['HTTP_HOST'] ile karşılaştırın.

Kökü. Htaccess dosyasında SetEnv MyHost domain.com Ekle ve common.php THS kodu ekleyin

if (getenv('MyHost')!=$_SERVER['HTTP_HOST']) {
  header($_SERVER['SERVER_PROTOCOL'].' 400 Bad Request');
  exit();
}

Her php sayfasında bu common.php dosyası içerir. session_start(), oturum çerezi değiştirebilir ve sonrası yöntemi farklı etki alanından geliyorsa reddetmek gibi her istek için gerekli her şeyi yapıyor Bu sayfa.

Kullanmak bile XSS her zaman orada olacak $_SERVER['HTTP_HOST'], $_SERVER['SERVER_NAME'] VEYA $_SERVER['PHP_SELF']