পিএইচপি $ _SERVER ['HTTP_HOST'] বনাম $ _SERVER ['SERVER_NAME'], আমি কি ম্যান পেজগুলি সঠিকভাবে বুঝতে পারি?


167

আমি প্রচুর অনুসন্ধান করেছি এবং পিএইচপি $ _SERVER ডকসও পড়েছি । আমার পিএইচপি স্ক্রিপ্টগুলির জন্য আমার সাইটের জুড়ে সরল লিঙ্ক সংজ্ঞাগুলির জন্য কোনটি ব্যবহার করবেন সে সম্পর্কে আমার কি অধিকার আছে?

$_SERVER['SERVER_NAME'] আপনার ওয়েব সার্ভারের কনফিগারেশন ফাইলের উপর ভিত্তি করে (আমার ক্ষেত্রে অ্যাপাচি 2), এবং কয়েকটি নির্দেশের উপর নির্ভর করে পরিবর্তিত হয়: (1) ভার্চুয়ালহস্ট, (2) সার্ভারনাম, (3) ইউজক্যানোনিক্যালনাম, ইত্যাদি

$_SERVER['HTTP_HOST'] ক্লায়েন্টের অনুরোধের ভিত্তিতে তৈরি।

সুতরাং, আমার কাছে মনে হবে যে আমার স্ক্রিপ্টগুলিকে যথাসম্ভব সামঞ্জস্যপূর্ণ করার জন্য যথাযথ ব্যবহার করা উচিত $_SERVER['HTTP_HOST']। এই ধারণাটি কি সঠিক?

ফলোআপ মন্তব্য:

আমি অনুমান করি যে এই নিবন্ধটি পড়ার পরে এবং কিছু লোকেরা "তারা কোনও $_SERVERযুদ্ধকে বিশ্বাস করবে না" বলে উল্লেখ করার পরে আমি কিছুটা ভৌতিক হয়ে পড়েছি :

স্পষ্টতই আলোচনাটি মূলত এ নিয়েই $_SERVER['PHP_SELF'] এবং কেন আপনি এক্সএসএস আক্রমণ রোধ করতে যথাযথভাবে পালানো ছাড়াই ফর্ম ক্রিয়া বৈশিষ্ট্যে এটি ব্যবহার করবেন না।

উপরে আমার মূল প্রশ্ন সম্পর্কে আমার উপসংহারটি এটি ব্যবহার করা "নিরাপদ" $_SERVER['HTTP_HOST'] XSS আক্রমণ সম্পর্কে চিন্তা না করে কোনও সাইটের সমস্ত লিঙ্কের জন্য , এমনকি ফর্মগুলিতে ব্যবহৃত হলেও।

আমি ভুল হলে আমাকে সংশোধন করুন।

উত্তর:


149

এটাই সম্ভবত সবার প্রথম চিন্তা। তবে এটি কিছুটা বেশি কঠিন। দেখুন ক্রিস Shiflett এর নিবন্ধ 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 সেটআপটি নিখুঁতভাবে সঠিকভাবে রয়েছে (এক্ষেত্রে তারা যে অপশনটি ব্যবহার করবে সেটির সঠিক ফলাফল দেবে), বা তারা এমনটি হোয়াইটলিস্টিং করবে যা এসপিআই সরবরাহকে মূল্য দেয় তা বিবেচনা করে না।
পেসারিয়ার

@ গম্বো, নির্দিষ্ট এসএপিআইয়ের সাথে গুরুতর সমস্যার কারণে আপনাকে "বন্দর" প্যাচ প্রয়োগ করতে হবে । এছাড়াও, ও (এন) পারফরম্যান্সের তুলনায় array_key_existsএটি আরও স্কেলযোগ্যin_array
পেসারিয়ার

2
@ পেসারিয়ের অ্যারে_কি_এক্সজিস্ট এবং ইন_আরে বিভিন্ন জিনিস করে, কীগুলির জন্য পূর্ববর্তী চেকগুলি, আধুনিক মানগুলি, যাতে আপনি কেবল সেগুলি বদলাতে পারবেন না। এছাড়াও, যদি আপনি দুইটি মানের একটি অ্যারে আছে, তাই না সত্যিই হে (ঢ) কর্মক্ষমতা ... সম্পর্কে চিন্তিত হতে হবে
Eis

