HTML / PHP के साथ XSS को कैसे रोकें?


256

मैं केवल HTML और PHP का उपयोग करके XSS (क्रॉस-साइट स्क्रिप्टिंग) को कैसे रोकूं?

मैंने इस विषय पर कई अन्य पोस्ट देखे हैं, लेकिन मुझे एक लेख नहीं मिला है जो स्पष्ट और स्पष्ट रूप से बताता है कि वास्तव में XSS को कैसे रोका जाए।


3
बस ध्यान दें कि यह उस मामले को हल नहीं करेगा जहां आप एचटीएमएल विशेषता के रूप में उपयोगकर्ता इनपुट का उपयोग करना चाहते हैं। उदाहरण के लिए, किसी छवि का स्रोत URL। एक सामान्य मामला नहीं है, लेकिन भूलना आसान है।
माइकल मिओर

@MichaelMior यहाँ XSS hrefया srcHTML विशेषता को रोकने के लिए एक समाधान है : stackoverflow.com/questions/19047119/…
baptx

यहाँ एक अच्छा लेख है जो एक्सएसएस और विभिन्न भाषाओं में इसे रोकने के तरीके (incl। PHP) के बारे में बताता है।
XCore

जवाबों:


296

मूल रूप से आपको फ़ंक्शन का उपयोग करने की आवश्यकता होती है htmlspecialchars()जब भी आप उपयोगकर्ता इनपुट से आए ब्राउज़र को कुछ आउटपुट करना चाहते हैं।

इस फ़ंक्शन का उपयोग करने का सही तरीका कुछ इस प्रकार है:

echo htmlspecialchars($string, ENT_QUOTES, 'UTF-8');

Google कोड विश्वविद्यालय में वेब सुरक्षा पर ये बहुत ही शैक्षिक वीडियो भी हैं:


7
@TimTim: अधिकांश मामलों के लिए, हाँ। हालाँकि, जब आपको HTML इनपुट चीज़ों को थोड़ा पेचीदा बनाने की अनुमति देने की आवश्यकता होती है और यदि ऐसा है तो मैं आपको htmlpurifier.org
Alix Axel

@ एलिक्स एक्सल, तो क्या आपका उत्तर htmlspecialchars का उपयोग करने या htmlpurifier.org का उपयोग करने के लिए है ?
तैतीस

3
यदि आपको HTML इनपुट का उपयोग करने की आवश्यकता है तो HTML Purifier का उपयोग करें, यदि नहीं htmlspecialchars()
एलिक्स एक्सल

9
htmlspecialchars या htmlentities? यहाँ देखें stackoverflow.com/questions/46483/…
kiranvj

4
ज्यादातर समय यह सही है, लेकिन यह उतना सरल नहीं है। आपको HTML, Js, Css में अविश्वासित स्ट्रिंग पर विचार करना चाहिए, और HTML में अविश्वसनीय HTML पर विचार करना चाहिए। इसे देखें: owasp.org/index.php/…
कांस्य पुरुष

41

मेरे पसंदीदा OWASP संदर्भों में से एक क्रॉस-साइट स्क्रिप्टिंग स्पष्टीकरण है, क्योंकि बड़ी संख्या में XSS अटैक वैक्टर हैं, लेकिन कुछ नियमों का पालन उनमें से अधिकांश के खिलाफ बचाव कर सकता है!

यह PHP Security Cheat Sheet है


7
मुझे भी .. यह XSS फ़िल्टर एविएशन

1
बिल्कुल XSS नहीं, लेकिन मुझे लगता है कि XSS और CSRF आमतौर पर मिश्रित होते हैं और दोनों वास्तव में खतरनाक होते हैं: owasp.org/index.php/…
साइमन

2
यह पेज अब मौजूद नहीं है
Mazzy

1
@ माज़ी आखिरी कैश web.archive.org/web/20180817180409/owasp.org/index.php/…
Wahyu Kristianto

15

सबसे महत्वपूर्ण चरणों में से एक है किसी भी उपयोगकर्ता इनपुट को संसाधित करने से पहले और ब्राउज़र पर वापस भेज दिया जाना। PHP में कुछ " फ़िल्टर " फ़ंक्शन हैं जिनका उपयोग किया जा सकता है।

आमतौर पर XSS के हमलों का वह रूप कुछ ऑफ-साइट जावास्क्रिप्ट के लिए एक लिंक सम्मिलित करना होता है जिसमें उपयोगकर्ता के लिए दुर्भावनापूर्ण इरादे होते हैं। इसके बारे में यहाँ और पढ़ें ।

