PHP $ _SERVER ['HTTP_HOST'] बनाम $ _SERVER ['SERVER_NAME'], क्या मैं मैन पेजों को ठीक से समझ रहा हूँ?


167

मैंने बहुत खोज की और PHP $ _SERVER डॉक्स भी पढ़े । क्या मेरे पास यह अधिकार है कि मैं अपनी पूरी साइट में उपयोग की जाने वाली सरल लिंक परिभाषाओं के लिए अपनी PHP लिपियों का उपयोग करूं?

$_SERVER['SERVER_NAME'] आपके वेब सर्वर की कॉन्फ़िगरेशन फ़ाइल (मेरे मामले में Apache2) पर आधारित है, और कुछ निर्देशों के आधार पर भिन्न होता है: (1) VirtualHost, (2) ServerName, (3) UseCanonicalName, आदि।

$_SERVER['HTTP_HOST'] ग्राहक से अनुरोध पर आधारित है।

इसलिए, यह मुझे प्रतीत होगा कि मेरी लिपियों को यथासंभव संगत बनाने के लिए उपयोग करने वाला उचित होगा $_SERVER['HTTP_HOST']। क्या यह धारणा सही है?

अनुवर्ती टिप्पणियाँ:

मुझे लगता है कि मैं इस लेख को पढ़ने के बाद थोड़ा पागल हो गया और ध्यान दिया कि कुछ लोगों ने कहा "वे किसी भी $_SERVERसंस्करण पर भरोसा नहीं करेंगे ":

जाहिरा तौर पर चर्चा मुख्य रूप से होती है $_SERVER['PHP_SELF']और आपको XSS हमलों को रोकने के लिए उचित रूप से भागने के बिना फॉर्म एक्शन विशेषता में इसका उपयोग क्यों नहीं करना चाहिए।

ऊपर मेरे मूल प्रश्न के बारे में मेरा निष्कर्ष यह है कि $_SERVER['HTTP_HOST']XSS हमलों के बारे में चिंता किए बिना किसी साइट पर सभी लिंक के लिए उपयोग करना "सुरक्षित" है , यहां तक ​​कि रूपों में उपयोग किए जाने पर भी।

कृपया मुझे सुधारें अगर मैं गलत हूं।

जवाबों:


149

यह शायद हर किसी का पहला विचार है। लेकिन यह थोड़ा मुश्किल है। देखें क्रिस शिफलेट का लेख SERVER_NAMEबनामHTTP_HOST

ऐसा लगता है कि चांदी की गोली नहीं है। केवल जब आप अपाचे को विहित नाम का उपयोग करने के लिए मजबूर करते हैं तो आपको हमेशा सही सर्वर नाम मिलेगा SERVER_NAME

तो आप या तो उसके साथ जाते हैं या आप एक सफेद सूची के खिलाफ होस्ट नाम की जांच करते हैं:

$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;
}

4
योग्य, मैंने वह लेख पढ़ा और यह वास्तव में मेरे प्रश्न का उत्तर देने के लिए प्रतीत नहीं हुआ। प्रो देव कौन से उपयोग करते हैं? या तो।
जेफ

2
Iiiiinteresting, मुझे कभी नहीं पता था कि SERVER_NAME ने अपाचे में डिफ़ॉल्ट रूप से उपयोगकर्ता द्वारा आपूर्ति किए गए मूल्यों का उपयोग किया था।
पॉवरलॉर्ड

1
@ जेफ़, उन सर्वरों के लिए जो एक से अधिक उप / डोमेन की मेजबानी करते हैं, आपके पास केवल दो विकल्प हैं $_SERVER['SERVER_NAME']और $_SERVER['HTTP_HOST'](उपयोगकर्ता अनुरोध के आधार पर कुछ अन्य कस्टम हैंडशेक को लागू करने से अलग)। प्रो देवों को उन चीजों पर भरोसा नहीं है जो वे पूरी तरह से नहीं समझते हैं। तो वे या तो अपने SAPI है सेटअप पूरी तरह से सही ढंग से (इस स्थिति में विकल्प वे का उपयोग होगा सही परिणाम दे), या वे श्वेत सूची बनाती ऐसी है कि वह बात नहीं क्या SAPI आपूर्ति को महत्व नहीं है कर देंगे।
पचेरियर

