javascript - JQuery के साथ एचटीएमएल स्ट्रिंग से बचें




string escaping (16)

क्या किसी को jQuery में स्ट्रिंग से HTML से बचने का एक आसान तरीका पता है? मुझे एक मनमानी स्ट्रिंग को पार करने में सक्षम होना चाहिए और HTML पृष्ठ में प्रदर्शन के लिए इसे ठीक से बचाना है (जावास्क्रिप्ट / एचटीएमएल इंजेक्शन हमलों को रोकना)। मुझे यकीन है कि ऐसा करने के लिए jQuery का विस्तार करना संभव है, लेकिन मुझे इसे पूरा करने के लिए इस समय ढांचे के बारे में पर्याप्त जानकारी नहीं है।


Mustache.js से भी समाधान है

var entityMap = {
  '&': '&',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#39;',
  '/': '&#x2F;',
  '`': '&#x60;',
  '=': '&#x3D;'
};

function escapeHtml (string) {
  return String(string).replace(/[&<>"'`=\/]/g, function (s) {
    return entityMap[s];
  });
}

अंडरस्कोर का उपयोग करने में काफी आसान है:

_.escape(string) 

अंडरस्कोर एक उपयोगिता पुस्तकालय है जो कई विशेषताओं को प्रदान करता है जो मूल जेएस प्रदान नहीं करता है। यहां lodash भी है जो अंडरस्कोर के समान एपीआई है लेकिन अधिक प्रदर्शन करने के लिए फिर से लिखा गया था।


आप आसानी से वेनिला जेएस के साथ कर सकते हैं।

बस एक पाठ दस्तावेज़ दस्तावेज़ नोड जोड़ें। यह ब्राउज़र से बच जाएगा।

var escaped = document.createTextNode("<HTML TO/ESCAPE/>")
document.getElementById("[PARENT_NODE]").appendChild(escaped)

उदाहरण से बचने वाली सादा जावास्क्रिप्ट:

function escapeHtml(text) {
    var div = document.createElement('div');
    div.innerText = text;
    return div.innerHTML;
}

escapeHtml("<script>alert('hi!');</script>")
// "&lt;script&gt;alert('hi!');&lt;/script&gt;"

मैंने mustache.js उदाहरण को बढ़ाया है स्ट्रिंग ऑब्जेक्ट में escapeHTML() विधि जोड़ना।

var __entityMap = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': '&quot;',
    "'": '&#39;',
    "/": '&#x2F;'
};

String.prototype.escapeHTML = function() {
    return String(this).replace(/[&<>"'\/]/g, function (s) {
        return __entityMap[s];
    });
}

इस तरह "Some <text>, more Text&Text".escapeHTML() का उपयोग करना काफी आसान है।


मैंने एक छोटा सा काम लिखा जो यह करता है। यह केवल " , & , < और > बच निकलता है (लेकिन आम तौर पर आपको वैसे भी वैसे भी चाहिए)। यह पहले से प्रस्तावित समाधानों के बाद थोड़ा अधिक सुरुचिपूर्ण है जिसमें यह केवल सभी रूपांतरण करने के लिए एक .replace() का उपयोग करता है। ( संपादित करें 2: यदि आप मूल कोड के बारे में उत्सुक हैं तो इस कोड के अंत को देखें, तो कम कोड जटिलता फ़ंक्शन को छोटा और नीरस बनाती है।)

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&<>]/g, function (a) {
        return { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' }[a];
    });
}

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

भागना / और ' भी

Mklement की टिप्पणी के जवाब में संपादित करें।

किसी भी चरित्र को शामिल करने के लिए उपरोक्त फ़ंक्शन को आसानी से विस्तारित किया जा सकता है। बचने के लिए और अधिक वर्ण निर्दिष्ट करने के लिए, उन्हें नियमित अभिव्यक्ति (यानी /[...]/g अंदर) और /[...]/g ऑब्जेक्ट में प्रविष्टि के रूप में वर्ण वर्ग में दोनों को सम्मिलित करें। ( संपादित करें 2: इस समारोह को भी उसी तरह छोटा करें।)

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&'\/<>]/g, function (a) {
        return {
            '"': '&quot;', '&': '&amp;', "'": '&#39;',
            '/': '&#47;',  '<': '&lt;',  '>': '&gt;'
        }[a];
    });
}

