cgi.escape wydaje się być jednym z możliwych wyborów. Czy to działa dobrze? Czy jest coś, co uważa się za lepsze?
cgi.escape
jest w porządku. Ucieka:
<
do <
>
do >
&
do &
To wystarczy dla całego HTML.
EDYCJA: Jeśli masz znaki inne niż ASCII, z których również chcesz uciec, aby włączyć je do innego zakodowanego dokumentu, który używa innego kodowania, jak mówi Craig , po prostu użyj:
data.encode('ascii', 'xmlcharrefreplace')
Nie zapomnij dekodowania data
do unicode
pierwszego, z wykorzystaniem co kodowania został zakodowany.
Jednak z mojego doświadczenia wynika, że ten rodzaj kodowania jest bezużyteczny, jeśli pracujesz z nim unicode
cały czas od początku. Po prostu zakoduj na końcu zgodnie z kodowaniem określonym w nagłówku dokumentu (utf-8
dla maksymalnej kompatybilności).
Przykład:
>>> cgi.escape(u'<a>bá</a>').encode('ascii', 'xmlcharrefreplace')
'<a>bá</a>
Warto również zwrócić uwagę (dzięki Greg) na dodatkowy quote
parametr cgi.escape
. Ustawiając ją na True
, cgi.escape
również wyłącza "
znak podwójnego cudzysłowu ( ), dzięki czemu można użyć wynikowej wartości w atrybucie XML / HTML.
EDYCJA: Zauważ, że cgi.escape został przestarzały w Pythonie 3.2 na korzyść html.escape
, który robi to samo, z wyjątkiem tego, że quote
domyślnie ma wartość True.
cgi.escape
funkcji, czy wystarczy, aby zabezpieczyć się przed wszystkimi (znanymi) atakami XSS?cgi.escape(yourunicodeobj).encode('ascii', 'xmlcharrefreplace') == '{{Measures 12 Ω"H x 17 5/8"W x 8 7/8"D. Imported.}}'
- jak widać, wyrażenie zwraca ascii bytestring, ze wszystkimi znakami Unicode innymi niż ASCII zakodowanymi przy użyciu tabeli odwołań znaków xml.W Pythonie 3.2
html
został wprowadzony nowy moduł, który służy do ucieczki znaków zastrzeżonych ze znaczników HTML.Ma jedną funkcję
escape()
:źródło
quote=True
?html.escape()
domyślnie nie stosuje cudzysłowów (w przeciwieństwie docgi.quote()
tego nie robi - i wyłącza tylko cudzysłowy, jeśli tak powiedziano). W związku z tym muszę jawnie ustawić opcjonalny parametr, aby wstrzyknąć coś do atrybutuhtml.escape()
, tj. Aby uczynić go niebezpiecznym dla atrybutów:t = '" onclick="alert()'; t = html.escape(t, quote=False); s = f'<a href="about.html" class="{t}">foo</a>'
escape()
nie wystarczy, aby atrybuty były bezpieczne. Innymi słowy, to nie jest bezpieczne:<a href=" {{ html.escape(untrusted_text) }} ">
href
jest ustawienie polityki bezpieczeństwa treści, która na to nie zezwala.html.escape
pojedyncze i podwójne cudzysłowy.Jeśli chcesz wyjść z kodu HTML w adresie URL:
Prawdopodobnie NIE jest to to, czego chciał OP (pytanie nie wskazuje jasno, w jakim kontekście ucieczka ma być używana), ale natywna biblioteka Pythona urllib ma metodę ucieczki z jednostek HTML, które muszą być bezpiecznie zawarte w adresie URL.
Oto przykład:
Znajdź dokumenty tutaj
źródło
Istnieje również doskonały pakiet zabezpieczający przed znacznikami .
markupsafe
Pakiet jest dobrze zaprojektowane, i prawdopodobnie najbardziej wszechstronny i pythonowy droga o ucieczce, IMHO, ponieważ:Markup
) jest klasą pochodzącą z Unicode (tjisinstance(escape('str'), unicode) == True
__html__
właściwością) i przeciążenia szablonów (__html_format__
).źródło
cgi.escape
powinna być dobra ucieczka przed HTML w ograniczonym sensie ucieczki przed znacznikami HTML i jednostkami znakowymi.Ale być może będziesz musiał również wziąć pod uwagę problemy z kodowaniem: jeśli HTML, który chcesz zacytować, zawiera znaki spoza ASCII w określonym kodowaniu, musisz również uważać, aby rozsądnie je przedstawiać podczas cytowania. Być może mógłbyś przekształcić je w byty. W przeciwnym razie należy upewnić się, że między „źródłowym” kodem HTML a stroną, na której jest osadzony, wykonywane są prawidłowe tłumaczenia kodowania, aby uniknąć uszkodzenia znaków spoza zestawu ASCII.
źródło
Brak bibliotek, czysty Python, bezpiecznie zapisuje tekst w tekście html:
źródło
<
testament uciekł do&lt;
cgi.escape
rozszerzonyTa wersja jest ulepszona
cgi.escape
. Zachowuje również spacje i nowe linie. Zwracaunicode
ciąg.na przykład
źródło
Nie jest to najłatwiejszy sposób, ale nadal prosty. Główna różnica w stosunku do modułu cgi.escape - nadal będzie działać poprawnie, jeśli już masz
&
w tekście. Jak widać z komentarzy do tego:Wersja cgi.escape
wersja regex
źródło
W przypadku starszego kodu w Pythonie 2.7 można to zrobić za pośrednictwem BeautifulSoup4 :
źródło