¿La mejor expresión regular para atrapar el ataque XSS (Cross-site Scripting) (en Java)?

StackOverflow https://stackoverflow.com/questions/24723

  •  09-06-2019
  •  | 
  •  

Pregunta

Jeff realmente publicó sobre esto en Sanitize HTML . Pero su ejemplo está en C # y en realidad estoy más interesado en una versión de Java. ¿Alguien tiene una mejor versión para Java? ¿Es su ejemplo lo suficientemente bueno como para convertir directamente de C # a Java?

[Actualización] He puesto una recompensa por esta pregunta porque SO no era tan popular cuando hice la pregunta como lo es hoy (*). En cuanto a cualquier cosa relacionada con la seguridad, ¡cuanta más gente lo vea, mejor será!

(*) De hecho, creo que todavía estaba en beta cerrada

¿Fue útil?

Solución

No hagas esto con expresiones regulares. Recuerde, no está protegiendo solo contra HTML válido; estás protegiendo contra el DOM que crean los navegadores web. Se puede engañar a los navegadores para que produzcan DOM válidos a partir de HTML no válido con bastante facilidad.

Por ejemplo, vea esta lista de ataques XSS ofuscados . ¿Estás preparado para adaptar una expresión regular para evitar este ataque del mundo real en Yahoo y Hotmail en IE6 / 7/8?

<HTML><BODY>
<?xml:namespace prefix="t" ns="urn:schemas-microsoft-com:time">
<?import namespace="t" implementation="#default#time2">
<t:set attributeName="innerHTML" to="XSS&lt;SCRIPT DEFER&gt;alert(&quot;XSS&quot;)&lt;/SCRIPT&gt;">
</BODY></HTML>

¿Qué tal este ataque que funciona en IE6?

<TABLE BACKGROUND="javascript:alert('XSS')">

¿Qué hay de los ataques que no figuran en este sitio? El problema con el enfoque de Jeff es que no es una lista blanca, como se afirma. Como alguien en esa página señala con destreza:

  

El problema con esto es que el html   debe estar limpio Hay casos donde   puede pasar html pirateado, y   no coincidirá, en cuyo caso   devolver la cadena html pirateada ya que   no coincidirá con nada para reemplazar. Esta   no es estrictamente la lista blanca.

Sugeriría una herramienta especialmente diseñada como AntiSamy . Funciona analizando realmente el HTML y luego atravesando el DOM y eliminando todo lo que no está en la lista blanca configurable . La principal diferencia es la capacidad de manejar con gracia HTML con formato incorrecto.

La mejor parte es que en realidad realiza pruebas unitarias para todos los ataques XSS en el sitio anterior. Además, qué podría ser más fácil que esta llamada API:

public String toSafeHtml(String html) throws ScanException, PolicyException {

    Policy policy = Policy.getInstance(POLICY_FILE);
    AntiSamy antiSamy = new AntiSamy();
    CleanResults cleanResults = antiSamy.scan(html, policy);
    return cleanResults.getCleanHTML().trim();
}

Otros consejos

No estoy convencido de que usar una expresión regular es la mejor manera de encontrar todo el código sospechoso. Las expresiones regulares son bastante fáciles de engañar, especialmente cuando se trata de HTML roto. Por ejemplo, la expresión regular que figura en el enlace HTML de Sanitize no eliminará todos los elementos 'a' que tengan un atributo entre el nombre del elemento y el atributo 'href':

< a alt = " inyección xss " href = " http: //www.malicous.com/bad.php " >

Una forma más sólida de eliminar el código malicioso es confiar en un analizador XML que pueda manejar todo tipo de documentos HTML (Tidy, TagSoup, etc.) y seleccionar los elementos que se eliminarán con una expresión XPath. Una vez que el documento HTML se analiza en un documento DOM, los elementos para revome pueden encontrarse de manera fácil y segura. Esto es incluso fácil de hacer con XSLT.

Extraje de NoScript el mejor complemento Anti-XSS, aquí está su Regex: Trabajo perfecto:

<[^\w<>]*(?:[^<>"'\s]*:)?[^\w<>]*(?:\W*s\W*c\W*r\W*i\W*p\W*t|\W*f\W*o\W*r\W*m|\W*s\W*t\W*y\W*l\W*e|\W*s\W*v\W*g|\W*m\W*a\W*r\W*q\W*u\W*e\W*e|(?:\W*l\W*i\W*n\W*k|\W*o\W*b\W*j\W*e\W*c\W*t|\W*e\W*m\W*b\W*e\W*d|\W*a\W*p\W*p\W*l\W*e\W*t|\W*p\W*a\W*r\W*a\W*m|\W*i?\W*f\W*r\W*a\W*m\W*e|\W*b\W*a\W*s\W*e|\W*b\W*o\W*d\W*y|\W*m\W*e\W*t\W*a|\W*i\W*m\W*a?\W*g\W*e?|\W*v\W*i\W*d\W*e\W*o|\W*a\W*u\W*d\W*i\W*o|\W*b\W*i\W*n\W*d\W*i\W*n\W*g\W*s|\W*s\W*e\W*t|\W*i\W*s\W*i\W*n\W*d\W*e\W*x|\W*a\W*n\W*i\W*m\W*a\W*t\W*e)[^>\w])|(?:<\w[\s\S]*[\s\0\/]|['"])(?:formaction|style|background|src|lowsrc|ping|on(?:d(?:e(?:vice(?:(?:orienta|mo)tion|proximity|found|light)|livery(?:success|error)|activate)|r(?:ag(?:e(?:n(?:ter|d)|xit)|(?:gestur|leav)e|start|drop|over)?|op)|i(?:s(?:c(?:hargingtimechange|onnect(?:ing|ed))|abled)|aling)|ata(?:setc(?:omplete|hanged)|(?:availabl|chang)e|error)|urationchange|ownloading|blclick)|Moz(?:M(?:agnifyGesture(?:Update|Start)?|ouse(?:PixelScroll|Hittest))|S(?:wipeGesture(?:Update|Start|End)?|crolledAreaChanged)|(?:(?:Press)?TapGestur|BeforeResiz)e|EdgeUI(?:C(?:omplet|ancel)|Start)ed|RotateGesture(?:Update|Start)?|A(?:udioAvailable|fterPaint))|c(?:o(?:m(?:p(?:osition(?:update|start|end)|lete)|mand(?:update)?)|n(?:t(?:rolselect|extmenu)|nect(?:ing|ed))|py)|a(?:(?:llschang|ch)ed|nplay(?:through)?|rdstatechange)|h(?:(?:arging(?:time)?ch)?ange|ecking)|(?:fstate|ell)change|u(?:echange|t)|l(?:ick|ose))|m(?:o(?:z(?:pointerlock(?:change|error)|(?:orientation|time)change|fullscreen(?:change|error)|network(?:down|up)load)|use(?:(?:lea|mo)ve|o(?:ver|ut)|enter|wheel|down|up)|ve(?:start|end)?)|essage|ark)|s(?:t(?:a(?:t(?:uschanged|echange)|lled|rt)|k(?:sessione|comma)nd|op)|e(?:ek(?:complete|ing|ed)|(?:lec(?:tstar)?)?t|n(?:ding|t))|u(?:ccess|spend|bmit)|peech(?:start|end)|ound(?:start|end)|croll|how)|b(?:e(?:for(?:e(?:(?:scriptexecu|activa)te|u(?:nload|pdate)|p(?:aste|rint)|c(?:opy|ut)|editfocus)|deactivate)|gin(?:Event)?)|oun(?:dary|ce)|l(?:ocked|ur)|roadcast|usy)|a(?:n(?:imation(?:iteration|start|end)|tennastatechange)|fter(?:(?:scriptexecu|upda)te|print)|udio(?:process|start|end)|d(?:apteradded|dtrack)|ctivate|lerting|bort)|DOM(?:Node(?:Inserted(?:IntoDocument)?|Removed(?:FromDocument)?)|(?:CharacterData|Subtree)Modified|A(?:ttrModified|ctivate)|Focus(?:Out|In)|MouseScroll)|r(?:e(?:s(?:u(?:m(?:ing|e)|lt)|ize|et)|adystatechange|pea(?:tEven)?t|movetrack|trieving|ceived)|ow(?:s(?:inserted|delete)|e(?:nter|xit))|atechange)|p(?:op(?:up(?:hid(?:den|ing)|show(?:ing|n))|state)|a(?:ge(?:hide|show)|(?:st|us)e|int)|ro(?:pertychange|gress)|lay(?:ing)?)|t(?:ouch(?:(?:lea|mo)ve|en(?:ter|d)|cancel|start)|ime(?:update|out)|ransitionend|ext)|u(?:s(?:erproximity|sdreceived)|p(?:gradeneeded|dateready)|n(?:derflow|load))|f(?:o(?:rm(?:change|input)|cus(?:out|in)?)|i(?:lterchange|nish)|ailed)|l(?:o(?:ad(?:e(?:d(?:meta)?data|nd)|start)?|secapture)|evelchange|y)|g(?:amepad(?:(?:dis)?connected|button(?:down|up)|axismove)|et)|e(?:n(?:d(?:Event|ed)?|abled|ter)|rror(?:update)?|mptied|xit)|i(?:cc(?:cardlockerror|infochange)|n(?:coming|valid|put))|o(?:(?:(?:ff|n)lin|bsolet)e|verflow(?:changed)?|pen)|SVG(?:(?:Unl|L)oad|Resize|Scroll|Abort|Error|Zoom)|h(?:e(?:adphoneschange|l[dp])|ashchange|olding)|v(?:o(?:lum|ic)e|ersion)change|w(?:a(?:it|rn)ing|heel)|key(?:press|down|up)|(?:AppComman|Loa)d|no(?:update|match)|Request|zoom))[\s\0]*=