आप अपनी साइट का परीक्षण भी करना चाहेंगे - मैं फ़ायरफ़ॉक्स ऐड-ऑन एक्सएसएस मी की सिफारिश कर सकता हूं ।


मुझे यह सुनिश्चित करने की आवश्यकता है कि मैं इनपुट को बिल्कुल सटीक रूप से साफ कर दूं। क्या कोई विशेष चरित्र / स्ट्रिंग है जिसे मुझे बाहर देखना है?
तैतिल

27
@TimTim - नहीं। सभी उपयोगकर्ता इनपुट को हमेशा अंतर्निहित शत्रुता माना जाना चाहिए ।
ज़ोम्बैट

इसके अलावा, आंतरिक डेटा (कर्मचारी, sysadmin, आदि) असुरक्षित हो सकता है। आपको व्याख्या के साथ प्रदर्शित (लॉग तिथि और उपयोगकर्ता के साथ) डेटा की पहचान और निगरानी करनी चाहिए।
सैमुअल Dauzon

9

वरीयता के क्रम में:

  1. यदि आप एक टेम्प्लेटिंग इंजन (जैसे टहनी, होशियार, ब्लेड) का उपयोग कर रहे हैं, तो जांच लें कि यह संदर्भ-संवेदनशील भागने की पेशकश करता है। मैं उस अनुभव से जानता हूं जो ट्विग करता है।{{ var|e('html_attr') }}
  2. यदि आप HTML को अनुमति देना चाहते हैं, तो HTML Purifier का उपयोग करें । यहां तक ​​कि अगर आपको लगता है कि आप केवल मार्कडाउन या रीस्ट्रक्टर्डटेक्स्ट स्वीकार करते हैं, तो भी आप HTML को इन मार्कअप लैंग्वेज आउटपुट से शुद्ध करना चाहते हैं।
  3. अन्यथा, उपयोग करें htmlentities($var, ENT_QUOTES | ENT_HTML5, $charset)और सुनिश्चित करें कि आपके दस्तावेज़ के बाकी हिस्से उसी तरह के वर्ण का उपयोग करते हैं $charset। ज्यादातर मामलों में, 'UTF-8'वांछित चरित्र सेट है।

इसके अलावा, सुनिश्चित करें कि आप आउटपुट पर बच सकते हैं, इनपुट पर नहीं


7

इसे एसओ डॉक्यूमेंटेशन बीटा से एक समेकित संदर्भ के रूप में क्रॉस-पोस्ट करना जो ऑफ़लाइन हो रहा है।

संकट

क्रॉस-साइट स्क्रिप्टिंग एक वेब क्लाइंट द्वारा दूरस्थ कोड का अनपेक्षित निष्पादन है। यदि कोई उपयोगकर्ता से इनपुट लेता है और उसे सीधे वेब पेज पर आउटपुट करता है, तो कोई भी वेब एप्लिकेशन एक्सएसएस के लिए खुद को उजागर कर सकता है। यदि इनपुट में HTML या JavaScript शामिल है, तो वेब क्लाइंट द्वारा इस सामग्री को प्रदान किए जाने पर दूरस्थ कोड निष्पादित किया जा सकता है।

उदाहरण के लिए, यदि तृतीय पक्ष पक्ष में जावास्क्रिप्ट फ़ाइल है:

// http://example.com/runme.js
document.write("I'm running");

और एक PHP अनुप्रयोग सीधे एक स्ट्रिंग को आउटपुट करता है जो इसमें उत्तीर्ण होता है:

<?php
echo '<div>' . $_GET['input'] . '</div>';

यदि एक अनियंत्रित GET पैरामीटर में है <script src="http://example.com/runme.js"></script>तो PHP स्क्रिप्ट का आउटपुट होगा:

<div><script src="http://example.com/runme.js"></script></div>

तीसरी पार्टी जावास्क्रिप्ट चलेगी और उपयोगकर्ता वेब पेज पर "मैं चल रहा हूं" देखेंगे।

उपाय

एक सामान्य नियम के रूप में, कभी भी क्लाइंट से आने वाले इनपुट पर भरोसा न करें। हर GET, POST, और कुकी मूल्य कुछ भी हो सकता है, और इसलिए इसे मान्य किया जाना चाहिए। जब इनमें से किसी भी मान का आउटपुट दिया जाता है, तो वे बच जाते हैं, इसलिए उनका मूल्यांकन अप्रत्याशित तरीके से नहीं किया जाएगा।