@ गंबो, आपको कुछ एसएपीआई के साथ गंभीर मुद्दों के कारण "पोर्ट" पैच लागू करने की आवश्यकता है । इसके अलावा, ओ (एन) प्रदर्शन की तुलना array_key_existsमें अधिक स्केलेबल हैin_array
पचेरियर

2
@Pacerier array_key_exists और in_array अलग-अलग काम करते हैं, चाबियाँ, बाद के मूल्यों के लिए पूर्व जांच करते हैं, इसलिए आप उन्हें इंटरचेंज नहीं कर सकते। इसके अलावा, यदि आपके पास दो मान हैं, तो आपको वास्तव में O (n) के प्रदर्शन के बारे में चिंतित नहीं होना चाहिए ...
eis

74

बस एक अतिरिक्त नोट - यदि सर्वर 80 के अलावा किसी पोर्ट पर चलता है (जैसा कि एक डेवलपमेंट / इंट्रानेट मशीन पर आम हो सकता है) तो HTTP_HOSTपोर्ट होता है, जबकि SERVER_NAMEऐसा नहीं है।

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

(कम से कम यही मैंने अपाचे पोर्ट-आधारित वर्चुअलहोस्टेस में देखा है)

माइक नीचे उल्लेख किया गया है के रूप में, HTTP_HOSTकरता नहीं होते हैं :443जब HTTPS पर चल रहा है (जब तक आप एक गैर मानक पोर्ट, जो मैं परीक्षण नहीं किया पर चल रहे हैं)।


4
नोट: पोर्ट 443 (डिफ़ॉल्ट SSL पोर्ट) के लिए HTTP_HOST में मौजूद नहीं है।
माइक

इसलिए दूसरे शब्दों में, उपयोगकर्ता द्वारा आपूर्ति किए HTTP_HOSTगए Host:पैरामीटर का मान बिल्कुल नहीं है । यह केवल उस पर आधारित है।
पचेरियर

1
@Pacerier नहीं, यह विपरीत है: HTTP_HOST बिल्कुल होस्ट: फ़ील्ड है जो HTTP अनुरोध के साथ आपूर्ति की गई थी। पोर्ट इसका हिस्सा है और ब्राउज़र इसका उल्लेख नहीं करते हैं जब यह डिफ़ॉल्ट एक है (HTTP के लिए 80, HTTPS के लिए 443)
xhienne

29

या तो उपयोग करें। वे दोनों समान रूप से (सुरक्षित) हैं, क्योंकि कई मामलों में SERVER_NAME वैसे भी HTTP_HOST से ही आबाद है। मैं आमतौर पर HTTP_HOST के लिए जाता हूं, ताकि उपयोगकर्ता उस सटीक होस्ट नाम पर बने रहें जिस पर उन्होंने शुरुआत की थी। उदाहरण के लिए यदि मेरे पास .com और .org डोमेन पर एक ही साइट है, तो मैं .org से .com पर किसी को भेजना नहीं चाहता, खासतौर पर तब जब उनके पास .org पर लॉगिन टोकन हो सकते हैं जो कि भेजे जाने पर वे खो देंगे। अन्य डोमेन।

किसी भी तरह से, आपको बस यह सुनिश्चित करने की आवश्यकता है कि आपका वेबप केवल ज्ञात-अच्छे डोमेन के लिए प्रतिक्रिया देगा। यह या तो (ए) किसी एप्लिकेशन-साइड चेक के साथ किया जा सकता है जैसे कि गुम्बो, या (बी) डोमेन नाम (ओं) पर एक वर्चुअल होस्ट का उपयोग करके जो आप चाहते हैं कि अज्ञात होस्ट हेडर देने वाले अनुरोधों का जवाब न दें

