• 主页
  • 系列总集
  • OpenCV
  • CMake
  • iOS
  • Java
  • 前端
所有文章 关于我

  • 主页
  • 系列总集
  • OpenCV
  • CMake
  • iOS
  • Java
  • 前端

关于XSS的一点思考

2016-10-29

XSS的噩梦

在文章WebGoat的XSS我们讲了XSS的基本原理,而最近我有一个关于富文本编辑器的需求,这里是最容易产生XSS的,我用的是summernote编辑器

获取编辑器内容

1
var markupStr = $('#summernote').summernote('code');

其中获得是一系列的HTML文本类似

1
<p>测试</p><p>图片</p><p><br></p>

写入编辑器内容

而写入编辑器内容则是实用的JQuery的append函数,直接把HTML添加到页面上

1
$('#summernote').summernote('code', markupStr);

问题出现

由于富文本编辑器需要直接append一堆HTML的文本,如果在传送markupStr的过程中被人篡改,再次写入的时候必定会引起XSS

问题结论

任何不采用虚拟DOM的方式直接对HTML进行改变的操作,都会引发XSS,如果不对元数据进行审查修改(白名单),任何编码类操作都是无效的

所以富文本编辑器因为其本质,是XSS的重灾区,除了后台白名单,我没有找到一劳永逸的解决方法,与其说富文本编辑器没有一劳永逸,任何XSS都没有一键防护的可能性,只能靠码农堆人力和写代码的时候多留意。

探索思路

由于XSS本身产生的实质就是浏览器边解析变生成,永远无法预测下一个字符的特性决定的,所以想彻底解决XSS可以从如下思路入手

解决的思路

  1. 渲染的时候进行转义,防止有问题的HTML标签产生
  2. 保证本身HTML字符串没问题

渲染时期

渲染时期解决XSS不同的手段都有如下几种,但是都不能用来修改summernote的append输入方式

技术方案 解决办法 不能代替append的原因
JSP c:out标签 fn:escapexml标签进行输出 格式信息会被转义,格式丢失了
JQuery 使用jQuery(html, attributes)创建DOM 需要重写summernote的函数,工作量巨大
React/Riot JSX和Tag构造虚拟DOM 需要再次引入一个新依赖,太复杂不可取

字符串控制

如果不能改变HTML出现在网页上的方式,那么只能从HTML字符串的内容入手了,可以在两个时段来对字符串进行处理

  1. 前端: 使用JS对字符串进行处理
  2. 后台: 在入库之前对逻辑层,对字符串进行处理

而处理对方式也有两种: 转义可疑的字符串 和 设置标签和标签属性的白名单

处理时期 可选择工具
前端输出 jsxss
后台储存 htmlpurifier,Jsoup,Sling

其中

  1. jsxss是一个白名单的JS脚本,很简单,但是每次前端都要执行
  2. htmlpurifier是PHP提供在后台对HTML字符串白名单的工具
  3. Java中这种工具不是太多,Jsoup是用于HTML解析的,并没有针对的白名单功能,而Sling用的人又太少

值得一提的是Sling是OWASP(Open Web Application Security Project)组织为了预防XSS提出的 AntiSamy 计划之一,如果有任何关于XSS防御的需求,可以搜索AntiSamy相关资料。

错误的方法

网上有很多Java开发可以 一键防护XSS的方法 经过测试都是 无效的

在web.xml中配置(无效)

在web.xml中增加配置代码:

1
2
3
4
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>

在包含form的jsp页面中添加(无效)

1
<spring:htmlEscape defaultHtmlEscape="true" />

直接在form中的元素中添加(无效)

1
2
3
<form:input path="someFormField" htmlEscape="true" />
或
<form:form htmlEscape="true">

错误的思路

提到XSS最教科书的解决方法是 转义 储存,但是这个对于富文本编辑器并没有卵用,原因如下

  1. 常规的数据提交中,可以通过后台转义保存(例如Java中的StringEscapeUtil工具)
  2. 然后在前端反转义输出,保证了不会产生XSS

但是但是富文本编辑器的除了数据之外,内容的格式信息都是由HTML标签属性存储的,无法进行反转义(UnEscape)输出 因为反转义后标签就变为数据的文本的一部分了

屠龙宝刀 点击就送 极品装备 一秒刷爆

在查询各种XSS的防御方案中,我见到了一个最简单粗暴而且超级有效的方法。。。但是。。。太粗暴了,不适用于富文本编辑器

如果在前端后台都无法操作,而且急需上线的情况下,防止XSS可以采用在Servlet上加上一个过滤器filter,把字符串中的所有半角标点符号换成全角,既不会影响数据的可读性,又能防止被浏览器解析

想起来这个方法的。。。真tm是个人才。。。。。

赏

请问老板还招人么(/ω\)

支付宝
微信
  • Java
  • Web
  • Security
  • XSS
  • Tips

扫一扫,分享到微信

微信分享二维码
IntelliJ用容器进行热部署HotSwap
JQuery的done/fail/always
© 2021 Alan Li
Hexo Theme Yilia by Litten
  • 所有文章
  • 关于我

tag:

  • iOS
  • Java
  • Collection
  • Python
  • Shell
  • CMake
  • Memory
  • JavaScript
  • Architecture
  • AnchorPoint
  • Android
  • Web
  • Annotation
  • AFNetworking
  • Window
  • ViewController
  • AutoLayout
  • Dozer
  • CoreAnimation
  • Cycle Retain
  • Block
  • UI
  • IDE
  • FrontEnd
  • CSS
  • Category
  • TableViewCell
  • Security
  • Net
  • JSP
  • Spring
  • C
  • MyBatis
  • Date
  • React
  • GCD
  • UITouch
  • Gesture
  • UIControl
  • Git
  • HTML
  • HTTPS
  • HTTP
  • Servlet
  • Server
  • DataBase
  • MySQL
  • Linux
  • Tutorial
  • Ajax
  • Type
  • JQuery
  • JSON
  • Exception
  • Parameter
  • Reflect
  • Thread
  • Sort
  • KVO
  • MKMapKit
  • Overlay
  • Maven
  • Configure
  • Tips
  • Transaction
  • Swift
  • NavigationBar
  • Nginx
  • Runtime
  • OpenCV
  • Property
  • Playground
  • Protocol
  • Redux
  • ScrollView
  • Session
  • Cookie
  • Shiro
  • Error
  • Singleton
  • RegEx
  • StackView
  • StatusBar
  • Base64
  • Socket
  • TCP
  • IP
  • TextField
  • CALayer
  • UILabel
  • View
  • Animation
  • Xcode
  • Hexo
  • Terminal
  • OC
  • Device
  • Log
  • Image
  • JUnit
  • Oval
  • Archive
  • XSS
  • Compiler
  • Aspect
  • Responder
  • Class
  • FireWall
  • RetainCount
  • Const
  • Frame
  • String
  • Symbols
  • Framework
  • CocoaPods
  • Unity
  • Message
  • Button
  • AuthorizationStatus
  • Struct
  • XCTest
  • NSNotification
  • Contact

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

我写的,大概率是错的。。。。。