74

কেবলমাত্র একটি অতিরিক্ত নোট - যদি সার্ভারটি 80 এর বাইরে অন্য কোনও বন্দরে চালিত হয় (যেমনটি কোনও বিকাশ / ইন্ট্রানেট মেশিনে সাধারণ হিসাবে দেখা যায়) তবে HTTP_HOSTপোর্টটি অন্তর্ভুক্ত রয়েছে, যখন SERVER_NAMEতা নেই।

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

(অ্যাপাচি পোর্ট-ভিত্তিক ভার্চুয়ালহোস্টগুলিতে আমি এটি লক্ষ্য করেছি)

মাইক নিচে উল্লেখ করা হয়েছে, HTTP_HOSTনেই না থাকতে :443যখন HTTPS দ্বারা চলমান (যদি না আপনি একটি অ-মানক পোর্ট, যা আমি পরীক্ষিত না উপর চালাচ্ছেন)।


4
দ্রষ্টব্য: বন্দরটি HTTP_HOST এ 443 (ডিফল্ট এসএসএল পোর্ট) এর জন্য উপস্থিত নেই।
মাইক

সুতরাং অন্য কথায়, এর মানটি ব্যবহারকারী সরবরাহিত প্যারামিটারের মতো HTTP_HOSTহয় না Host:। এটি কেবল এর উপর ভিত্তি করে।
প্যাসেরিয়ার

1
@ পেসিয়ার নং, এটি বিপরীত: HTTP_HOST হ'ল হোস্ট: ক্ষেত্র যা HTTP অনুরোধের সাথে সরবরাহ করা হয়েছিল। বন্দরটি এরই একটি অংশ এবং এটি ব্রাউজারগুলি ডিফল্ট হয়ে গেলে এটি উল্লেখ করে না (HTTP এর জন্য 80; এইচটিটিপিএসের জন্য 443)
xhienne

29

হয় ব্যবহার করুন। এগুলি উভয়ই সমানভাবে (ইন) সুরক্ষিত, যেমন অনেক ক্ষেত্রেই SERVER_NAME কেবলমাত্র HTTP_HOST থেকে জনবহুল। আমি সাধারণত HTTP_HOST এর জন্য যাই, যাতে ব্যবহারকারীরা ঠিক যে হোস্ট নামটি শুরু করেছিলেন তার উপর থেকে যায়। উদাহরণস্বরূপ যদি আমার .com এবং .org ডোমেইনে একই সাইট থাকে তবে আমি .org থেকে .com এ কাউকে পাঠাতে চাই না, বিশেষত যদি তারা .org এ লগইন টোকেন থাকতে পারে তবে তারা হারাতে চাইবে যদি প্রেরণ করা হয় তবে অন্য ডোমেন।

যেভাবেই হোক, আপনার কেবল নিশ্চিত হওয়া দরকার যে আপনার ওয়েব অ্যাপ্লিকেশন কেবল পরিচিত-ভাল ডোমেনের জন্য প্রতিক্রিয়া জানাবে। এটি হয় (ক) গাম্বোর মতো অ্যাপ্লিকেশন সাইড চেক সহ, বা (খ) আপনি যে ডোমেন নাম (গুলি) ব্যবহার করতে চান তাতে কোনও ভার্চুয়াল হোস্ট ব্যবহার করে এটি করা যেতে পারে যা সাড়া দেয় না অজানা হোস্ট শিরোনামের অনুরোধগুলির ।