इसका कारण यह है कि यदि आप अपनी साइट को किसी पुराने नाम के तहत एक्सेस करने की अनुमति देते हैं, तो आप अपने आप को डीएनएस विद्रोही हमलों के लिए खोल देते हैं (जहां किसी अन्य साइट का होस्टनाम आपके आईपी को इंगित करता है, एक उपयोगकर्ता हमलावर के होस्टनाम के साथ आपकी साइट तक पहुंचता है, फिर होस्टनाम हमलावर के आईपी में ले जाया जाता है, अपने कुकीज़ / ऑर्ट को इसके साथ ले जाता है) और खोज इंजन अपहरण (जहां एक हमलावर आपकी साइट पर अपना स्वयं का होस्टनाम बताता है और खोज इंजन को 'सर्वश्रेष्ठ' प्राथमिक होस्टनाम के रूप में देखने की कोशिश करता है)।

जाहिरा तौर पर चर्चा मुख्य रूप से $ _SERVER ['PHP_SELF'] के बारे में है और आपको XSS हमलों को रोकने के लिए उचित रूप से भागने के बिना फॉर्म एक्शन विशेषता में इसका उपयोग क्यों नहीं करना चाहिए।

Pfft। वैसे आपको बिना भागने के किसी भी विशेषता में कुछ भी उपयोग नहीं करना चाहिए , इसलिए वहां सर्वर चर के बारे में कुछ खास नहीं है।htmlspecialchars($string, ENT_QUOTES)


समाधान के साथ रहें (ए), (बी) वास्तव में सुरक्षित नहीं है, HTTP अनुरोधों में निरपेक्ष यूआरआई का उपयोग करके नाम आधारित वर्चुअलाइजेशन सुरक्षा बायपास के लिए अनुमति देता है। इसलिए वास्तविक नियम कभी SERVER_NAME या HTTP_HOST पर भरोसा नहीं करता है
Regilero

@bobince, उल्लिखित खोज इंजन अपहरण कार्य कैसे करता है? खोज इंजन डोमेन यूआरएल के लिए शब्दों को मैप करते हैं, वे आईपी के साथ सौदा नहीं करते हैं। तो आप यह क्यों कहते हैं कि "एक हमलावर खोज इंजन attacker.comको आपके सर्वर के आईपी के लिए सबसे अच्छा प्राथमिक स्रोत के रूप में देख सकता है "? यह खोज इंजन के लिए कुछ भी मतलब नहीं लगता है, वह भी क्या करने जा रहा है?
पचेरियर

2
Google ने निश्चित रूप से (किसी रूप में अभी भी किसी न किसी रूप में) को डुप्ले साइटों की अवधारणा दी है, ताकि यदि आपकी साइट तक पहुँच हो http://example.com/, http://www.example.com/और http://93.184.216.34/यह उन्हें एक साइट में मिला दे, तो सबसे लोकप्रिय पते चुनें, और केवल उसी पर लिंक लौटाएँ संस्करण। यदि आप evil-example.comएक ही पते पर इंगित कर सकते हैं और Google को संक्षेप में देख सकते हैं कि अधिक लोकप्रिय पते के रूप में आप साइट का रस चुरा सकते हैं। मुझे नहीं पता कि यह आज कितना व्यावहारिक है लेकिन मैंने देखा है कि रूसी लिंक फार्म हमलावरों ने इसे अतीत में करने की कोशिश की थी।
बॉब

24

यह होस्ट नाम प्राप्त करने के लिए सिम्फनी का उपयोग करने का एक क्रियात्मक अनुवाद है ( अधिक शाब्दिक अनुवाद के लिए दूसरा उदाहरण देखें ):

function getHost() {
    $possibleHostSources = array('HTTP_X_FORWARDED_HOST', 'HTTP_HOST', 'SERVER_NAME', 'SERVER_ADDR');
    $sourceTransformations = array(
        "HTTP_X_FORWARDED_HOST" => function($value) {
            $elements = explode(',', $value);
            return trim(end($elements));
        }
    );
    $host = '';
    foreach ($possibleHostSources as $source)
    {
        if (!empty($host)) break;
        if (empty($_SERVER[$source])) continue;
        $host = $_SERVER[$source];
        if (array_key_exists($source, $sourceTransformations))
        {
            $host = $sourceTransformations[$source]($host);
        } 
    }

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

    return trim($host);
}

