XSS漏洞
漏洞案例
漏洞描述
安全编码
XSS(Cross Site Scripting) 跨站脚本攻击,攻击者插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
【必须】外部输入拼接到response页面前进行编码处理 当响应“content-type”为“html”类型时,外部输入拼接到响应包中,需根据输出位置进行编码处理,需要对以下6个特殊字符进行HTML实体编码(&, <, >, ", ',/),也可参考或直接使用业界已有成熟第三方库如ESAPI。 【必须】设置正确的HTTP响应包类型 响应包的HTTP头“Content-Type”必须正确配置响应包的类型,禁止非HTML类型的响应包设置为“text/html”。此举会使浏览器在直接访问链接时,将非HTML格式的返回报文当做HTML解析,增加反射型XSS的触发几率。 【建议】设置安全的HTTP响应头 控制用户登录鉴权的Cookie字段 应当设置HttpOnly属性以防止被XSS漏洞/JavaScript操纵泄漏。
运行
漏洞代码
// 简单的反射型XSS,没对输出做处理。当攻击者输入恶意js语句时可触发 @GetMapping("/reflect") public static String input(String content) { return content; }
运行
安全代码 - htmlEscape方法
// 采用Spring自带的方法会对特殊字符全转义 import org.springframework.web.util.HtmlUtils; @GetMapping("/safe1") public static String safe1(String content) { return HtmlUtils.htmlEscape(content); }
运行
安全代码 - 自定义过滤
// 将特殊字符做转义,(bug:这里被转义了) private static String XssFilter(String content) { content = StringUtils.replace(content, "&", "&"); content = StringUtils.replace(content, "<", "<"); content = StringUtils.replace(content, ">", ">"); content = StringUtils.replace(content, "\"", """); content = StringUtils.replace(content, "'", "'"); content = StringUtils.replace(content, "/", "/"); return content; }
运行
安全代码 - 黑白名单
// 场景:针对富文本的处理方式,需保留部分标签 import org.jsoup.Jsoup; import org.jsoup.safety.Whitelist; public static String safe3(String content) { Whitelist whitelist = (new Whitelist()) .addTags("p", "hr", "div", "img", "span", "textarea") // 设置允许的标签 .addAttributes("a", "href", "title") // 设置标签允许的属性, 避免如nmouseover属性 .addProtocols("img", "src", "http", "https") // img的src属性只允许http和https开头 .addProtocols("a", "href", "http", "https"); return Jsoup.clean(content, whitelist); }
运行
安全代码 - ESAPI
public static String safe4(String content){ return ESAPI.encoder().encodeForHTML(content); }