পাইথনে এইচটিএমএল এড়ানো সহজতম উপায় কী?


137

cgi.escape মনে হয় একটি সম্ভাব্য পছন্দ। এটা কি ভাল কাজ করে? এমন কিছু আছে যা আরও ভাল বলে বিবেচিত হয়?

উত্তর:


176

cgi.escapeভাল. এটি পালিয়ে যায়:

  • < প্রতি &lt;
  • > প্রতি &gt;
  • & প্রতি &amp;

সমস্ত HTML এর জন্য এটি যথেষ্ট for

সম্পাদনা: আপনার যদি অ-এস্কি অক্ষর থাকে তবে আপনি পালাতেও চান, অন্য কোনও এনকোডড ডকুমেন্টের অন্তর্ভুক্তির জন্য যা আলাদা এনকোডিং ব্যবহার করে, যেমন ক্রেগ বলেছেন, কেবল ব্যবহার করুন:

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এছাড়াও ডাবল উদ্ধৃতি অক্ষর পালাতে ( ") যাতে আপনি আপনার এক্সএমএল / এইচটিএমএল অ্যাট্রিবিউট ফলে মান ব্যবহার করতে পারেন।

সম্পাদনা: দ্রষ্টব্য যে সিজি.ইসকেপ পাইথন ৩.২ এ অনুগ্রহ html.escapeকরে চলেছে, যা quoteসত্যের ডিফল্ট ব্যতীত একই কাজ করে ।


7
এইচটিএমএল অ্যাট্রিবিউটের মানগুলিতে টেক্সট ব্যবহার করার সময় সিজি.ইসকেপে অতিরিক্ত বুলিয়ান প্যারামিটারগুলি উদ্ধৃতি অব্যাহতির জন্যও বিবেচনা করা উচিত।
গ্রেগ হিউগিল

কেবলমাত্র নিশ্চিত হতে: আমি যদি cgi.escapeফাংশনটির মাধ্যমে সমস্ত অবিশ্বস্ত ডেটা চালাই তবে সমস্ত (জ্ঞাত) এক্সএসএস আক্রমণগুলির বিরুদ্ধে রক্ষা করার জন্য যথেষ্ট?
টমাস সেদোভিচ

@ টমাস সেদোভিচ: আপনি যেখানে cgi.escape চালানোর পরে পাঠ্যটি রাখবেন তার উপর নির্ভর করে। যদি রুট এইচটিএমএল প্রসঙ্গে স্থাপন করা হয় তবে হ্যাঁ, আপনি সম্পূর্ণ নিরাপদ।
nosklo

কি {{ব্যবস্থা 12 Ω "এইচ x 17 5/8" W X 8 7/8 "ডি আমদানিকৃত}।।} যে না ASCII এর, তাই সঙ্কেতাক্ষরে লিখা () আপনাকে এখানে একটি ব্যতিক্রম নিক্ষেপ করা হবে মত ইনপুট সম্পর্কে।
অ্যান্ড্রু Kolesnikov

@ অ্যান্ড্রু কোলেস্নিকভ: আপনি কি চেষ্টা করে দেখেছেন? cgi.escape(yourunicodeobj).encode('ascii', 'xmlcharrefreplace') == '{{Measures 12 &#937;"H x 17 5/8"W x 8 7/8"D. Imported.}}'- যেমন আপনি দেখতে পাচ্ছেন, এক্সএমএল অক্ষর রেফারেন্স সারণীটি ব্যবহার করে সমস্ত নন-এসসিআই ইউনিকোড অক্ষর এনকোডযুক্ত এক্সপ্রেশনটি ascii বাইট্রেস্টিং প্রত্যাবর্তন করে।
nosklo

112

পাইথন ৩.২-তে একটি নতুন 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
@ সালমানআববাস আপনি কি ভয় পেয়েছেন যে উদ্ধৃতিগুলি এড়ানো যায়নি? নোট করুন যে 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>'
optionচ্ছিক

@ ম্যাক্সচলেপজিগ আমার ধারণা সালমান বলছেন escape()বৈশিষ্ট্যগুলি নিরাপদ করার পক্ষে যথেষ্ট নয়। অন্য কথায়, এটি নিরাপদ নয়:<a href=" {{ html.escape(untrusted_text) }} ">
পিয়ানোজেমস

@ পিয়ানোজেমস, আমি দেখছি। আমি লিঙ্কের মানগুলি একটি ডোমেন নির্দিষ্ট শব্দার্থিক বৈধতা যাচাই করা বিবেচনা করি। পালানোর মতো লেজিকাল নয়। ইনলাইন জাভা স্ক্রিপ্ট ছাড়াও, আপনি আর ইউআরএল নির্দিষ্ট বৈধতা (উদাহরণস্বরূপ স্প্যামারগুলির কারণে) ছাড়াই অবিশ্বস্ত ব্যবহারকারী ইনপুট থেকে লিঙ্কগুলি তৈরি করতে চান না। এই জাতীয় বৈশিষ্ট্যগুলিতে ইনলাইন জাভা স্ক্রিপ্ট থেকে রক্ষা করার একটি সহজ পদ্ধতি href হ'ল একটি সামগ্রী সুরক্ষা নীতি সেট করা যা এটিকে অস্বীকার করে।
ম্যাক্সচলেপজিগ

@ পিয়ানোজেমস এটি নিরাপদ, কারণ html.escapeএকক উদ্ধৃতি এবং ডাবল উক্তিগুলি এড়ায় ।
ফ্লাইম

11

আপনি যদি কোনও ইউআরএল থেকে এইচটিএমএল থেকে পালাতে চান:

এটি সম্ভবত ওপি যা চেয়েছিল তা নয় (প্রশ্নটি স্পষ্টভাবে নির্দেশ করে না যে পালানোর বিষয়টি বোঝানো হয়েছে), কিন্তু পাইথনের নেটিভ লাইব্রেরি ইউরালিবের এইচটিএমএল সত্তাগুলি থেকে রক্ষা পাওয়ার জন্য একটি পদ্ধতি রয়েছে যা নিরাপদে কোনও URL- এ অন্তর্ভুক্ত করা দরকার need

নিচেরটি একটি উদাহরণ:

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

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

এখানে ডক্স সন্ধান করুন


10
এটি পালানোর ভুল ধরণের; আমরা খুঁজছেন এইচটিএমএল বেরিয়ে , যেমন উল্টোদিকে URL টি এনকোডিং
চসফিয়ার 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প্যাকেজ ভাল engineered হয়, এবং সম্ভবত বহুমুখী এবং Pythonic পথ সবচেয়ে পলায়নপর এই প্রোগ্রামটিতে, কারণ সম্পর্কে যেতে:

  1. রিটার্ন ( Markup) হ'ল একটি ক্লাস যা ইউনিকোড থেকে উত্পন্ন (isinstance(escape('str'), unicode) == True
  2. এটি সঠিকভাবে ইউনিকোড ইনপুট পরিচালনা করে
  3. এটি পাইথনে কাজ করে (২.6, ২.7, ৩.৩ এবং পাইপি)
  4. এটি বস্তুর কাস্টম পদ্ধতিগুলি (যেমন কোনও __html__সম্পত্তি সহ বস্তু ) এবং টেমপ্লেট ওভারলোডগুলি ( __html_format__) সম্মান করে ।

7

cgi.escape এইচটিএমএল ট্যাগ এবং চরিত্র সত্ত্বাগুলি পালানোর সীমিত অর্থে এইচটিএমএল থেকে বাঁচতে ভাল হওয়া উচিত।

তবে আপনাকে এনকোডিংয়ের বিষয়গুলিও বিবেচনা করতে হবে: আপনি যেই এইচটিএমএলটি উদ্ধৃত করতে চান তার যদি কোনও নির্দিষ্ট এনকোডিং-এ অ-এএসসিআইআই অক্ষর থাকে, তবে আপনাকেও যত্নবান হতে হবে যে আপনি উদ্ধৃতি দেওয়ার সময় সংবেদনশীলভাবে উপস্থাপন করছেন। সম্ভবত আপনি তাদের সত্তা রূপান্তর করতে পারে। অন্যথায় আপনার নিশ্চিত হওয়া উচিত যে অ-ASCII অক্ষরগুলি দূষিত করা এড়াতে "উত্স" এইচটিএমএল এবং এটি এমবেড করা পৃষ্ঠার মধ্যে সঠিক এনকোডিং অনুবাদগুলি করা হয়েছে।


3

কোনও লাইব্রেরি নেই, খাঁটি পাইথন, নিরাপদে এইচটিএমএল পাঠ্যে পাঠানো যায় না:

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

regex সংস্করণ

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

পাইথন ২.7-এ লিগ্যাসি কোডের জন্য এটি বিউটিফুলসপ এমপি 4 এর মাধ্যমে করতে পারেন :

>>> bs4.dammit import EntitySubstitution
>>> esub = EntitySubstitution()
>>> esub.substitute_html("r&d")
'r&amp;d'
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.