रगड़ा हुआ:

यह सिम्फनी फ्रेमवर्क में उपयोग की जाने वाली एक विधि के नंगे PHP के लिए मेरा अनुवाद है जो बेहतरीन तरीके से क्रम में होस्टनाम को हर तरह से संभव बनाने की कोशिश करता है:

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);
}

1
@StefanNch कृपया "इस तरह परिभाषित करें"।
शोदेव

1
@ शशदेव मुझे वास्तव में "कठिन" लगता है जैसे if ($host = $_SERVER['HTTP_X_FORWARDED_HOST'])या हालत बयान पढ़ने के लिए x = a == 1 ? True : False। पहली बार मैंने यह देखा है कि मेरा दिमाग $ होस्ट की तात्कालिकता और "क्यों केवल एक ही" = "संकेत" के लिए एक उत्तर की तलाश में था। मैं कमजोर टाइपिंग प्रोग्रामिंग भाषाओं को नापसंद करने लगा हूं। सब कुछ अलग तरह से लिखा गया है। आप समय नहीं बचाते हैं और आप विशेष नहीं हैं। मैं इस तरह से कोड नहीं लिखता, क्योंकि समय बीतने के बाद, मैं वह हूं जिसे इसे डीबग करना होगा। थके हुए दिमाग के लिए वाकई गन्दा लगता है! मुझे पता है कि मेरा इंग्लिश बहुत बड़ा है, लेकिन कम से कम मैं कोशिश करता हूं।
स्टीफन नच

1
दोस्तों, मैंने सिम्फनी से कोड को पोर्ट किया। इस तरह से मैंने इसे लिया। सभी के लिए यह मायने रखता है - यह काम करता है और यह पूरी तरह से लगता है। मैं, खुद भी, यह बात काफी पठनीय नहीं है, लेकिन मेरे पास इसे पूरी तरह से फिर से लिखने का समय नहीं है।
एंटीटॉक्सिक

2
मुझे ठीक लगता है। वे टर्नरी ऑपरेटर हैं और वास्तव में उचित पठनीयता के बिना समय और (बाइट्स) को बचा सकते हैं, जब उचित रूप से उपयोग किया जाता है।
शोदेव

1
@antitoxic, -1 सिम्फनी कोडर्स (कई अन्य लोगों की तरह) बिल्कुल नहीं जानते कि वे इस मामले में क्या कर रहे हैं। यह आपको मेजबान नाम नहीं देता (साइमन का जवाब देखें)। यह आपको केवल एक अच्छा अनुमान देता है जो कई बार गलत होगा
पचेरियर

11

क्या $_SERVER['HTTP_HOST']XSS हमलों के बारे में चिंता किए बिना किसी साइट पर सभी लिंक के लिए उपयोग करना "सुरक्षित" है , यहां तक ​​कि रूपों में भी इस्तेमाल किया जाता है?

