Skip to content

Commit 23da5b2

Browse files
committed
8
1 parent dbfb6c8 commit 23da5b2

File tree

4 files changed

+47
-2
lines changed

4 files changed

+47
-2
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Fork of Jsoup in [https://github.com/jhy/jsoup](https://github.com/jhy/jsoup)
2222

2323
### [Jsoup代码解读之七-select](https://github.com/code4craft/jsoup/blob/master/blogs/jsoup7.md)
2424

25+
### [Jsoup代码解读之八-防御XSS攻击](https://github.com/code4craft/jsoup/blob/master/blogs/jsoup8.md)
26+
2527
-------
2628

2729
## 协议:

blogs/images/hacker.png

70.1 KB
Loading

blogs/jsoup7.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Jsoup的select包里,类结构如下:
1111

1212
![uml][2]
1313

14-
在最开始介绍的Jsoup的时候,就已经说过`NodeVisitor``Selector`了。`Selector`是select部分的对外facade,而`NodeVisitor`则是遍历树的底层API,CSS Selector也是根据`NodeVisitor`实现的遍历。
14+
在最开始介绍Jsoup的时候,就已经说过`NodeVisitor``Selector`了。`Selector`是select部分的对外facade,而`NodeVisitor`则是遍历树的底层API,CSS Selector也是根据`NodeVisitor`实现的遍历。
1515

1616
Jsoup的select核心是`Evaluator`。Selector所传递的表达式,会经过`QueryParser`,最终编译成一个`Evaluator``Evaluator`是一个抽象类,它只有一个方法:
1717

@@ -48,7 +48,7 @@ Evaluator的设计简洁明了,所有的Selector表达式单词都会编译到
4848
}
4949
```
5050

51-
这里Parent包含了一个`evaluator`属性,会根据这个evaluator去验证所有父节点。注意Parent是可以嵌套的,所以这个表达式"div ul li"最终会编译成`And(And(Parent(Tag("div")),Tag("ul")),Tag("li"))`这样的Evaluator组合。
51+
这里Parent包含了一个`evaluator`属性,会根据这个evaluator去验证所有父节点。注意Parent是可以嵌套的,所以这个表达式"div ul li"最终会编译成`And(Parent(And(Parent(Tag("div")),Tag("ul")),Tag("li")))`这样的Evaluator组合。
5252

5353
select部分比想象的要简单,代码可读性也很高。经过了parser部分的研究,这部分应该算是驾轻就熟了。
5454

blogs/jsoup8.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
Jsoup代码解读之八-防御XSS攻击
2+
--------
3+
![hacker][1]
4+
5+
## 一般原理
6+
7+
cleaner是Jsoup的重要功能之一,我们常用它来进行富文本输入中的XSS防御。
8+
9+
我们知道,XSS攻击的一般方式是,通过在页面输入中嵌入一段恶意脚本,对输出时的DOM结构进行修改,从而达到执行这段脚本的目的。对于纯文本输入,过滤/转义HTML特殊字符`<`,`>`,`"`,`'`是行之有效的办法,但是如果本身用户输入的就是一段HTML文本(例如博客文章),这种方式就不太有效了。这个时候,就是Jsoup大显身手的时候了。
10+
11+
在前面,我们已经知道了,Jsoup里怎么将HTML变成一棵DOM树,怎么对DOM树进行遍历,怎么对DOM文档进行输出,那么其实cleaner的实现方式,也能猜出大概了。使用Jsoup进行XSS防御,大致分为三个步骤:
12+
13+
1. 将HTML解析为DOM树
14+
15+
这一步可以过滤掉一些企图搞破坏的非闭合标签、非正常语法等。例如一些输入,会尝试用`</textarea>`闭合当前Tag,然后写入攻击脚本。而根据前面对Jsoup的parser的分析,这种时候,这些非闭合标签会被当做错误并丢弃。
16+
17+
2. 过滤高风险标签/属性/属性值
18+
19+
高风险标签是指`<script>`以及类似标签,对属性/属性值进行过滤是因为某些属性值里也可以写入javascript脚本,例如`onclick='alert("xss!")'`。
20+
21+
22+
3. 重新将DOM树输出为HTML文本
23+
24+
DOM树的输出,在前面(Jsoup代码解读之三)已经提到过了。
25+
26+
## Cleaner与Whitelist
27+
28+
对于上述的两个步骤,1、3都已经分别在parser和输出中完成,现在只剩下步骤 2:过滤高风险标签等。
29+
30+
Jsoup给出的答案是白名单。
31+
32+
```java
33+
public class Whitelist {
34+
private Set<TagName> tagNames; // tags allowed, lower case. e.g. [p, br, span]
35+
private Map<TagName, Set<AttributeKey>> attributes; // tag -> attribute[]. allowed attributes [href] for a tag.
36+
private Map<TagName, Map<AttributeKey, AttributeValue>> enforcedAttributes; // always set these attribute values
37+
private Map<TagName, Map<AttributeKey, Set<Protocol>>> protocols; // allowed URL protocols for attributes
38+
private boolean preserveRelativeLinks; // option to preserve relative links
39+
}
40+
```
41+
42+
43+
[1]: http://static.oschina.net/uploads/space/2013/0831/071752_RBZc_190591.png

0 commit comments

Comments
 (0)