strike - Sanitizar la entrada del usuario usando Python
xss strike (7)
Aquí hay un fragmento que eliminará todas las etiquetas que no estén en la lista blanca, y todos los atributos de etiqueta que no estén en la lista blanca attribues (por lo que no puede usar onclick
).
Es una versión modificada de http://www.djangosnippets.org/snippets/205/ , con la expresión regular de los valores de los atributos para evitar que las personas utilicen href="javascript:..."
, y otros casos descritos en http: //ha.ckers.org/xss.html .
(por ejemplo, <a href="ja	vascript:alert(''hi'')">
o <a href="ja vascript:alert(''hi'')">
, etc.)
Como puede ver, usa la (impresionante) biblioteca BeautifulSoup .
import re
from urlparse import urljoin
from BeautifulSoup import BeautifulSoup, Comment
def sanitizeHtml(value, base_url=None):
rjs = r''[/s]*(&#x.{1,7})?''.join(list(''javascript:''))
rvb = r''[/s]*(&#x.{1,7})?''.join(list(''vbscript:''))
re_scripts = re.compile(''(%s)|(%s)'' % (rjs, rvb), re.IGNORECASE)
validTags = ''p i strong b u a h1 h2 h3 pre br img''.split()
validAttrs = ''href src width height''.split()
urlAttrs = ''href src''.split() # Attributes which should have a URL
soup = BeautifulSoup(value)
for comment in soup.findAll(text=lambda text: isinstance(text, Comment)):
# Get rid of comments
comment.extract()
for tag in soup.findAll(True):
if tag.name not in validTags:
tag.hidden = True
attrs = tag.attrs
tag.attrs = []
for attr, val in attrs:
if attr in validAttrs:
val = re_scripts.sub('''', val) # Remove scripts (vbs & js)
if attr in urlAttrs:
val = urljoin(base_url, val) # Calculate the absolute url
tag.attrs.append((attr, val))
return soup.renderContents().decode(''utf8'')
Como han dicho los otros carteles, prácticamente todas las bibliotecas db de Python se encargan de la inyección de SQL, por lo que esto debería prácticamente cubrirlo.
¿Cuál es la mejor manera de desinfectar la entrada del usuario para una aplicación web basada en Python? ¿Existe una función única para eliminar los caracteres HTML y otras combinaciones de caracteres necesarios para evitar un ataque de inyección XSS o SQL?
El mismo Jeff Atwood describió cómo .com desinfecta la entrada del usuario (en términos no específicos del idioma) en el blog : http://blog..com/2008/06/safe-html-and-xss/
Sin embargo, como señala Justin, si usas plantillas de Django o algo similar, entonces probablemente desinfectarán tu salida HTML de todos modos.
La inyección SQL tampoco debería ser una preocupación. Todas las bibliotecas de base de datos de Python (MySQLdb, cx_Oracle, etc.) siempre desinfectan los parámetros que pasa. Estas bibliotecas son utilizadas por todos los mapeadores relacionales de objetos de Python (como los modelos de Django), por lo que no tiene que preocuparse por el saneamiento allí tampoco.
La mejor manera de evitar XSS no es intentar filtrar todo, sino simplemente codificar la entidad HTML. Por ejemplo, gire automáticamente <into & lt ;. Esta es la solución ideal, suponiendo que no necesita aceptar ninguna entrada html (fuera de las áreas de foros / comentarios donde se utiliza como marcado, debería ser bastante raro tener que aceptar HTML); hay tantas permutaciones a través de codificaciones alternativas que cualquier cosa menos una lista blanca ultra restrictiva (az, AZ, 0-9, por ejemplo) va a dejar pasar algo.
La inyección SQL, a diferencia de otras opiniones, aún es posible si solo está creando una cadena de consulta. Por ejemplo, si está concatenando un parámetro entrante en una cadena de consulta, tendrá inyección de SQL. La mejor forma de protegerse contra esto tampoco es filtrar, sino usar religiosamente consultas parametrizadas y NUNCA concatenar la entrada del usuario.
Esto no quiere decir que el filtrado todavía no sea una buena práctica, pero en términos de inyección SQL y XSS, estará mucho más protegido si usa Religiosamente Parameterize Queries y HTML Entity Encoding.
Para desinfectar una entrada de cadena que desea almacenar en la base de datos (por ejemplo, un nombre de cliente), necesita escapar de ella o simplemente eliminar cualquier comilla ('', "). Esto previene eficazmente la inyección clásica de SQL que puede ocurrir si están ensamblando una consulta SQL a partir de cadenas pasadas por el usuario.
Por ejemplo (si es aceptable eliminar presupuestos por completo):
datasetName = datasetName.replace("''","").replace(''"'',"")
Si está utilizando un marco como django , el marco puede hacer esto por usted utilizando filtros estándar. De hecho, estoy bastante seguro de que django lo hace automáticamente a menos que le digas que no lo haga.
De lo contrario, recomendaría usar algún tipo de validación de expresiones regulares antes de aceptar entradas de formularios. No creo que haya una solución mágica para su problema, pero al usar el módulo re, debería poder construir lo que necesita.
Ya no desarrollo mucho más la web, pero cuando lo hice, hice algo así:
Cuando no se supone que se debe realizar un análisis sintáctico, por lo general, escapo de los datos para no interferir con la base de datos cuando los guardo, y evito todo lo que leo de la base de datos para no interferir con html cuando lo visualizo (cgi.escape () en pitón).
Lo más probable es que, si alguien intente ingresar caracteres html o cosas así, en realidad quisieran que se muestre como texto de todos modos. Si no lo hicieron, bien difícil :)
En resumen, siempre escapa lo que puede afectar el objetivo actual para los datos.
Cuando necesité un análisis sintáctico (marcado o lo que sea) usualmente traté de mantener ese idioma en un conjunto que no se cruza con html para poder guardarlo adecuadamente escapado (después de validar los errores de sintaxis) y analizarlo en html cuando se visualiza sin tener que preocuparse por los datos que el usuario pone allí interfiriendo con su html.
Ver también Escaping HTML
Editar : Bleach es un contenedor alrededor de html5lib que hace que sea aún más fácil de utilizar como desinfectante basado en una lista blanca.
html5lib
viene con un html5lib
HTML basado en una lista blanca: es fácil subclasificarlo para restringir las etiquetas y atributos que los usuarios pueden usar en su sitio, e incluso intenta desinfectar CSS si permite el uso del atributo de style
.
Ahora lo estoy usando en la función de utilidad sanitize_html
mi clon :
http://code.google.com/p/soclone/source/browse/trunk/soclone/utils/html.py
Lancé todos los ataques enumerados en XSS Cheatsheet de ha.ckers.org (que están disponibles en formato XML en el mismo después de realizar la conversión de Markdown a HTML usando python-markdown2 y parece haberse mantenido bien.
Sin embargo, el componente de editor de WMD que utiliza actualmente es un problema: en realidad tuve que deshabilitar JavaScript para probar los ataques de XSS Cheatsheet, ya que pegarlos todos en WMD terminó por darme cuadros de alerta y borrar la página.