हाँ, यह है सुरक्षित उपयोग करने के लिए $_SERVER['HTTP_HOST'], (और यहां तक कि $_GETऔर $_POST) तक आप उन्हें सत्यापित करने के रूप में के रूप में उन्हें स्वीकार करने से पहले। यह मैं सुरक्षित उत्पादन सर्वरों के लिए करता हूं:

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
$reject_request = true;
if(array_key_exists('HTTP_HOST', $_SERVER)){
    $host_name = $_SERVER['HTTP_HOST'];
    // [ need to cater for `host:port` since some "buggy" SAPI(s) have been known to return the port too, see http://goo.gl/bFrbCO
    $strpos = strpos($host_name, ':');
    if($strpos !== false){
        $host_name = substr($host_name, $strpos);
    }
    // ]
    // [ for dynamic verification, replace this chunk with db/file/curl queries
    $reject_request = !array_key_exists($host_name, array(
        'a.com' => null,
        'a.a.com' => null,
        'b.com' => null,
        'b.b.com' => null
    ));
    // ]
}
if($reject_request){
    // log errors
    // display errors (optional)
    exit;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
echo 'Hello World!';
// ...

इसका लाभ $_SERVER['HTTP_HOST']यह है कि इसके व्यवहार की तुलना में अधिक अच्छी तरह से परिभाषित किया गया है $_SERVER['SERVER_NAME']। कंट्रास्ट ➫➫ :

होस्ट की सामग्री: वर्तमान अनुरोध से हेडर, यदि कोई है।

साथ में:

सर्वर होस्ट का नाम जिसके तहत वर्तमान स्क्रिप्ट निष्पादित हो रही है।

एक बेहतर परिभाषित इंटरफ़ेस का उपयोग करने का $_SERVER['HTTP_HOST']अर्थ है कि अधिक SAPI विश्वसनीय विश्वसनीय व्यवहार का उपयोग करके इसे लागू करेंगे । (विपरीत अन्य ।) हालांकि, यह अभी पूरी तरह से SAPI निर्भर है ➫➫ :

इस बात की कोई गारंटी नहीं है कि प्रत्येक वेब सर्वर इनमें से कोई भी [ $_SERVERप्रविष्टियां] प्रदान करेगा ; सर्वर कुछ को छोड़ सकते हैं, या दूसरों को यहां सूचीबद्ध नहीं कर सकते हैं।

यह समझने के लिए कि मेजबान नाम को ठीक से कैसे प्राप्त किया जाए, सबसे पहले और आपको यह समझने की जरूरत है कि एक सर्वर जिसमें केवल कोड होता है, उसके पास नेटवर्क पर अपना नाम जानने का कोई साधन नहीं होता है । इसे एक घटक के साथ इंटरफ़ेस करने की आवश्यकता है जो इसे अपने नाम से आपूर्ति करता है। इसके जरिए किया जा सकता है:

  • स्थानीय कॉन्फ़िगरेशन फ़ाइल

  • स्थानीय डेटाबेस

  • हार्डकोड स्रोत कोड

  • बाहरी अनुरोध ( कर्ल )

  • ग्राहक / हमलावर का Host:अनुरोध

  • आदि

आमतौर पर इसका स्थानीय (SAPI) कॉन्फ़िगरेशन फ़ाइल के माध्यम से किया जाता है। ध्यान दें कि आपने इसे सही तरीके से कॉन्फ़िगर किया है, उदाहरण के लिए Apache configured :

गतिशील वर्चुअल होस्ट को सामान्य की तरह बनाने के लिए कुछ चीजों को 'फेक' होना चाहिए।

सबसे महत्वपूर्ण सर्वर नाम है जो अपाचे द्वारा स्व-संदर्भ URL बनाने के लिए उपयोग किया जाता है, आदि यह ServerNameनिर्देश के साथ कॉन्फ़िगर किया गया है , और यह SERVER_NAMEपर्यावरण चर के माध्यम से सीजीआई के लिए उपलब्ध है ।

रन टाइम पर उपयोग किया जाने वाला वास्तविक मान UseCanonicalName सेटिंग द्वारा नियंत्रित किया जाता है।

साथ UseCanonicalName Off सर्वर नाम की सामग्री से आता Host:अनुरोध में शीर्ष लेख। इसके साथ UseCanonicalName DNS वर्चुअल होस्ट के IP पते के रिवर्स DNS लुकअप से आता है। पूर्व सेटिंग का उपयोग नाम-आधारित गतिशील वर्चुअल होस्टिंग के लिए किया जाता है, और बाद का उपयोग ** आईपी-आधारित होस्टिंग के लिए किया जाता है।

यदि Apache सर्वर नाम का काम नहीं कर सकता है क्योंकि कोई Host:हेडर नहीं है या DNS लुकअप विफल हो जाता है तोServerName इसके साथ कॉन्फ़िगर किए गए मान का उपयोग किया जाता है।


8

दोनों के बीच मुख्य अंतर यह है कि $_SERVER['SERVER_NAME']एक सर्वर नियंत्रित चर है, जबकि $_SERVER['HTTP_HOST']एक उपयोगकर्ता-नियंत्रित मूल्य है।

अंगूठे का नियम उपयोगकर्ता से मूल्यों पर कभी भरोसा नहीं करना है, इसलिए $_SERVER['SERVER_NAME']बेहतर विकल्प है।

जैसा कि गम्बो ने बताया, यदि आप सेट नहीं करते हैं, तो Apache उपयोगकर्ता द्वारा आपूर्ति किए गए मानों से SERVER_NAME का निर्माण करेगा UseCanonicalName On

संपादित करें: सभी ने कहा कि यदि साइट नाम-आधारित वर्चुअल होस्ट का उपयोग कर रही है, तो HTTP होस्ट हेडर उन साइटों तक पहुंचने का एकमात्र तरीका है जो डिफ़ॉल्ट साइट नहीं हैं।


समझ लिया। मेरा Hangup "उपयोगकर्ता $ _SERVER ['HTTP_HOST'] का मूल्य कैसे बदल सकता है?" क्या यह भी संभव है?
जेफ

5
एक उपयोगकर्ता इसे बदल सकता है क्योंकि यह केवल आने वाले अनुरोध से होस्ट हेडर की सामग्री है। मुख्य सर्वर (या डिफ़ॉल्ट के लिए बाध्य वर्चुअलहॉट : 80) सभी अज्ञात होस्टों को जवाब देगा, इस प्रकार उस साइट पर होस्ट टैग की सामग्री कुछ भी सेट की जा सकती है।
पॉवरलॉर्ड

4
ध्यान दें कि IP- आधारित वर्चुअल होस्ट ALWAYS उनके विशिष्ट IP पर प्रतिक्रिया देगा, इसलिए आप किसी भी परिस्थिति में उन पर HTTP होस्ट मान पर भरोसा नहीं कर सकते ।
पॉवरलॉर्ड

1
@Jeff, यह पूछ की तरह है "यह पिज्जा झोपड़ी का फोन नंबर और कॉल करने के लिए संभव है अनुरोध केएफसी कर्मचारियों से बात करने की?" निश्चित रूप से आप कुछ भी आप चाहते हैं अनुरोध कर सकते हैं। @Powerlord, इसका IP- आधारित वर्चुअल होस्ट से कोई लेना-देना नहीं है। IP- आधारित वर्चुअल होस्ट की परवाह किए बिना या नहीं, आपका सर्वर किसी भी परिस्थिति में HTTP के Host:मूल्य पर भरोसा नहीं कर सकता है जब तक कि आपने इसे पहले ही सत्यापित नहीं किया है, या तो मैन्युअल रूप से या अपने SAPI सेटअप के माध्यम से।
22

3

मुझे यकीन नहीं है और वास्तव में भरोसा नहीं है $_SERVER['HTTP_HOST']क्योंकि यह क्लाइंट से हेडर पर निर्भर है। दूसरे तरीके से, यदि क्लाइंट द्वारा अनुरोधित एक डोमेन मेरा नहीं है, तो वे मेरी साइट पर नहीं पहुंचेंगे क्योंकि DNS और TCP / IP प्रोटोकॉल इसे सही गंतव्य पर इंगित करते हैं। हालाँकि मुझे नहीं पता कि DNS, नेटवर्क या अपाचे सर्वर को भी हाईजैक करना संभव है। सुरक्षित होने के लिए, मैं पर्यावरण में होस्ट नाम को परिभाषित करता हूं और इसके साथ तुलना करता हूं $_SERVER['HTTP_HOST']

जोड़े SetEnv MyHost domain.com.htaccess फाइल में जड़ पर और Common.php में चौथाई कोड जोड़

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

मैं हर php पेज में इस Common.php फ़ाइल को शामिल करता हूँ। यह पृष्ठ प्रत्येक अनुरोध के लिए आवश्यक कुछ भी कर रहा है session_start(), सत्र कुकी को संशोधित करें और पोस्ट विधि अलग डोमेन से आए तो अस्वीकार करें।


1
बेशक डीएनएस को बायपास करना संभव है। एक हमलावर Host:सीधे आपके सर्वर के आईपी पर एक फ़र्ज़ी मूल्य जारी कर सकता है ।
पचेरियर

1

XSSहमेशा वहाँ होगा भले ही आप का उपयोग करें $_SERVER['HTTP_HOST'], $_SERVER['SERVER_NAME']या$_SERVER['PHP_SELF']


1

पहले मैं आपको सभी अच्छे उत्तर और स्पष्टीकरण के लिए धन्यवाद देना चाहता हूं। यह वह विधि है जिसे मैंने आधार url प्राप्त करने के लिए आपके सभी उत्तर के आधार पर बनाया है। मैं केवल बहुत ही दुर्लभ परिस्थितियों में इसका उपयोग करता हूं। इसलिए सुरक्षा मुद्दों पर बड़ा ध्यान केंद्रित नहीं है, जैसे XSS हमले। शायद किसी को इसकी जरूरत हो।

// Get base url
function getBaseUrl($array=false) {
    $protocol = "";
    $host = "";
    $port = "";
    $dir = "";  

    // Get protocol
    if(array_key_exists("HTTPS", $_SERVER) && $_SERVER["HTTPS"] != "") {
        if($_SERVER["HTTPS"] == "on") { $protocol = "https"; }
        else { $protocol = "http"; }
    } elseif(array_key_exists("REQUEST_SCHEME", $_SERVER) && $_SERVER["REQUEST_SCHEME"] != "") { $protocol = $_SERVER["REQUEST_SCHEME"]; }

    // Get host
    if(array_key_exists("HTTP_X_FORWARDED_HOST", $_SERVER) && $_SERVER["HTTP_X_FORWARDED_HOST"] != "") { $host = trim(end(explode(',', $_SERVER["HTTP_X_FORWARDED_HOST"]))); }
    elseif(array_key_exists("SERVER_NAME", $_SERVER) && $_SERVER["SERVER_NAME"] != "") { $host = $_SERVER["SERVER_NAME"]; }
    elseif(array_key_exists("HTTP_HOST", $_SERVER) && $_SERVER["HTTP_HOST"] != "") { $host = $_SERVER["HTTP_HOST"]; }
    elseif(array_key_exists("SERVER_ADDR", $_SERVER) && $_SERVER["SERVER_ADDR"] != "") { $host = $_SERVER["SERVER_ADDR"]; }
    //elseif(array_key_exists("SSL_TLS_SNI", $_SERVER) && $_SERVER["SSL_TLS_SNI"] != "") { $host = $_SERVER["SSL_TLS_SNI"]; }

    // Get port
    if(array_key_exists("SERVER_PORT", $_SERVER) && $_SERVER["SERVER_PORT"] != "") { $port = $_SERVER["SERVER_PORT"]; }
    elseif(stripos($host, ":") !== false) { $port = substr($host, (stripos($host, ":")+1)); }
    // Remove port from host
    $host = preg_replace("/:\d+$/", "", $host);

    // Get dir
    if(array_key_exists("SCRIPT_NAME", $_SERVER) && $_SERVER["SCRIPT_NAME"] != "") { $dir = $_SERVER["SCRIPT_NAME"]; }
    elseif(array_key_exists("PHP_SELF", $_SERVER) && $_SERVER["PHP_SELF"] != "") { $dir = $_SERVER["PHP_SELF"]; }
    elseif(array_key_exists("REQUEST_URI", $_SERVER) && $_SERVER["REQUEST_URI"] != "") { $dir = $_SERVER["REQUEST_URI"]; }
    // Shorten to main dir
    if(stripos($dir, "/") !== false) { $dir = substr($dir, 0, (strripos($dir, "/")+1)); }

    // Create return value
    if(!$array) {
        if($port == "80" || $port == "443" || $port == "") { $port = ""; }
        else { $port = ":".$port; } 
        return htmlspecialchars($protocol."://".$host.$port.$dir, ENT_QUOTES); 
    } else { return ["protocol" => $protocol, "host" => $host, "port" => $port, "dir" => $dir]; }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.