2008-08-24 13 views
20

Jeff realmente publicó sobre esto en Sanitize HTML. Pero su ejemplo está en C# y estoy realmente más interesado en una versión de Java. ¿Alguien tiene una mejor versión para Java? ¿Su ejemplo es lo suficientemente bueno como para convertir directamente de C# a Java?¿Mejor expresión regular para detectar ataques XSS (Cross-site Scripting) (en Java)?

[Actualización] he puesto una recompensa sobre esta cuestión debido a que no era tan popular cuando hice la pregunta como lo es hoy (*). En cuanto a todo lo relacionado con la seguridad, mientras más personas lo analicen, ¡mejor será!

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

+0

¿Qué más se puede pedir? Las respuestas se ven bien para mí. –

Respuesta

60

No haga esto con expresiones regulares. Recuerde, no está protegiendo solo contra HTML válido; está protegiendo contra el DOM que crean los navegadores web. Los navegadores pueden ser engañados para producir DOM válido a partir de HTML no válido con bastante facilidad.

Por ejemplo, consulte esta lista de obfuscated XSS attacks. ¿Estás preparado para adaptar una expresión regular para evitar este ataque real en el Yahoo and 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 se enumeran en este sitio? El problema con el enfoque de Jeff es que no es una lista blanca, como se dijo. Como alguien con habilidad en that page señala:

El problema con él, es que el html debe estar limpia. Hay casos en que puede pasar en html pirateado, y no coincidirá, en cuyo caso devolverá la cadena html pirateada ya que no coincidirá con nada que reemplazar. Este no está estrictamente incluido en la lista blanca.

Sugeriría una herramienta especialmente diseñada como AntiSamy. Funciona analizando realmente el HTML, y luego recorriendo 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 mal formado.

La mejor parte es que en realidad las pruebas unitarias de todos los ataques XSS en el sitio anterior. Además, ¿qué podría ser más fácil que esto llamada a la 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(); 
} 
+0

¡AntiSamy se ve genial! Además, usar diferentes políticas es una buena idea, ya que mantiene las reglas de limpieza fuera del código, lo que facilita su mantenimiento. Este es claramente un enfoque muy agradable. Prestigio. – potyl

+1

+1. No puede procesar HTML de manera confiable utilizando expresiones regulares. Analizarlo en un DOM fácilmente filtrable, y luego utilizar una serialización conocida, es de lejos el enfoque más sensato. – bobince

+0

Me gusta mucho esta respuesta, ya que no responde directamente la pregunta, ¡sino que resuelve el problema! –

4

la expresión regular se muestra en el ejemplo, debería funcionar sin importar el idioma.

lo tanto, es la expresión regular que desea, o el código java para poner esta lógica en torno a la expresión regular?

0

El mayor problema mediante el uso de código de Jeffs es el @ que en la actualidad tampoco está disponible.

probablemente me acaba de tomar la expresión regular "en bruto" de código Jeffs si lo necesitaba y lo pega en

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

y ver las cosas que necesitan escapar obtener escapó y luego usarlo.


Tomando el uso de esta expresión regular en mente yo personalmente asegurarse de que yo entendía exactamente lo que estaba haciendo, por qué y qué consecuencias sería si yo no tenga éxito, antes de copiar/pegar nada, al igual que las otras respuestas tratan para ayudarte con.

(Eso es bastante consejos propbably sonido para cualquier copiar/pegar)

4

no estoy convencido de que al 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 enumerada en el enlace Desinfectar HTML 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 robusta de eliminar código malicioso es confiar en un analizador XML que pueda manejar todo tipo de documentos HTML (Tidy, TagSoup, etc.) y para seleccionar los elementos para eliminar con una expresión XPath. Una vez que el documento HTML se analiza en un documento DOM, los elementos para revome se pueden encontrar de manera fácil y segura. Esto es incluso fácil de hacer con XSLT.

+0

+1, consulte mi respuesta para una API de Java del mundo real que hace exactamente eso –

0

[\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 &, tiene preocupaciones. Y simplemente reemplazar todas las instancias de & con &amp; no es suficiente. Demasiado complicado para confiar: P. Obviamente, esto no permitirá una gran cantidad de texto legítimo (simplemente puede reemplazar todos los caracteres no coincidentes con un! O algo así), pero creo que matará a XSS.

La idea de simplemente analizarlo como html y generar html nuevo es probablemente mejor.

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

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

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

extraje de NoScript mejor complemento Anti-XSS, aquí es su expresión regular: impecable trabajo:

<[^\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 una parte de NoScript, un complemento que se actualiza regularmente

+0

no compila en java: Causado por: java.util.regex.PatternSyntaxException: secuencia de escape octal ilegal cerca del índice 525 – KIC

+1

Probé un bit extremadamente simple de XSS en esa cadena de prueba regex101 y lo rompí en mi primer intento. No muy perfecto. Todo lo que hice fue agregar un enlace con un 'javascript:' href. –

Cuestiones relacionadas