cgi.escape parece una opción posible. ¿Funciona bien? ¿Hay algo que se considere mejor?
cgi.escape
está bien. Se escapa:
<
a <
>
a >
&
a &
Eso es suficiente para todo HTML.
EDITAR: si tiene caracteres no ascii de los que también quiere escapar, para incluirlos en otro documento codificado que use una codificación diferente, como dice Craig , simplemente use:
data.encode('ascii', 'xmlcharrefreplace')
No se olvide de decodificación data
de unicode
primera, utilizando cualquier codificación que se ha codificado.
Sin embargo, en mi experiencia, ese tipo de codificación es inútil si solo trabajas unicode
todo el tiempo desde el principio. Simplemente codifique al final la codificación especificada en el encabezado del documento ( utf-8
para una compatibilidad máxima).
Ejemplo:
>>> cgi.escape(u'<a>bá</a>').encode('ascii', 'xmlcharrefreplace')
'<a>bá</a>
También vale la pena señalar (gracias Greg) son las tomas de quote
parámetros adicionales cgi.escape
. Con esto establecido en True
, cgi.escape
también escapa caracteres de comillas dobles ( "
) para que pueda usar el valor resultante en un atributo XML / HTML.
EDITAR: Tenga en cuenta que cgi.escape ha quedado en desuso en Python 3.2 a favor de html.escape
, lo que hace lo mismo, excepto que el valor quote
predeterminado es True.
cgi.escape
función, ¿es suficiente para proteger contra todos los ataques XSS (conocidos)?cgi.escape(yourunicodeobj).encode('ascii', 'xmlcharrefreplace') == '{{Measures 12 Ω"H x 17 5/8"W x 8 7/8"D. Imported.}}'
- como puede ver, la expresión devuelve una cadena de bytes ascii, con todos los caracteres unicode no ascii codificados utilizando la tabla de referencia de caracteres xml.En Python 3.2
html
se introdujo un nuevo módulo, que se utiliza para escapar de los caracteres reservados del marcado HTML.Tiene una función
escape()
:fuente
quote=True
?html.escape()
comillas de escape se omiten de manera predeterminada (en contraste,cgi.quote()
no lo hacen, y solo se escapan las comillas dobles, si se le indica). Por lo tanto, tengo que establecer explícitamente un parámetro opcional para inyectar algo en un atributohtml.escape()
, es decir, hacerlo inseguro para los atributos:t = '" onclick="alert()'; t = html.escape(t, quote=False); s = f'<a href="about.html" class="{t}">foo</a>'
escape()
que no es suficiente para que los atributos sean seguros. En otras palabras, esto no es seguro:<a href=" {{ html.escape(untrusted_text) }} ">
href
es establecer una Política de seguridad de contenido que no lo permita.html.escape
se escapa entre comillas simples y comillas dobles.Si desea escapar de HTML en una URL:
Probablemente esto NO sea lo que el OP quería (la pregunta no indica claramente en qué contexto se pretende usar el escape), pero la biblioteca nativa de Python urllib tiene un método para escapar de las entidades HTML que deben incluirse en una URL de forma segura.
Lo siguiente es un ejemplo:
Encuentra documentos aquí
fuente
También está el excelente paquete de marcado seguro .
El
markupsafe
paquete está bien diseñado, y probablemente la forma más versátil y pitónica de escapar, en mi humilde opinión, porque:Markup
) es una clase derivada de unicode (es decirisinstance(escape('str'), unicode) == True
__html__
propiedad) y sobrecargas de plantillas (__html_format__
).fuente
cgi.escape
debería ser bueno escapar de HTML en el sentido limitado de escapar de las etiquetas HTML y las entidades de caracteres.Pero es posible que también deba considerar problemas de codificación: si el HTML que desea citar tiene caracteres que no son ASCII en una codificación particular, entonces también deberá asegurarse de representarlos de manera sensata al citarlos. Quizás podrías convertirlos en entidades. De lo contrario, debe asegurarse de que se realicen las traducciones de codificación correctas entre el HTML "fuente" y la página en la que está incrustado, para evitar corromper los caracteres no ASCII.
fuente
Ninguna biblioteca, Python puro, escapa de forma segura de texto a texto html:
fuente
<
se escapará a&lt;
cgi.escape
extendidoEsta versión mejora
cgi.escape
. También conserva espacios en blanco y nuevas líneas. Devuelve unaunicode
cadena.por ejemplo
fuente
No es la forma más fácil, pero sigue siendo sencilla. La principal diferencia con el módulo cgi.escape : seguirá funcionando correctamente si ya lo tiene
&
en su texto. Como ves en los comentarios:cgi.escape version
versión regex
fuente
Para el código heredado en Python 2.7, puede hacerlo a través de BeautifulSoup4 :
fuente