এর কারণ হ'ল যদি আপনি আপনার সাইটটিকে কোনও পুরানো নামের অধীনে অ্যাক্সেস করার অনুমতি দেন তবে আপনি নিজেকে ডিএনএস রিবাইন্ডিং আক্রমণগুলিতে উন্মুক্ত রাখেন (যেখানে অন্য সাইটের হোস্টনাম আপনার আইপিটিতে নির্দেশ করে, কোনও ব্যবহারকারী আক্রমণকারীর হোস্টনামের সাহায্যে আপনার সাইট অ্যাক্সেস করে, তারপরে হোস্টনাম আক্রমণকারীদের আইপি-তে স্থানান্তরিত হয়, এটির সাথে আপনার কুকিজ / প্রমাণকে নিয়ে) এবং অনুসন্ধান ইঞ্জিন হাইজ্যাকিং (যেখানে কোনও আক্রমণকারী আপনার সাইটে তাদের নিজস্ব হোস্টনামটি নির্দেশ করে এবং অনুসন্ধান ইঞ্জিনগুলিকে এটি 'সেরা' প্রাথমিক হোস্টনাম হিসাবে দেখায়)।

স্পষ্টতই আলোচনাটি মূলত $ _SERVER ['পিএইচপিএসএসএলএফ'] সম্পর্কে এবং এক্সএসএস আক্রমণ রোধ করতে যথাযথভাবে পালানো ছাড়াই আপনি কেন ফর্ম ক্রিয়া বৈশিষ্ট্যে এটি ব্যবহার করবেন না।

Pfft। আচ্ছা আপনি ব্যবহার করা উচিত নয় কিছু মধ্যে কোনো সঙ্গে পলায়নের ছাড়া অ্যাট্রিবিউট htmlspecialchars($string, ENT_QUOTES), তাই আছে সেখানে সার্ভার ভেরিয়েবল সম্পর্কে কিছুই বিশেষ।


সমাধান সহ থাকুন (ক), (খ) সত্যই নিরাপদ নয়, এইচটিটিপি অনুরোধে নিখুঁত ইউআরআই ব্যবহার করে নাম ভিত্তিক ভার্চুয়ালহোস্ট সুরক্ষা বাইপাসের অনুমতি দেয়। সুতরাং আসল বিধিটি কখনই SERVER_NAME বা HTTP_HOST এ বিশ্বাস করে না
রেজিলিও

@ ববিনস, উল্লিখিত সার্চ ইঞ্জিন হাইজ্যাকিং কীভাবে কাজ করবে? অনুসন্ধান ইঞ্জিনগুলি ডোমেনে ম্যাপের শব্দগুলি ইউআরএলে , তারা আইপিগুলিতে ডিল করে না। তাহলে আপনি কেন বলছেন যে "আক্রমণকারী অনুসন্ধান সার্চ ইঞ্জিনগুলিকে attacker.comআপনার সার্ভারের আইপি-র জন্য সেরা প্রাথমিক উত্স হিসাবে দেখাতে পারে" তার অর্থ? এটি অনুসন্ধান ইঞ্জিনগুলির কোনও অর্থ বলে মনে হচ্ছে না, এমন কি এমন কি করতে চলেছে?
প্যাসেরিয়ার

2
গুগল অবশ্যই ছিল (এবং সম্ভবত এখনও কিছু আকারে আছে) প্রতারিত সাইট ধারণা, তাই যদি আপনার সাইট হিসাবে প্রবেশযোগ্য যে http://example.com/, http://www.example.com/এবং http://93.184.216.34/এটা এক সাইটে সেগুলি একত্রিত হবে, ঠিকানা সবচেয়ে জনপ্রিয় চয়ন করুন এবং শুধু তাই লিঙ্ক আসতে সংস্করণ। আপনি যদি evil-example.comএকই ঠিকানায় ইঙ্গিত করে গুগলকে সংক্ষেপে দেখতে পারেন যে আরও জনপ্রিয় ঠিকানা হিসাবে আপনি সাইটের রস চুরি করতে পারেন। আজকের দিনে এটি কতটা বাস্তব তা আমি জানি না তবে আমি রাশিয়ান লিঙ্ক ফার্ম ফার্ম আক্রমণকারীদের অতীতে এটি করার চেষ্টা করতে দেখেছি।
6:38

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

সেকেলে:

সিমফনি ফ্রেমওয়ার্কে ব্যবহৃত এমন পদ্ধতির বেয়ার পিএইচপিতে এটি আমার অনুবাদ যা সর্বোত্তম অনুশীলনের ক্রমানুসারে হোস্টনামকে সম্ভাব্য প্রতিটি উপায়ে থেকে পেতে চেষ্টা করে:

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
@ স্টেফাননিচ দয়া করে "এইভাবে" সংজ্ঞা দিন।
শোদেব

