Jsoup代码解读之六-防御XSS攻击
Jsoup代码解读之八-防御XSS攻击
防御XSS攻击的一般原理
cleaner是Jsoup的重要功能之一,我们常用它来进行富文本输入中的XSS防御。
我们知道,XSS攻击的一般方式是,通过在页面输入中嵌入一段恶意脚本,对输出时的DOM结构进行修改,从而达到执行这段脚本的目的。对于纯文本输入,过滤/转义HTML特殊字符<
,>
,"
,'
是行之有效的办法,但是如果本身用户输入的就是一段HTML文本(例如博客文章),这种方式就不太有效了。这个时候,就是Jsoup大显身手的时候了。
在前面,我们已经知道了,Jsoup里怎么将HTML变成一棵DOM树,怎么对DOM树进行遍历,怎么对DOM文档进行输出,那么其实cleaner的实现方式,也能猜出大概了。使用Jsoup进行XSS防御,大致分为三个步骤:
将HTML解析为DOM树
这一步可以过滤掉一些企图搞破坏的非闭合标签、非正常语法等。例如一些输入,会尝试用
</textarea>
闭合当前Tag,然后写入攻击脚本。而根据前面对Jsoup的parser的分析,这种时候,这些非闭合标签会被当做错误并丢弃。过滤高风险标签/属性/属性值
高风险标签是指
<script>
以及类似标签,对属性/属性值进行过滤是因为某些属性值里也可以写入javascript脚本,例如onclick='alert("xss!")'
。重新将DOM树输出为HTML文本
DOM树的输出,在前面(Jsoup代码解读之三)已经提到过了。
Cleaner与Whitelist
对于上述的两个步骤,1、3都已经分别在parser和输出中完成,现在只剩下步骤 2:过滤高风险标签等。
Jsoup给出的答案是白名单。下面是Whitelist
的部分代码。
public class Whitelist {
private Set<TagName> tagNames; // tags allowed, lower case. e.g. [p, br, span]
private Map<TagName, Set<AttributeKey>> attributes; // tag -> attribute[]. allowed attributes [href] for a tag.
private Map<TagName, Map<AttributeKey, AttributeValue>> enforcedAttributes; // always set these attribute values
private Map<TagName, Map<AttributeKey, Set<Protocol>>> protocols; // allowed URL protocols for attributes
private boolean preserveRelativeLinks; // option to preserve relative links
}
这里定义了标签名/属性名/属性值的白名单。
而Cleaner
是过滤的执行者。不出所料,Cleaner内部定义了CleaningVisitor
来进行标签的过滤。CleaningVisitor的过滤过程并不改变原始DOM树的值,而是将符合条件的属性,加入到Element destination
里去。
private final class CleaningVisitor implements NodeVisitor {
private int numDiscarded = 0;
private final Element root;
private Element destination; // current element to append nodes to
private CleaningVisitor(Element root, Element destination) {
this.root = root;
this.destination = destination;
}
public void head(Node source, int depth) {
if (source instanceof Element) {
Element sourceEl = (Element) source;
if (whitelist.isSafeTag(sourceEl.tagName())) { // safe, clone and copy safe attrs
ElementMeta meta = createSafeElement(sourceEl);
Element destChild = meta.el;
destination.appendChild(destChild);
numDiscarded += meta.numAttribsDiscarded;
destination = destChild;
} else if (source != root) { // not a safe tag, so don't add. don't count root against discarded.
numDiscarded++;
}
} else if (source instanceof TextNode) {
TextNode sourceText = (TextNode) source;
TextNode destText = new TextNode(sourceText.getWholeText(), source.baseUri());
destination.appendChild(destText);
} else { // else, we don't care about comments, xml proc instructions, etc
numDiscarded++;
}
}
public void tail(Node source, int depth) {
if (source instanceof Element && whitelist.isSafeTag(source.nodeName())) {
destination = destination.parent(); // would have descended, so pop destination stack
}
}
}
结束语
至此,Jsoup的全部模块都已经写完了。Jsoup源码并不多,只有14000多行,但是实现非常精巧,在读代码的过程中,除了相关知识,还验证几个很重要的思想:
最好的代码抽象,是对现实概念的映射。
这句话在看《代码大全》的时候印象很深刻。在Jsoup里,只要有相关知识,每个类的作用都能第一时间明白其作用。
不要过度抽象
在Jsoup里,只用到了两个接口,一个是
NodeVisitor
,一个是Connection
,其他都是用抽象类或者直接用实现类代替。记得有次面试的时候被问到我们开发中每逢一个功能,都要先定义一个接口的做法是否必要?现在的答案是没有必要,过度的抽象反而会降低代码质量。另外,Jsoup的代码内聚性都很高,每个类的功能基本都定义在类的内部,这是一个典型的充血模型。同时有大量的facade使用,而避免了Factory、Configure等类的出现,个人感觉这点是非常好的。
Jsoup代码解读之六-防御XSS攻击的更多相关文章
- 防御XSS攻击的七条原则
本文将会着重介绍防御XSS攻击的一些原则,需要读者对于XSS有所了解,至少知道XSS漏洞的基本原理,如果您对此不是特别清楚,请参考这两篇文章:<Stored and Reflected XSS ...
- 拦截过滤防御XSS攻击 -- Struts2.3 以及 2.5 的解决方式
使用Struts2框架开发的后台在防御XSS攻击的时候很多方式都不能用,因为Struts2对请求进行的二次封装有区别.以下针对Struts2的XSS攻击进行拦截过滤防御解决: Struts2.3 本方 ...
- 认识与防御XSS攻击
什么是xss攻击? XSS,即(Cross Site Scripting)中文名称为“跨站脚本攻击”.XSS的重点不在于跨站攻击而在于脚本攻击.攻击者可以利用 web应用的漏洞或缺陷之处,向页面注入恶 ...
- WEB安全 - 认识与防御XSS攻击
目录 什么是xss攻击? XSS的危害 XSS攻击分类 xss攻击示例 反射型攻击 - 前端URL参数解析 反射型攻击 - 后端URL参数解析 注入型攻击 - 留言评论 如何规避xss攻击? 总结 什 ...
- Asp.net防御XSS攻击组件库
一.AntiXss 翻看mvc4高级编程,偶看到作者强烈推荐使用AntiXss防御XSS攻击,收集资料看下. 目前类库已融入到.netframework中,类库主页不再更新. 使用方法:使用Nuget ...
- Jsoup代码解读之五-实现一个CSS Selector
Jsoup代码解读之七-实现一个CSS Selector 当当当!终于来到了Jsoup的特色:CSS Selector部分.selector也是我写的爬虫框架webmagic开发的一个重点.附上一张s ...
- Jsoup代码解读之四-parser
Jsoup代码解读之四-parser 作为Java世界最好的HTML 解析库,Jsoup的parser实现非常具有代表性.这部分也是Jsoup最复杂的部分,需要一些数据结构.状态机乃至编译器的知识.好 ...
- Jsoup代码解读之三-Document的输出
Jsoup代码解读之三-Document的输出 Jsoup官方说明里,一个重要的功能就是output tidy HTML.这里我们看看Jsoup是如何输出HTML的. HTML相关知识 分析代码前 ...
- Jsoup代码解读之一-概述
Jsoup代码解读之一-概述 今天看到一个用python写的抽取正文的东东,美滋滋的用Java实现了一番,放到了webmagic里,然后发现Jsoup里已经有了…觉得自己各种不靠谱啊!算了,静下心来学 ...
随机推荐
- js-计算器
<div class="main"><h1>HTML5-计算器</h1> <input id="num1& ...
- python request使用
相比httplib.urllib,request真是太美丽了,记录下 下载安装地址:http://docs.python-requests.org/en/latest/user/install/#in ...
- Hibernate之dynamic-update
问题:设置了dynamic-update, 可是事实上并没有按照期望进行了update. 案例代码如下: 1.持久化对象 package com.jdw.hibernate.entities; imp ...
- OpenCV学习 4:摄像头视频读写与边缘检测
原创文章,欢迎转载,转载请注明出处 想实现人脸识别,车辆识别,车牌识别.一般我们可不是读硬盘里面的视频文件的,都是直接从摄像头读取视频流然后直接识别的.所以读取摄像头的视频流这是基础...OpenCV ...
- <meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Pragma" content="no-cache"><meta http-equiv="Cac ...
- Umbraco扩展开发
国内Umbraco方面的资料很少,搜集到一些国外的优秀项目或插件.记录下来,便于日后使用: backoffice:https://github.com/TimGeyssens 后台扩展UI,可以在这里 ...
- 解决Robotium测试用例crash问题
今天遇到一个棘手的问题 用robotium框架真机测试客户端时 跑到一半会crash 搜了一堆资料终于解决了 我的程序引起crash主要原因有两个: 1.用Robotium测试框架跑多个用例(写在同一 ...
- 起启航-华夏互联与杰华网络合体结盟打造本土IT利舰
北京时间2013年9月9日消息: 领先的软件研发企业上海逐一软件科技有限公司与专业互联网推广运营机构南昌杰华网络开发有限公司达成协议,双方将建立紧密合作关系与集团运营体制,并在未来的10个月内进行相应 ...
- 弹飞DZY(思维,打表,还没过全,先放着)
弹飞DZYDescription某天,机智的ZZC发明了一种超级弹力装置,为了在他的朋友DZY面前显摆,他邀请DZY一起玩个游戏.游戏一开始,ZZC在地上沿着一条直线摆上n个装置,每个装置设定初始弹力 ...
- 茴香豆的第五种写法---设置ExpandableListView系统自带图标按下效果
1 编写groupindicator_selector.xml如下: <?xml version="1.0" encoding="utf-8"?> ...