¿Cuál es la mejor manera de desinfectar las entradas del usuario para una aplicación web basada en Python? ¿Hay una función única para eliminar los caracteres HTML y otras combinaciones de caracteres necesarios para evitar un ataque de inyección de SQL XSS?Desinfección de entrada de usuario utilizando Python
Respuesta
Si está utilizando un marco como django, el marco puede hacer esto fácilmente con 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.
Jeff Atwood mismo describió cómo StackOverflow.com desinfecta la entrada del usuario (en términos de lenguaje no-específico) en el blog de desbordamiento de pila: http://blog.stackoverflow.com/2008/06/safe-html-and-xss/
Sin embargo, como señala Justin, si utiliza las plantillas de Django o algo similar entonces probablemente desinfectarán tu salida de HTML de todos modos.
La inyección de 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.
Aquí hay un fragmento que eliminará todas las etiquetas que no estén en la lista blanca, y todos los atributos de etiquetas que no estén en la lista blanca attribues (para que no pueda usar onclick
).
que es una versión modificada de http://www.djangosnippets.org/snippets/205/, con la expresión regular en los valores de atributo para evitar que la gente use 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 se puede ver, se utiliza la (impresionante) BeautifulSoup biblioteca.
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 los otros críticos han dicho, casi todas las bibliotecas db Python cuidar de inyección de SQL, por lo que este debe más o menos cubierta ti.
no hago el desarrollo web mucho más tiempo, pero cuando lo hice, hice algo así:
Cuando se supone ningún análisis a suceder, por lo general sólo escapar de los datos para no interferir con la base de datos cuando lo almaceno, y escapo todo lo que leo de la base de datos para no interferir con html cuando lo visualizo (cgi.escape() en python).
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é algún tipo de análisis (marcado o lo que sea), generalmente trataba de mantener ese idioma en un conjunto que no se cruza con html, así podía almacenarlo adecuadamente escapado (después de validar los errores de sintaxis) y analizarlo html cuando se visualiza sin tener que preocuparse por los datos que el usuario pone interfiere con su html.
Ver también Escaping HTML
La mejor manera de prevenir XSS no es tratar de filtrar todo, pero en lugar de simplemente hacer HTML Entidad codificación. Por ejemplo, gire automáticamente < en & lt ;. Esta es la solución ideal, suponiendo que no necesita aceptar ninguna entrada html (fuera de las áreas de foro/comentario donde se usa 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 (a-z, A-Z, 0-9 por ejemplo) va a dejar pasar algo.
Inyección SQL, contrariamente a otra opinión, todavía es posible, si solo está construyendo 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 no sea aún una buena práctica, pero en términos de inyección SQL y XSS, estará mucho más protegido si utiliza religiosamente Parameterize Queries y HTML Entity Encoding.
Esto no es correcto en muchos casos. Consulte las notas de OSWAP sobre "¿Por qué no puedo solo codificar la entidad HTML con datos que no son de confianza?" https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet – Purrell
Editar: bleach es un envoltorio alrededor de html5lib que hace que sea aún más fácil de usar como desinfectante basado en una lista blanca.
html5lib
viene con un desinfectante de HTML basado en la lista blanca - es fácil de subclase para restringir las etiquetas y atributos usuarios están autorizados a utilizar en su sitio, y que incluso los intentos de desinfectar CSS si se va a permitir el uso de la style
atributo.
Aquí está ahora estoy usando la función sanitize_html
utilidad de mi desbordamiento de pila clon:
http://code.google.com/p/soclone/source/browse/trunk/soclone/utils/html.py
he tirado todos los ataques que figuran en ha.ckers.org's XSS Cheatsheet (que son hábilmente available in XML format en ello después de realizar Markdown a Conversión de HTML usando python-markdown2 y parece haberse mantenido bien
El componente del editor de WMD que Stackoverflow usa actualmente es un problema, de hecho, tuve que deshabilitar JavaScript para probar el XS S ataques de Cheatsheet, ya que pegarlos a todos en WMD terminó dándome cuadros de alerta y borrando la página.
Para desinfectar una entrada de cadena que desee almacenar en la base de datos (por ejemplo, un nombre de cliente) necesita escaparse o simplemente eliminar cualquier comilla (', ") de esta. puede suceder si usted está montando una consulta SQL de cadenas pasadas por el usuario
por ejemplo (si es aceptable para eliminar las citas por completo):.
datasetName = datasetName.replace("'","").replace('"',"")
Er ... no ... Todavía no haría esto. Para todo lo que sea un elemento de datos, use consultas parametrizadas. Para las consultas que no son de datos (creadas dinámicamente), realmente debería estar usando una lista blanca. 'pg_catalog.pg_user' no contiene comillas, pero probablemente tampoco lo desee en sus consultas generadas. En su lugar, haga algo como 'datasetName = datasetName if datasetName en DATASETNAME_WHITELIST else sulk()' – SingleNegationElimination
- 1. ¿Es seguro mostrar la entrada del usuario como valores de entrada sin desinfección?
- 2. Desinfección de la entrada del usuario antes de agregarla al DOM en Javascript
- 3. Desinfección PHPSESSID
- 4. Desinfección de los datos del usuario en GET por PHP
- 5. Python: entrada de usuario y argumentos de línea de comando
- 6. Aceptar entrada de usuario
- 7. Limpieza/desinfección de los atributos xpath
- 8. Python WX - Devolver entrada de usuario desde wx Dialog
- 9. filepath autocompletion utilizando la entrada de usuarios
- 10. Entrada de usuario + Ruby + Regex?
- 11. wix obtener usuario de entrada
- 12. JPanel Desinfección y repintado de gráficos?
- 13. Obtener entrada del usuario
- 14. Desinfección formulario de contacto y sin mysql_real_escape_string
- 15. Desinfección de XML incorrecto en Java
- 16. Detectar lenguaje de entrada de cadena/usuario
- 17. Validación de entrada de usuario para JOptionPane.showInputDialog
- 18. Lectura de entrada de usuario sin eco
- 19. C# Entrada de usuario de consola
- 20. C - Lectura de entrada de usuario
- 21. rieles -: se une desinfección/sustitución
- 22. Obtener contraseña de entrada utilizando node.js
- 23. Manejar la entrada de usuario con Raphael
- 24. Entrada de usuario, ¿cómo podemos hacerlo?
- 25. ¿Validar la entrada del usuario?
- 26. Al hacer la desinfección en CakePHP
- 27. Dos valores de una entrada en python?
- 28. Toma de entrada de usuario para crear usuarios en Django
- 29. Creación dinámica de tabla con la entrada de usuario
- 30. Python: generador de clases usando la entrada del usuario como nombres de clase
no se le debe intentar arreglar la inyección de SQL desinfectando ¡Si el API de la base de datos se usa correctamente, no hay posibilidad de inyección SQL. –
'... si se utiliza la API de la base de datos correctamente no hay posibilidad de inyección SQL'. De forma adecuada, ¿te refieres a utilizar consultas parametrizadas? ¿Eso te cubre al 100%? – Medorator
@buffer, sé que su comentario es antiguo, pero si desea que otras personas, además de OP, vean sus comentarios, debe llamarlos con un símbolo \ @. – user1717828