पायथन में HTML से बचने का सबसे आसान तरीका क्या है?


137

cgi.escape एक संभव पसंद की तरह लगता है। क्या यह अच्छी तरह से काम करता है? क्या कुछ ऐसा है जिसे बेहतर माना जाता है?

जवाबों:


176

cgi.escapeठीक है। यह बच जाता है:

  • < सेवा &lt;
  • > सेवा &gt;
  • & सेवा &amp;

यह सभी HTML के लिए पर्याप्त है।

संपादित करें: यदि आपके पास गैर-एससीआई चर है तो आप भी बचना चाहते हैं, एक अन्य एन्कोडेड दस्तावेज़ में शामिल करने के लिए जो एक अलग एन्कोडिंग का उपयोग करता है, जैसे क्रेग कहते हैं, बस उपयोग करें:

data.encode('ascii', 'xmlcharrefreplace')

डिकोड के लिए मत भूलना dataके लिए unicodeपहले जो कुछ भी एन्कोडिंग यह इनकोडिंग था का उपयोग कर।

हालांकि मेरे अनुभव में कि अगर आप अभी unicodeशुरू से ही हर समय काम करते हैं तो इस तरह की एनकोडिंग बेकार है । दस्तावेज़ हेडर ( utf-8अधिकतम संगतता के लिए) में निर्दिष्ट एन्कोडिंग के अंत में बस एनकोड करें ।

उदाहरण:

>>> cgi.escape(u'<a>bá</a>').encode('ascii', 'xmlcharrefreplace')
'&lt;a&gt;b&#225;&lt;/a&gt;