Prueba: http://regex101.com/r/rV7zK8

Creo que bloquea 99% XSS porque es parte de NoScript, un complemento que se actualiza regularmente

^(\s|\w|\d|<br>)*?$ 

Esto validará caracteres, dígitos, espacios en blanco y también la etiqueta <br>. Si desea más riesgo, puede agregar más etiquetas como

^(\s|\w|\d|<br>|<ul>|<\ul>)*?$

El mayor problema al usar el código jeffs es el @ que actualmente no está disponible.

Probablemente solo tomaría el " raw " regexp del código jeffs si lo necesitaba y pegarlo en

http: //www.cis.upenn. edu / ~ matuszek / General / RegexTester / regex-tester.html

y vea cómo escapan las cosas que necesitan escapar y luego úselas.


Teniendo en cuenta el uso de esta expresión regular, personalmente me aseguraría de comprender exactamente lo que estaba haciendo, por qué y qué consecuencias tendría si no tuviera éxito, antes de copiar / pegar nada, como las otras respuestas intentan ayudarlo con .

(Eso es probablemente un buen consejo para copiar / pegar)

[\s\w\.]*. Si no coincide, tienes XSS. Tal vez. Tenga en cuenta que esta expresión solo permite letras, números y puntos. Evita todos los símbolos, incluso los útiles, por miedo a XSS. Una vez que permite & Amp ;, tiene preocupaciones. Y simplemente reemplazando todas las instancias de & Amp; con &amp; no es suficiente. Demasiado complicado para confiar: P. Obviamente, esto no permitirá una gran cantidad de texto legítimo (puede reemplazar todos los caracteres que no coinciden con un! O algo así), pero creo que matará a XSS.

La idea de analizarlo como html y generar un nuevo html probablemente sea mejor.

Un hilo antiguo pero tal vez esto sea útil para otros usuarios. Existe una herramienta de capa de seguridad mantenida para php: https://github.com/PHPIDS/ Se basa en un conjunto de expresiones regulares que puedes encontrar aquí:

https://github.com/PHPIDS/PHPIDS/ blob / master / lib / IDS / default_filter.xml

Esta pregunta ilustra perfectamente una gran aplicación del estudio de la teoría de la computación. La teoría de la computación es un campo que se enfoca en producir representaciones matemáticas de computadoras.

Algunas de las investigaciones más profundas en la teoría de la computación son las pruebas que ilustran las relaciones de varios idiomas.

Algunas de las relaciones lingüísticas que los teóricos de la computación han demostrado incluyen:

 ingrese la descripción de la imagen aquí

Esto muestra que los lenguajes libres de contexto son más poderosos que los lenguajes normales. Por lo tanto, si un lenguaje está explícitamente libre de contexto (libre de contexto y no es regular), entonces es imposible que cualquier expresión regular lo reconozca.

JavaScript es, como mínimo, libre de contexto, por lo que sabemos con un cien por ciento de certeza que diseñar una expresión regular (regex) capaz de atrapar todo XSS es una tarea imposible.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top