1
@showdev আমি সত্যিই মত অবস্থা বিবৃতি পড়তে "কঠিন" এটি if ($host = $_SERVER['HTTP_X_FORWARDED_HOST'])বা x = a == 1 ? True : False। প্রথমবার আমি এটি দেখেছি যে আমার মস্তিষ্ক $ হোস্ট ইনস্ট্যান্টেশন এবং "কেবলমাত্র একটি কেন" = "চিহ্ন?" এর জন্য একটি উত্তর খুঁজছিল। আমি দুর্বল টাইপিং প্রোগ্রামিং ভাষার অপছন্দ করতে শুরু করছি। সব কিছু আলাদা করে লেখা হয়। আপনি সময় বাঁচান না এবং আপনি বিশেষ নন। আমি কোডটি এইভাবে লিখি না, কারণ সময় পার হওয়ার পরে, আমিই এটির ডিবাগ করা দরকার। ক্লান্ত মস্তিষ্কের জন্য সত্যিই অগোছালো লাগছে! আমি জানি আমার ইংরাজী ইংরেজী, তবে কমপক্ষে চেষ্টা করে দেখি।
স্টিফ্যানচ

1
বলছি, আমি সিমফনি থেকে কেবল কোডটি পোর্ট করেছি। এইভাবে আমি এটি গ্রহণ করেছি। এটির জন্য এটি গুরুত্বপূর্ণ - এটি কাজ করে এবং এটি বেশ পুঙ্খানুপুঙ্খ বলে মনে হয়। আমি নিজেও, বিষয়টিও যথেষ্ট পাঠযোগ্য নয় তবে এটি সম্পূর্ণরূপে পুনরায় লেখার জন্য আমার হাতে সময় নেই।
অ্যান্টিটক্সিক

2
আমার কাছে ভাল লাগছে। এগুলি হল টেরিনারি অপারেটর এবং যথাযথভাবে ব্যবহৃত হলে, পাঠযোগ্যতা হ্রাস না করে সময় (এবং বাইটস) বাঁচাতে পারে।
শোদেব

1
@antitoxic, -1 সিম্ফনি কোডার (অন্য অনেকের মতো) তারা জানে না যে তারা এই ক্ষেত্রে কী করছে। এটি আপনাকে হোস্টের নাম দেয় না (সাইমন এর উত্তর দেখুন)। এটি কেবল আপনাকে সেরা অনুমান দেয় যা বহুবার ভুল হবে
পেসারিয়ার

11

$_SERVER['HTTP_HOST']ফর্ম ব্যবহার করার পরেও, এক্সএসএস আক্রমণ সম্পর্কে চিন্তা না করে কোনও সাইটে সমস্ত লিঙ্ক ব্যবহার করা কি "নিরাপদ" ?

হ্যাঁ, এটি ব্যবহার করা নিরাপদ$_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 নির্ভরশীল ➫➫ :

এখানে কোনও গ্যারান্টি নেই যে প্রতিটি ওয়েব সার্ভার এগুলির [ $_SERVERএনট্রি] কোনও সরবরাহ করবে ; সার্ভারগুলি কিছু বাদ দিতে পারে বা অন্যকে এখানে তালিকাভুক্ত নয় provide

হোস্টের নামটি কীভাবে পুনরুদ্ধার করবেন তা বোঝার জন্য, প্রথম এবং সর্বাগ্রে আপনার বুঝতে হবে যে যে সার্ভারটিতে কেবল কোড রয়েছে তার নেটওয়ার্কে নিজের নাম জানার (যাচাই করার প্রাক-প্রয়োজনীয়তা) কোনও উপায় নেই । এটিকে এমন একটি উপাদান দিয়ে ইন্টারফেস করা দরকার যা এটির নিজের নাম সরবরাহ করে। এটি এর মাধ্যমে করা যেতে পারে:

  • স্থানীয় কনফিগারেশন ফাইল

  • স্থানীয় ডাটাবেস

  • হার্ডকোডযুক্ত উত্স কোড

  • বাহ্যিক অনুরোধ ( কার্ল )

  • ক্লায়েন্ট / আক্রমণকারীর Host:অনুরোধ

  • ইত্যাদি