इसके अलावा ध्यान दें लायक (धन्यवाद ग्रेग) अतिरिक्त quoteपैरामीटर cgi.escapeलेता है। इसके साथ सेट करने पर True, cgi.escapeदोहरे उद्धरण चिह्नों ( ") से बच जाता है ताकि आप XML / HTML विशेषता में परिणामी मान का उपयोग कर सकें।

संपादित करें: ध्यान दें कि cgi.escape के पक्ष में पायथन 3.2 में पदावनत किया गया है html.escape, जो कि quoteसत्य को उस चूक के अलावा करता है ।


7
Cgi.escape के लिए अतिरिक्त बूलियन पैरामीटर को HTML विशेषता मानों में पाठ का उपयोग करने पर उद्धरण से बचने के लिए भी विचार किया जाना चाहिए।
ग्रेग हेविल

बस यह सुनिश्चित करने के लिए: यदि मैं cgi.escapeफ़ंक्शन के माध्यम से सभी अविश्वसनीय डेटा चलाता हूं , तो सभी (ज्ञात) एक्सएसएस अटैच के खिलाफ सुरक्षा के लिए पर्याप्त है?
टॉमस सेडोविक

@ टोमस सेदोविक: इस पर निर्भर करता है कि आप इसमें cgi.escape चलाने के बाद टेक्स्ट को कहां रखेंगे। यदि रूट HTML संदर्भ में रखा जाता है तो हां, आप पूरी तरह से सुरक्षित हैं।
3

इनपुट के बारे में क्या {{उपाय 12 Ω "H x 17 5/8" W x 8 7/8 "स्थान। आयातित।}}} यह ascii नहीं है, इसलिए सांकेतिक शब्दों में बदलना () आप पर एक अपवाद फेंक देंगे।
एंड्रयू कोलेस्निक

@Andrew Kolesnikov: क्या आपने इसकी कोशिश की है? cgi.escape(yourunicodeobj).encode('ascii', 'xmlcharrefreplace') == '{{Measures 12 &#937;"H x 17 5/8"W x 8 7/8"D. Imported.}}'- जैसा कि आप देख सकते हैं, एक्सिस वर्ण संदर्भ तालिका का उपयोग करके एन्कोडेड सभी गैर-एस्की यूनिकोड वर्णों के साथ, एसेटि बाइटस्ट्रिंग लौटता है।
nosklo

112

पायथन 3.2 में एक नया htmlमॉड्यूल पेश किया गया था, जिसका उपयोग HTML मार्कअप से आरक्षित वर्णों से बचने के लिए किया जाता है।

इसका एक कार्य है escape():

>>> import html
>>> html.escape('x > 2 && x < 7 single quote: \' double quote: "')
'x &gt; 2 &amp;&amp; x &lt; 7 single quote: &#x27; double quote: &quot;'

किस बारे में quote=True?
2rs2ts

1
@SalmanAbbas क्या आप डरते हैं कि उद्धरण बच नहीं रहे हैं? ध्यान दें कि html.escape()डिफॉल्ट रूप से (इसके विपरीत cgi.quote(), यदि बताया गया है, तो डिफ़ॉल्ट रूप से ), उद्धरणों से बच जाता है और केवल बच जाता है। इस प्रकार, मुझे स्पष्ट रूप से एक विशेषता के साथ कुछ को इंजेक्ट करने के लिए एक वैकल्पिक पैरामीटर सेट करना होगा html.escape(), अर्थात इसे विशेषताओं के लिए असुरक्षित बनाने के लिए:t = '" onclick="alert()'; t = html.escape(t, quote=False); s = f'<a href="about.html" class="{t}">foo</a>'
maxschlepzig

@ maxschlepzig मुझे लगता है कि सलमान कह escape()रहे हैं कि विशेषताओं को सुरक्षित बनाने के लिए पर्याप्त नहीं है। दूसरे शब्दों में, यह सुरक्षित नहीं है:<a href=" {{ html.escape(untrusted_text) }} ">
पियानो नाम

@pianoJames, मैं देखता हूं। मैं लिंक मानों को एक डोमेन विशिष्ट अर्थ सत्यापन की जाँच करने पर विचार करता हूं। बच निकलने जैसा कोई लेक्सिकल नहीं। इनलाइन जावा स्क्रिप्ट के अलावा, आप वास्तव में बिना यूआरएल विशिष्ट सत्यापन (जैसे स्पैम के कारण) के बिना अविश्वसनीय उपयोगकर्ता इनपुट से लिंक नहीं बनाना चाहते हैं। इनलाइन विशेषताओं में इनलाइन जावा स्क्रिप्ट के विरुद्ध सुरक्षा के लिए एक सरल तरीका href एक कंटेंट सिक्योरिटी पॉलिसी सेट करना है जो इसे अस्वीकृत कर देती है।
मैक्सक्लेपज़िग

@pianoJames यह सुरक्षित है, क्योंकि html.escapeसिंगल कोट्स और डबल कोट्स से बच जाते हैं।
फ्लि‍म

11

यदि आप URL में HTML से बचना चाहते हैं:

यह संभवतः ऐसा नहीं है कि ओपी चाहता था (यह प्रश्न स्पष्ट रूप से इंगित नहीं करता है कि किस संदर्भ में भागने का उपयोग किया जाना है), लेकिन पायथन की मूल लाइब्रेरी urllib में HTML संस्थाओं से बचने की एक विधि है जिसे सुरक्षित रूप से एक URL में शामिल करने की आवश्यकता है।

निम्नलिखित एक उदाहरण है:

#!/usr/bin/python
from urllib import quote

x = '+<>^&'
print quote(x) # prints '%2B%3C%3E%5E%26'

यहां डॉक्स ढूंढें


10
यह भागने का गलत प्रकार है; URL एन्कोडिंग के विपरीत, हम HTML से बच रहे हैं ।
चॉस्फीयर 2112

7
हालांकि - यह वही था जो मैं वास्तव में देख रहा था ;-)
ब्रैड

9

उत्कृष्ट मार्कअप कैफे पैकेज भी है

>>> from markupsafe import Markup, escape
>>> escape("<script>alert(document.cookie);</script>")
Markup(u'&lt;script&gt;alert(document.cookie);&lt;/script&gt;')

markupsafeपैकेज में अच्छी तरह से इंजीनियर है, और शायद बहुमुखी और pythonic तरीका सबसे भागने IMHO, क्योंकि के बारे में जाने के लिए:

  1. वापसी ( Markup) यूनिकोड (यानी) से प्राप्त एक वर्ग हैisinstance(escape('str'), unicode) == True
  2. यह ठीक से यूनिकोड इनपुट को संभालता है
  3. यह पायथन में काम करता है (2.6, 2.7, 3.3 और pypy)
  4. यह वस्तुओं के कस्टम तरीकों (यानी एक __html__संपत्ति के साथ वस्तुओं ) और टेम्पलेट अधिभार ( __html_format__) का सम्मान करता है ।

7

cgi.escape HTML टैग और चरित्र संस्थाओं से बचने के सीमित अर्थों में HTML से बचने के लिए अच्छा होना चाहिए।

लेकिन आपको एन्कोडिंग मुद्दों पर भी विचार करना पड़ सकता है: यदि आप जिस एचटीएमएल को उद्धृत करना चाहते हैं, उसमें एक विशेष एन्कोडिंग में गैर-एएससीआईआई अक्षर हैं, तो आपको यह भी ध्यान रखना होगा कि आप उद्धृत करते समय समझदारी से प्रतिनिधित्व करते हैं। शायद आप उन्हें संस्थाओं में बदल सकते हैं। अन्यथा आपको यह सुनिश्चित करना चाहिए कि गैर-ASCII वर्णों को दूषित करने से बचने के लिए "एन्कोडिंग" एचटीएमएल और उस पेज के बीच सही एन्कोडिंग अनुवाद किया जाता है।


3

कोई पुस्तकालय, शुद्ध अजगर, सुरक्षित रूप से HTML पाठ में पाठ से बच जाता है:

text.replace('&', '&amp;').replace('>', '&gt;').replace('<', '&lt;'
        ).encode('ascii', 'xmlcharrefreplace')

1
आपका आदेश गलत है, &lt;वसीयत से बच जाएगा&amp;lt;
जेसन एस

@ हसन एस फिक्स के लिए धन्यवाद!
स्पीडप्लेन

1

cgi.escape विस्तारित

यह संस्करण सुधारता है cgi.escape। यह व्हाट्सएप और न्यूलाइन्स को भी संरक्षित करता है। एक unicodeस्ट्रिंग लौटाता है ।

def escape_html(text):
    """escape strings for display in HTML"""
    return cgi.escape(text, quote=True).\
           replace(u'\n', u'<br />').\
           replace(u'\t', u'&emsp;').\
           replace(u'  ', u' &nbsp;')

उदाहरण के लिए

>>> escape_html('<foo>\nfoo\t"bar"')
u'&lt;foo&gt;<br />foo&emsp;&quot;bar&quot;'

1

सबसे आसान तरीका नहीं है, लेकिन फिर भी सीधा है। Cgi.escape मॉड्यूल से मुख्य अंतर - यह अभी भी ठीक से काम करेगा यदि &amp;आपके पाठ में पहले से ही है । जैसा कि आप इसे टिप्पणियों से देखते हैं:

cgi.escape संस्करण

def escape(s, quote=None):
    '''Replace special characters "&", "<" and ">" to HTML-safe sequences.
    If the optional flag quote is true, the quotation mark character (")
is also translated.'''
    s = s.replace("&", "&amp;") # Must be done first!
    s = s.replace("<", "&lt;")
    s = s.replace(">", "&gt;")
    if quote:
        s = s.replace('"', "&quot;")
    return s

रेगेक्स संस्करण

QUOTE_PATTERN = r"""([&<>"'])(?!(amp|lt|gt|quot|#39);)"""
def escape(word):
    """
    Replaces special characters <>&"' to HTML-safe sequences. 
    With attention to already escaped characters.
    """
    replace_with = {
        '<': '&gt;',
        '>': '&lt;',
        '&': '&amp;',
        '"': '&quot;', # should be escaped in attributes
        "'": '&#39'    # should be escaped in attributes
    }
    quote_pattern = re.compile(QUOTE_PATTERN)
    return re.sub(quote_pattern, lambda x: replace_with[x.group(0)], word)

0

अजगर 2.7 में विरासत कोड के लिए, के माध्यम से यह कर सकते हैं BeautifulSoup4 :

>>> bs4.dammit import EntitySubstitution
>>> esub = EntitySubstitution()
>>> esub.substitute_html("r&d")
'r&amp;d'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.