代码之家  ›  专栏  ›  技术社区  ›  Thierry Roy

捕获XSS(跨站点脚本)攻击的最佳正则表达式(Java)?

  •  21
  • Thierry Roy  · 技术社区  · 18 年前

    杰夫实际上在网上发布了这个消息 Sanitize HTML . 但他的例子是C语言,我实际上对Java版本更感兴趣。有人有更好的Java版本吗?他的例子是否足够好,可以直接从C#转换为Java?

    [更新]我对这个问题给予了奖励,因为当我问这个问题时,它不像今天那么受欢迎(*)。至于任何与安全有关的事情,人们调查得越多越好!

    (*)事实上,我认为它仍处于封闭测试阶段

    9 回复  |  直到 6 年前
        1
  •  77
  •   Chase Seibert    17 年前

    不要对正则表达式执行此操作。记住,你不仅仅是在保护有效的HTML;您正在针对web浏览器创建的DOM进行保护。浏览器可以很容易地从无效的HTML生成有效的DOM。

    例如,请参见以下列表: obfuscated XSS attacks . 您准备好定制一个正则表达式来防止对 Yahoo and Hotmail 在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>
    

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

    本网站未列出的攻击如何?杰夫的方法的问题在于,它并不像所宣称的那样是一个白名单。作为某人 that page 巧妙地指出:

    您可以传入被黑客攻击的html,并且 不匹配,在这种情况下 返回被黑客攻击的html字符串

    我建议使用专门构建的工具,如 AntiSamy 可配置 白名单。主要区别在于能够优雅地处理格式错误的HTML。

    最好的部分是,它实际上对上述站点上的所有XSS攻击进行了单元测试。此外,还有什么比这个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();
    }
    
        2
  •  7
  •   user3709489    12 年前

    我从NoScript最佳反XSS插件中提取,下面是它的正则表达式: 完美工作:

    <[^\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]*=
    

    测试: http://regex101.com/r/rV7zK8

    我认为它阻止了99%的XSS,因为它是NoScript的一部分,NoScript是一个定期更新的插件

        3
  •  4
  •   Emmanuel Rodriguez    17 年前

    我不相信使用正则表达式是查找所有可疑代码的最佳方法。正则表达式非常容易欺骗,特别是在处理损坏的HTML时。例如,Sanitize HTML链接中列出的正则表达式将无法删除在元素名称和属性“href”之间具有属性的所有“a”元素:

    <a alt=“xss注入”href=”http://www.malicous.com/bad.php“>

    删除恶意代码的一种更为健壮的方法是依靠能够处理各种HTML文档(Tidy、TagSoup等)的XML解析器,并使用XPath表达式选择要删除的元素。一旦HTML文档被解析为DOM文档,就可以轻松安全地找到要revome的元素。使用XSLT甚至很容易做到这一点。

        4
  •  3
  •   atoms atoms    17 年前
    ^(\s|\w|\d|<br>)*?$ 
    

    这将验证字符、数字、空格以及 <br> 如果你想要更多的风险,你可以添加更多的标签,比如

    ^(\s|\w|\d|<br>|<ul>|<\ul>)*?$
    
        5
  •  2
  •   Philip DiSarro    6 年前

    这个问题完美地说明了计算理论研究的重大应用。计算理论是一个专注于产生和研究用于计算的数学表示的领域。

    计算理论中一些最深刻的研究包括说明各种语言之间关系的证明。

    计算理论家已经证明的一些语言关系包括:

    enter image description here

    这表明上下文无关语言严格来说比常规语言更强大。因此,如果一种语言是显式上下文无关的(上下文无关且不规则),那么它就不可能 任何 正则表达式来识别它。

    JavaScript至少是上下文无关的,因此我们百分之百确定地知道,设计一个能够捕获所有XS的正则表达式(regex)在数学上是不可能的任务。

        6
  •  0
  •   svrist    18 年前

    使用jeffs代码的最大问题是@,它目前不可用。

    如果需要,我可能会从jeffs代码中获取“raw”regexp并将其粘贴到

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

    看到需要逃跑的东西就逃跑,然后使用它。


    考虑到这个正则表达式的使用,我个人会确保在复制/粘贴任何东西之前,我完全理解我在做什么,为什么以及如果我没有成功会有什么后果,就像其他答案一样,我会尝试帮助你。

    (对于任何复制/粘贴,这都是非常合理的建议)

        7
  •  0
  •   Brian    17 年前

    [\s\w\.]* . 如果不匹配,则表示您有XSS。大概请注意,此表达式仅允许字母、数字和句点。出于对XSS的恐惧,它避免了所有符号,甚至是有用的符号。一旦你允许&,你有烦恼。而仅仅是替换&具有 &amp; 这是不够的。太复杂了,不能信任:P。显然,这将禁止大量合法文本(您可以用!或其他东西替换所有不匹配的字符),但我认为这将杀死XSS。

    将其解析为html并生成新的html可能更好。

        8
  •  0
  •   KIC    12 年前

    一个旧的线程,但这可能对其他用户有用。php有一个维护的安全层工具: https://github.com/PHPIDS/ 它基于一组正则表达式,您可以在此处找到:

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

        9
  •  0
  •   NoNaMe    6 年前

    value.replaceAll("(?i)(\\b)(on\\S+)(\\s*)=|javascript:|(<\\s*)(\\/*)script|style(\\s*)=|(<\\s*)meta", "");
    

    添加(?i)以忽略字母表的大小写。