उपर्युक्त उपयोग पर ध्यान दें &#39; apostrophe के लिए (प्रतीकात्मक इकाई &apos; इसके बजाय इस्तेमाल किया जा सकता है - यह एक्सएमएल में परिभाषित किया गया है, लेकिन मूल रूप से HTML spec में शामिल नहीं किया गया था और इसलिए सभी ब्राउज़रों द्वारा समर्थित नहीं किया जा सकता है। देखें: HTML वर्ण एन्कोडिंग पर विकिपीडिया लेख )। मुझे यह भी याद है कि दशमलव इकाइयों का उपयोग हेक्साडेसिमल का उपयोग करने से अधिक व्यापक रूप से समर्थित है, लेकिन मुझे अब इसके लिए स्रोत नहीं मिल रहा है। (और वहां कई ब्राउज़र नहीं हो सकते हैं जो हेक्साडेसिमल इकाइयों का समर्थन नहीं करते हैं।)

नोट: बच निकले वर्णों की सूची में / और ' उन सभी को उपयोगी नहीं है, क्योंकि उनके पास HTML में कोई विशेष अर्थ नहीं है और उन्हें भागने की आवश्यकता नहीं है

मूल escapeHtml फंक्शन

संपादित करें 2: मूल कार्य .replace() कॉलबैक के लिए आवश्यक ऑब्जेक्ट को संग्रहीत करने के लिए एक चर ( chr ) का उपयोग करता है। इस चर को फ़ंक्शन (अनिवार्य रूप से) थोड़ा बड़ा और अधिक जटिल बनाने के लिए इसे एक अतिरिक्त अज्ञात फ़ंक्शन की आवश्यकता होती है।