সাধারণত এটি স্থানীয় (SAPI) কনফিগার ফাইলের মাধ্যমে সম্পন্ন হয়। মনে রাখবেন আপনি এটিকে সঠিকভাবে কনফিগার করেছেন, যেমন অ্যাপাচি ➫➫ ➫➫ :

গতিশীল ভার্চুয়াল হোস্টটিকে সাধারণের মতো দেখতে কিছু জিনিস 'নকল' হওয়া দরকার।

সর্বাধিক গুরুত্বপূর্ণ হ'ল সার্ভারের নাম যা আপাচি দ্বারা স্ব-রেফারেন্সিয়াল ইউআরএল তৈরি করতে ব্যবহৃত হয়, ইত্যাদি এটি কনফিগার করা আছে ServerName নির্দেশের এবং এটি সিজিআই-র মাধ্যমে উপলব্ধ isSERVER_NAME পরিবেশ পরিবর্তনশীলের ।

রান সময় ব্যবহৃত প্রকৃত মান ইউজকনোনিক্যালনাম সেটিং দ্বারা নিয়ন্ত্রিত হয়

UseCanonicalName Offসার্ভারের সাথেHost: অনুরোধের শিরোনামের সামগ্রীগুলি থেকে নাম আসে name এটির সাথে UseCanonicalName DNS ভার্চুয়াল হোস্টের আইপি ঠিকানার বিপরীত ডিএনএস লুকআপ আসে। পূর্ববর্তী সেটিংসটি নাম ভিত্তিক গতিশীল ভার্চুয়াল হোস্টিংয়ের জন্য ব্যবহৃত হয় এবং পরবর্তীটিটি ** আইপি-ভিত্তিক হোস্টিংয়ের জন্য ব্যবহৃত হয়।

Host:শিরোনাম না থাকায় বা যদি ডিএনএস লুকআপ ব্যর্থ হয় তবে অ্যাপাচি যদি সার্ভার নামটি কাজ করতে না পারে তবেServerName পরিবর্তে কনফিগার করা মানটি ব্যবহার করা হবে।


8

উভয়ের মধ্যে প্রধান পার্থক্য $_SERVER['SERVER_NAME']হ'ল একটি সার্ভার নিয়ন্ত্রিত চলক, যখন while$_SERVER['HTTP_HOST'] একটি ব্যবহারকারী নিয়ন্ত্রিত মান।

থাম্বের বিধিটি হ'ল কখনও কখনও ব্যবহারকারীর কাছ থেকে মানগুলিকে বিশ্বাস করা উচিত $_SERVER['SERVER_NAME'] আরও ভাল পছন্দ।

গম্বো যেমন উল্লেখ করেছে, আপনি সেট না করা থাকলে অ্যাপাচি ব্যবহারকারী সরবরাহিত মান থেকে SERVER_NAME তৈরি করবে UseCanonicalName On

সম্পাদনা: সমস্ত কিছু বলা সত্ত্বেও, যদি সাইটটি কোনও নাম ভিত্তিক ভার্চুয়াল হোস্ট ব্যবহার করে, তবে HTTP হোস্ট শিরোনামই সেই সাইটগুলিতে পৌঁছানোর একমাত্র উপায় যা ডিফল্ট সাইট নয়।


বুঝতে পারছিল না। আমার হ্যাঙ্গআপটি হল "কোনও ব্যবহারকারী কীভাবে $ _SERVER ['HTTP_HOST'] এর মান পরিবর্তন করতে পারে?" এটা কি সম্ভব?
জেফ

5
কোনও ব্যবহারকারী এটি পরিবর্তন করতে পারে কারণ এটি আগত অনুরোধ থেকে কেবল হোস্ট শিরোনামের বিষয়বস্তু। প্রধান সার্ভার (বা VirtualHost আবদ্ধ ডিফল্ট : 80) সমস্ত অজানা হোস্ট সাড়া দিতে হবে, এইভাবে যে সাইটে হোস্ট ট্যাগ বিষয়বস্তু কিছু সেট করা যেতে পারে।
পাওয়ারলর্ড