ध्यान रखें कि सरलतम अनुप्रयोगों में भी डेटा को इधर-उधर खिसकाया जा सकता है और सभी स्रोतों पर नज़र रखना कठिन होगा। इसलिए आउटपुट से हमेशा बचना सबसे अच्छा अभ्यास है ।

PHP संदर्भ के आधार पर आउटपुट से बचने के कुछ तरीके प्रदान करता है।

फ़िल्टर फ़ंक्शंस

PHPs फ़िल्टर फ़ंक्शंस php स्क्रिप्ट में इनपुट डेटा को कई तरीकों से सैनिटाइज़ या मान्य करने की अनुमति देता है । क्लाइंट इनपुट को सहेजते या आउटपुट करते समय वे उपयोगी होते हैं।

HTML एनकोडिंग

htmlspecialcharsकिसी भी "HTML विशेष वर्ण" को उनके HTML एन्कोडिंग में परिवर्तित कर देगा, जिसका अर्थ है कि तब उन्हें मानक HTML के रूप में संसाधित नहीं किया जाएगा। इस विधि का उपयोग करके हमारे पिछले उदाहरण को ठीक करने के लिए:

<?php
echo '<div>' . htmlspecialchars($_GET['input']) . '</div>';
// or
echo '<div>' . filter_input(INPUT_GET, 'input', FILTER_SANITIZE_SPECIAL_CHARS) . '</div>';

उत्पादन होगा:

<div>&lt;script src=&quot;http://example.com/runme.js&quot;&gt;&lt;/script&gt;</div>

<div>टैग के अंदर सब कुछ ब्राउज़र द्वारा जावास्क्रिप्ट टैग के रूप में व्याख्या नहीं किया जाएगा , बल्कि एक साधारण पाठ नोड के रूप में। उपयोगकर्ता सुरक्षित रूप से देखेगा:

<script src="http://example.com/runme.js"></script>

URL एनकोडिंग

डायनामिक रूप से जेनरेट किए गए URL urlencodeको आउटपुट करते समय, PHP वैध URL को सुरक्षित रूप से आउटपुट करने के लिए फ़ंक्शन प्रदान करता है । इसलिए, उदाहरण के लिए, यदि कोई उपयोगकर्ता उस डेटा को इनपुट करने में सक्षम है जो अन्य GET पैरामीटर का हिस्सा बन जाता है:

<?php
$input = urlencode($_GET['input']);
// or
$input = filter_input(INPUT_GET, 'input', FILTER_SANITIZE_URL);
echo '<a href="http://example.com/page?input="' . $input . '">Link</a>';

किसी भी दुर्भावनापूर्ण इनपुट को एन्कोडेड URL पैरामीटर में बदल दिया जाएगा।

विशेष बाहरी पुस्तकालयों या OWASP AntiSamy सूचियों का उपयोग करना

कभी-कभी आप HTML या अन्य प्रकार के कोड इनपुट भेजना चाहेंगे। आपको अधिकृत शब्दों (श्वेत सूची) और गैर-अधिकृत (ब्लैकलिस्ट) की सूची बनाए रखने की आवश्यकता होगी।

आप OWASP AntiSamy वेबसाइट पर उपलब्ध मानक सूचियों को डाउनलोड कर सकते हैं । प्रत्येक सूची एक विशिष्ट प्रकार के इंटरैक्शन के लिए फिट है (ईबे एपी, स्मॉलमसीई, आदि ...)। और यह खुला स्रोत है।

HTML को फ़िल्टर करने के लिए और सामान्य मामले के लिए XSS हमलों को रोकने के लिए मौजूद लाइब्रेरी हैं और कम से कम एंटीस्माइ सूचियों के साथ बहुत आसान उपयोग करते हैं। उदाहरण के लिए आपके पास HTML शोधक है


5

कई चौखटे विभिन्न तरीकों से XSS को संभालने में मदद करती हैं। अपना स्वयं का रोल करते समय या यदि कुछ XSS चिंता है, तो हम filter_input_array का लाभ उठा सकते हैं (PHP 5 में उपलब्ध है = 5.2.0, PHP 7.) मैं आमतौर पर इस स्निपेट को अपने SessionController में जोड़ दूंगा, क्योंकि सभी कॉल किसी भी अन्य नियंत्रक से पहले वहां जाते हैं। डेटा के साथ सहभागिता करता है। इस तरीके से, सभी उपयोगकर्ता इनपुट 1 केंद्रीय स्थान में साफ हो जाते हैं। यदि यह किसी प्रोजेक्ट की शुरुआत में या आपके डेटाबेस के ज़हर खाने से पहले किया जाता है, तो आपको आउटपुट के समय कोई समस्या नहीं होनी चाहिए ... कचरा बाहर, कचरा बाहर रोकता है।