var escapeHtml = (function () {
    'use strict';
    var chr = { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };
    return function (text) {
        return text.replace(/[\"&<>]/g, function (a) { return chr[a]; });
    };
}());

मैंने परीक्षण नहीं किया है कि दो संस्करणों में से कौन सा तेज़ है। यदि आप करते हैं, तो यहां इसके बारे में जानकारी और लिंक जोड़ने के लिए स्वतंत्र महसूस करें।


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

मेरा बिंदु स्पष्ट करने के लिए, यहां उत्तरों में से एक का उपयोग करके एक उदाहरण है:

आइए कहें कि आप अपने ब्लॉग में एक टिप्पणी से एचटीएमएल से बचने के लिए फंक्शन एस्केप एचटीएमएल का उपयोग कर रहे हैं और फिर इसे अपने सर्वर पर पोस्ट कर रहे हैं।

var entityMap = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': '&quot;',
    "'": '&#39;',
    "/": '&#x2F;'
  };

  function escapeHtml(string) {
    return String(string).replace(/[&<>"'\/]/g, function (s) {
      return entityMap[s];
    });
  }

उपयोगकर्ता यह कर सकता था:

  • POST अनुरोध पैरामीटर संपादित करें और टिप्पणी को जावास्क्रिप्ट कोड से प्रतिस्थापित करें।
  • ब्राउजर कंसोल का उपयोग करके एचटीएमएल फंक्शन को ओवरराइट करें।

यदि उपयोगकर्ता इस स्निपेट को कंसोल में पेस्ट करता है तो यह XSS सत्यापन को बाईपास करेगा:

function escapeHtml(string){
   return string
}

यदि आप पुनः भागने से नहीं रोकते हैं, तो सभी समाधान बेकार हैं, उदाहरण के लिए अधिकांश समाधान बचते रहेंगे &amp;

escapeHtml = function (s) {
    return s ? s.replace(
        /[&<>'"]/g,
        function (c, offset, str) {
            if (c === "&") {
                var substr = str.substring(offset, offset + 6);
                if (/&(amp|lt|gt|apos|quot);/.test(substr)) {
                    // already escaped, do not re-escape
                    return c;
                }
            }
            return "&" + {
                "&": "amp",
                "<": "lt",
                ">": "gt",
                "'": "apos",
                '"': "quot"
            }[c] + ";";
        }
    ) : "";
};

यदि आपके पास underscore.js है, तो _.escape उपयोग _.escape (ऊपर पोस्ट की गई jQuery विधि से अधिक कुशल):

_.escape('Curly, Larry & Moe'); // returns: Curly, Larry &amp; Moe

यह एक अच्छा सुरक्षित उदाहरण है ...

function escapeHtml(str) {
    if (typeof(str) == "string"){
        try{
            var newStr = "";
            var nextCode = 0;
            for (var i = 0;i < str.length;i++){
                nextCode = str.charCodeAt(i);
                if (nextCode > 0 && nextCode < 128){
                    newStr += "&#"+nextCode+";";
                }
                else{
                    newStr += "?";
                }
             }
             return newStr;
        }
        catch(err){
        }
    }
    else{
        return str;
    }
}

Underscore.string lib का प्रयास करें, यह jQuery के साथ काम करता है।

_.str.escapeHTML('<div>Blah blah blah</div>')

उत्पादन:

'&lt;div&gt;Blah blah blah&lt;/div&gt;'

escape() और unescape() का उद्देश्य यूआरएल के लिए स्ट्रिंग एन्कोड / डीकोड करना है, न कि एचटीएमएल।

दरअसल, मैं उस चाल को करने के लिए निम्न स्निपेट का उपयोग करता हूं जिसके लिए किसी भी ढांचे की आवश्यकता नहीं होती है:

var escapedHtml = html.replace(/&/g, '&amp;')
                      .replace(/>/g, '&gt;')
                      .replace(/</g, '&lt;')
                      .replace(/"/g, '&quot;')
                      .replace(/'/g, '&apos;');

चूंकि आप jQuery का उपयोग कर रहे हैं, आप केवल तत्व की text प्रॉपर्टी सेट कर सकते हैं:

// before:
// <div class="someClass">text</div>
var someHtmlString = "<script>alert('hi!');</script>";

// set a DIV's text:
$("div.someClass").text(someHtmlString);
// after: 
// <div class="someClass">&lt;script&gt;alert('hi!');&lt;/script&gt;</div>

// get the text in a string:
var escaped = $("<div>").text(someHtmlString).html();
// value: 
// &lt;script&gt;alert('hi!');&lt;/script&gt;

यह उत्तर jQuery और सामान्य जेएस विधियों को प्रदान करता है, लेकिन यह डोम का उपयोग किए बिना सबसे छोटा है:

unescape(escape("It's > 20% less complicated this way."))

बच निकला स्ट्रिंग: It%27s%20%3E%2020%25%20less%20complicated%20this%20way.

यदि बच निकले स्थान आपको परेशान करते हैं, तो कोशिश करें:

unescape(escape("It's > 20% less complicated this way.").replace(/%20/g, " "))

बच निकला स्ट्रिंग: It%27s %3E 20%25 less complicated this way.

दुर्भाग्यवश, जावास्क्रिप्ट संस्करण 1.5 में escape() फ़ंक्शन को बहिष्कृत किया गया था। encodeURI() या encodeURIComponent() विकल्प हैं, लेकिन वे अनदेखा करते हैं, इसलिए कोड की अंतिम पंक्ति इस में बदल जाएगी:

decodeURI(encodeURI("It's > 20% less complicated this way.").replace(/%20/g, " ").replace("'", '%27'))

सभी प्रमुख ब्राउज़र अभी भी शॉर्ट कोड का समर्थन करते हैं, और पुरानी वेबसाइटों की संख्या को देखते हुए, मुझे संदेह है कि जल्द ही बदल जाएगा।


(function(undefined){
    var charsToReplace = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;'
    };

    var replaceReg = new RegExp("[" + Object.keys(charsToReplace).join("") + "]", "g");
    var replaceFn = function(tag){ return charsToReplace[tag] || tag; };

    var replaceRegF = function(replaceMap) {
        return (new RegExp("[" + Object.keys(charsToReplace).concat(Object.keys(replaceMap)).join("") + "]", "gi"));
    };
    var replaceFnF = function(replaceMap) {
        return function(tag){ return replaceMap[tag] || charsToReplace[tag] || tag; };
    };

    String.prototype.htmlEscape = function(replaceMap) {
        if (replaceMap === undefined) return this.replace(replaceReg, replaceFn);
        return this.replace(replaceRegF(replaceMap), replaceFnF(replaceMap));
    };
})();

कोई वैश्विक चर, कुछ स्मृति अनुकूलन। उपयोग:

"some<tag>and&symbol©".htmlEscape({'©': '&copy;'})

परिणाम है:

"some&lt;tag&gt;and&amp;symbol&copy;"

function htmlDecode(t){
   if (t) return $('<div />').html(t).text();
}

एक जादू की तरह काम करता है





escaping