4
নোট করুন যে আইপি-ভিত্তিক ভার্চুয়াল হোস্টগুলি সর্বদা তাদের নির্দিষ্ট আইপিতে প্রতিক্রিয়া জানায়, সুতরাং আপনি কোনও পরিস্থিতিতে তাদের উপর এইচটিটিপি হোস্ট মানকে বিশ্বাস করতে পারবেন না ।
পাওয়ারলর্ড

1
@ জেফ, এটি জিজ্ঞাসার মতো "পিজ্জার হাটের ফোন নম্বরটি কল করা এবং কেএফসি কর্মীদের সাথে কথা বলার অনুরোধ করা সম্ভব ?" অবশ্যই আপনি যে কোনও কিছুতে অনুরোধ করতে পারেন। @ পাওয়ারওয়ার্ড, আইপি-ভিত্তিক ভার্চুয়াল হোস্টগুলির সাথে এর কোনও যোগসূত্র নেই। আপনার সার্ভার, আইপি-ভিত্তিক ভার্চুয়াল হোস্ট নির্বিশেষে বা না হোক, কোনও পরিস্থিতিতেই HTTP এর Host:মানকে বিশ্বাস করতে পারে না যদি আপনি এটি নিজেই যাচাই না করে থাকেন, না হয় নিজেই বা আপনার SAPI এর সেটআপের মাধ্যমে।
প্যাসেরিয়ার

3

আমি নিশ্চিত এবং সত্যই বিশ্বাস $_SERVER['HTTP_HOST']করি না কারণ এটি ক্লায়েন্টের শিরোনামের উপর নির্ভর করে। অন্য উপায়ে, যদি ক্লায়েন্টের দ্বারা অনুরোধ করা কোনও ডোমেন আমার না হয় তবে তারা আমার সাইটে পাবে না কারণ ডিএনএস এবং টিসিপি / আইপি প্রোটোকল এটিকে সঠিক গন্তব্যে দেখায়। তবে আমি জানি না ডিএনএস, নেটওয়ার্ক বা এমনকি অ্যাপাচি সার্ভার হাইজ্যাক করা সম্ভব কিনা। নিরাপদ থাকতে, আমি পরিবেশে হোস্টের নামটি সংজ্ঞায়িত করি এবং এর সাথে তুলনা করি $_SERVER['HTTP_HOST']

যোগ SetEnv MyHost domain.com.htaccess ফাইল শিকড় এবং Common.php মধ্যে ths কোড যোগ

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

আমি এই পিএইচপি পৃষ্ঠায় এই কমন.এফপি ফাইলটি অন্তর্ভুক্ত করি। এই পৃষ্ঠায় প্রতিটি অনুরোধের জন্য প্রয়োজনীয় কিছু করছে যেমন session_start()সেশন কুকি সংশোধন করুন এবং পোস্ট পদ্ধতিটি যদি অন্য ডোমেন থেকে আসে তবে তা প্রত্যাখ্যান করুন।


1
অবশ্যই এটি ডিএনএসকে বাইপাস করা সম্ভব। একজন আক্রমণকারী Host:সরাসরি আপনার সার্ভারের আইপিতে একটি খাঁটি মূল্য দিতে পারে।
পেসারিয়ার


1

প্রথমে আমি সমস্ত ভাল উত্তর এবং ব্যাখ্যার জন্য আপনাকে ধন্যবাদ জানাতে চাই। বেস ইউআরএল পাওয়ার জন্য আপনার সমস্ত উত্তরের উপর ভিত্তি করেই আমি এই পদ্ধতিটি তৈরি করেছি। আমি কেবল এটি খুব বিরল পরিস্থিতিতে ব্যবহার করি। সুতরাং এক্সএসএস আক্রমণগুলির মতো সুরক্ষা ইস্যুগুলিতে কোনও বড় ফোকাস নেই। কারও প্রয়োজন হতে পারে।

// 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]; }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.