/* Prevent XSS input */
$_GET   = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
$_POST  = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
/* I prefer not to use $_REQUEST...but for those who do: */
$_REQUEST = (array)$_POST + (array)$_GET + (array)$_REQUEST;

उपरोक्त सभी HTML और स्क्रिप्ट टैग हटा देगा । यदि आपको एक समाधान की आवश्यकता है जो एक श्वेतसूची के आधार पर सुरक्षित टैग की अनुमति देता है, तो HTML शोधकर्ता की जांच करें ।


यदि आपका डेटाबेस पहले से ही ज़हर है या आप आउटपुट के समय XSS से निपटना चाहते हैं, तो OWASP इसके लिए एक कस्टम रैपर फ़ंक्शन बनाने की सलाह देता है echo, और इसका उपयोग करके आप उपयोगकर्ता द्वारा आपूर्ति किए गए मानों का उत्पादन करते हैं:

//xss mitigation functions
function xssafe($data,$encoding='UTF-8')
{
   return htmlspecialchars($data,ENT_QUOTES | ENT_HTML401,$encoding);
}
function xecho($data)
{
   echo xssafe($data);
}

2

आप कुछ XSS संबंधित HTTP प्रतिसाद हेडर के माध्यम से भी सेट करने में सक्षम हैं header(...)

X-XSS- सुरक्षा "1; मोड = ब्लॉक"

यह सुनिश्चित करने के लिए, ब्राउज़र XSS सुरक्षा मोड सक्षम है।

सामग्री-सुरक्षा-नीति "डिफ़ॉल्ट-src 'स्वयं'; ..."

ब्राउज़र-साइड सामग्री सुरक्षा को सक्षम करने के लिए। सामग्री सुरक्षा नीति (CSP) विवरण के लिए इसे देखें: http://content-security-policy.com/ विशेष रूप से इनलाइन-स्क्रिप्ट्स को ब्लॉक करने के लिए CSP की स्थापना और बाहरी स्क्रिप्ट स्रोत XSS के विरुद्ध सहायक है।

आप की सुरक्षा से संबंधित उपयोगी HTTP रिस्पांस हेडर के एक सामान्य समूह के लिए, OWASP: https://www.owasp.org/index.php/List_of_useful_HTTP_headers देखें


1
<?php
function xss_clean($data)
{
// Fix &entity\n;
$data = str_replace(array('&amp;','&lt;','&gt;'), array('&amp;amp;','&amp;lt;','&amp;gt;'), $data);
$data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data);
$data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data);
$data = html_entity_decode($data, ENT_COMPAT, 'UTF-8');

// Remove any attribute starting with "on" or xmlns
$data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data);

// Remove javascript: and vbscript: protocols
$data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data);

// Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data);

// Remove namespaced elements (we do not need them)
$data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data);

do
{
    // Remove really unwanted tags
    $old_data = $data;
    $data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
}
while ($old_data !== $data);

// we are done...
return $data;
}

5
आपके इनपुट पर preg_replaceइसका उपयोग नहीं करना चाहिए evalowasp.org/index.php/PHP_Security_Cheat_Sheet#Code_Injection
CrabLab

0

का प्रयोग करें htmlspecialcharsपर PHP। HTML का उपयोग करने से बचने की कोशिश करें:

element.innerHTML = “…”; element.outerHTML = “…”; document.write(…); document.writeln(…);

जहां varहै उपयोगकर्ता द्वारा नियंत्रित किया

इसके अलावा स्पष्ट रूप से टालने की कोशिश करें eval(var), अगर आपको उनमें से किसी का उपयोग करना है तो जेएस से बचने की कोशिश करें, एचटीएमएल उनसे बच जाए और आपको कुछ और करना होगा लेकिन मूल बातें के लिए यह पर्याप्त होना चाहिए।


0

htmlentitiesफ़ंक्शन का उपयोग करने वाले अपने इनपुट को सुरक्षित रखने का सबसे अच्छा तरीका है । उदाहरण:

htmlentities($target, ENT_QUOTES, 'UTF-8');

आप यहाँ अधिक जानकारी प्राप्त कर सकते हैं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.