https://www.jianshu.com/p/74d6521f878f
之前一直没有注意过这种安全性问题,但是昨天实验室一个娃面试的时候被问到了这个问题,突然觉得挺感兴趣的,所以就了解了一下。
什么是XSS攻击
XSS
全称(Cross Site Scripting) 跨站脚本攻击, 是Web程序中最常见的漏洞。指攻击者在网页中嵌入客户端脚本(例如JavaScript), 当用户浏览此网页时,脚本就会在用户的浏览器上执行,从而达到攻击者的目的. 比如获取用户的Cookie,导航到恶意网站,携带木马等。
XSS攻击的原理
XSS
主要就是通过一些正常的站内交互途径,例如发表评论,提交含有JavaScript
的内容文本,这时服务器端如果没有过滤或转义掉这些脚本,作为内容发布到了页面上,其他用户访问这个页面的时候就会运行这些脚本,从而被攻击。
那么先举个栗子吧:
<input type="text" id="userInput"/>
<input type="button" onclick="submit()" value="提交"/>
JavaScript
代码:
function submit() {
var input = document.getElementById("userInput").value;
console.log(input);
}
当我随意输入一个值时,这个程序运行正常:
那么如果我输入了document.cookie
呢?我先给它加一个cookie
:
document.cookie = "name=haha";
这只是简单的获取
cookie
,如果我给里面加一些其他代码呢,后果不堪设想
XSS攻击类型
- 反射型XSS
主要是通过修改url的方式,因为url的参数可能在页面中用到,那我们就可以在参数中加一些恶意代码,当受害人访问这个链接的时候,这个恶意代码就执行了 - 储蓄型XSS
比如说有一个可以发表评论的地方,大家都可以评论,可以想到这个评论是要保存到后端的,如果这个评论有xss漏洞的话,我们发表一些恶意代码,然后恶意代码就被保存到服务器上了,当别人访问的时候,恶意代码执行,然后中招。
如何预防
1.使用XSS Filter
- 输入过滤,对用户提交的数据进行有效性验证,仅接受指定长度范围内并符合我们期望格式的的内容提交,阻止或者忽略除此外的其他任何数据
- 输出转义,当需要将一个字符串输出到Web网页时,同时又不确定这个字符串中是否包括XSS特殊字符,为了确保输出内容的完整性和正确性,输出HTML属性时可以使用HTML转义编码进行处理,输出到<script>中,可以进行JS编码。
url编码解码,这里所谓的输出转义就是将特殊字符转义成浏览器页面要识别的东西例如<srcipt>alert("aaa")</script>,如果直接在浏览器上输出这个内容,浏览器认为这就是一个JavaScript脚本就会弹出一个对话框。我们让让浏览器显示<srcipt>我们就是对<和>进行转义,转义成<scprit> -
比如用户输入的<>换成< >
存入数据库就是< >
我预期是在 jsp 上输出的时候
jsp 会自动把< > 转成<>显示
-
下面是常用的html转义符:
字符 说明 转义字符 " 双引号 &amp;quot; & &符号 &amp;amp; < 小于 &amp;lt; > 大于 &amp;gt; 不断行的空白格 &amp;nbsp; ' 单引号 &amp;acute; © 版权 &amp;copy; ® 已注册商标 &amp;reg;
2.使用 HttpOnly Cookie
http-only参数,在重要的cookie
参数中加入httpOnly
属性,这样的话javascript
就不能取到cookie
值,可以解决一部分xss
威胁。
记录自己的点滴~
3.输入内容长度控制
对于不受信任的输入,都应该限定一个合理的长度。虽然无法完全防止 XSS 发生,但可以增加 XSS 攻击的难度。
4.输入内容限制
对于部分输入,可以限定不能包含特殊字符或者仅能输入数字等。
5.其他安全措施
- HTTP-only Cookie: 禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。
- 验证码:防止脚本冒充用户提交危险操作。
补充:
为什么要用转义字符串?
HTML中<,>,&等有特殊含义(<,>,用于链接签,&用于转义),不能直接使用。这些符号是不显示在我们最终看到的网页里的,那如果我们希望在网页中显示这些符号,该怎么办呢?
这就要说到HTML转义字符串(Escape Sequence)了。
转义字符串(Escape Sequence)也称字符实体(Character Entity)。在HTML中,定义转义字符串的原因有两个:第一个原因是像“<”和“>”这类符号已经用来表示HTML标签,因此就不能直接当作文本中的符号来使用。为了在HTML文档中使用这些符号,就需要定义它的转义字符串。当解释程序遇到这类字符串时就把它解释为真实的字符。在输入转义字符串时,要严格遵守字母大小写的规则。第二个原因是,有些字符在ASCII字符集中没有定义,因此需要使用转义字符串来表示。
转义字符串的组成
转义字符串(Escape Sequence),即字符实体(Character Entity)分成三部分:第一部分是一个&符号,英文叫ampersand;第二部分是实体(Entity)名字或者是#加上实体(Entity)编号;第三部分是一个分号。
比如,要显示小于号(<),就可以写 < 或者 < 。
用实体(Entity)名字的好处是比较好理解,一看lt,大概就猜出是less than的意思,但是其劣势在于并不是所有的浏览器都支持最新的Entity名字。而实体(Entity)编号,各种浏览器都能处理。
提示:实体名称(Entity)是区分大小写的。
备注:同一个符号,可以用“实体名称”和“实体编号”两种方式引用,“实体名称”的优势在于便于记忆,但不能保证所有的浏览器都能顺利识别它,而“实体编号”则没有这种担忧,但它实在不方便记忆。
如何显示空格?
通常情况下,HTML会自动截去多余的空格。不管你加多少空格,都被看做一个空格。比如你在两个字之间加了10个空格,HTML会截去9个空格,只保留一个。为了在网页中增加空格,你可以使用 表示空格。
HTML特殊转义字符列表
最常用的字符实体
Character Entities
显示 | 说明 | 实体名称 | 实体编号 |
---|---|---|---|
半方大的空白 |   |   | |
全方大的空白 |   |   | |
不断行的空白格 | |   | |
< | 小于 | < | < |
> | 大于 | > | > |
& | &符号 | & | & |
" | 双引号 | " | " |
© | 版权 | © | © |
® | 已注册商标 | ® | ® |
™ | 商标(美国) | ™ | ™ |
× | 乘号 | × | × |
÷ | 除号 | ÷ | ÷ |
字符 | 十进制 | 转义字符 | 字符 | 十进制 | 转义字符 |
---|---|---|---|---|---|
" | " | " | & | & | & |
< | < | < | à | à | à |
> | > | > | 不断开空格 |   | |
? | ¡ | ¡ | Á | Á | Á |
á | á | á | â | â | â |
¢ | ¢ | ¢ | Â | Â | ˆ |
£ | £ | £ | Ã | Ã | Ã |
ã | ã | ã | ä | ä | ä |
¤ | ¤ | ¤ | Ä | Ä | Ä |
¥ | ¥ | ¥ | Å | Å | ˚ |
å | å | å | æ | æ | æ |
| | ¦ | ¦ | Æ | Æ | Æ |
§ | § | § | Ç | Ç | Ç |
ç | ç | ç | è | è | è |
¨ | ¨ | ¨ | È | È | È |
© | © | © | É | É | É |
é | é | é | ê | ê | ê |
a | ª | ª | Ê | Ê | Ê |
? | « | « | Ë | Ë | Ë |
ë | ë | ë | ì | ì | ì |
? | ¬ | ¬ | Ì | Ì | Ì |
/x7f | ­ | ­ | Í | Í | Í |
í | í | í | î | î | î |
® | ® | ® | Î | Î | Î |
ˉ | ¯ | ¯ | Ï | Ï | Ï |
ï | ï | ï | ð | ð | &ieth; |
° | ° | ° | Ð | Ð | Ð |
± | ± | ± | Ñ | Ñ | Ñ |
ñ | ñ | ñ | ò | ò | ò |
2 | ² | ² | Ò | Ò | Ò |
3 | ³ | ³ | Ó | Ó | Ó |
ó | ó | ó | ô | ô | ô |
′ | ´ | ´ | Ô | Ô | Ô |
μ | µ | µ | Õ | Õ | Õ |
õ | õ | õ | ö | ö | ö |
? | ¶ | ¶ | Ö | Ö | Ö |
· | · | · | × | × | × |
÷ | ÷ | ÷ | ø | ø | ø |
? | ¸ | ¸ | Ø | Ø | Ø |
1 | ¹ | ¹ | Ù | Ù | Ù |
ù | ù | ù | ú | ú | ú |
o | º | º | Ú | Ú | Ú |
? | » | » | Û | Û | Û |
û | û | û | ü | ü | ü |
? | ¼ | ¼ | Ü | Ü | Ü |
? | ½ | ½ | Ý | Ý | Ý |
? | ¾ | ¾ | Þ | Þ | Þ |
þ | þ | þ | ý | ý | ý |
? | ¿ | ¿ | ß | ß | ß |
À | À | À | ÿ | ÿ | ÿ |
特殊符号
|
命名实体
|
十进制编码
|
特殊符号
|
命名实体
|
十进制编码
|
Α
|
Α
|
Α
|
Β
|
Β
|
Β
|
Γ
|
Γ
|
Γ
|
Δ
|
Δ
|
Δ
|
Ε
|
Ε
|
Ε
|
Ζ
|
Ζ
|
Ζ
|
Η
|
Η
|
Η
|
Θ
|
Θ
|
Θ
|
Ι
|
Ι
|
Ι
|
Κ
|
Κ
|
Κ
|
Λ
|
Λ
|
Λ
|
Μ
|
Μ
|
Μ
|
Ν
|
Ν
|
Ν
|
Ξ
|
Ξ
|
Ξ
|
Ο
|
Ο
|
Ο
|
Π
|
Π
|
Π
|
Ρ
|
Ρ
|
Ρ
|
Σ
|
Σ
|
Σ
|
Τ
|
Τ
|
Τ
|
Υ
|
Υ
|
Υ
|
Φ
|
Φ
|
Φ
|
Χ
|
Χ
|
Χ
|
Ψ
|
Ψ
|
Ψ
|
Ω
|
Ω
|
Ω
|
α
|
α
|
α
|
β
|
β
|
β
|
γ
|
γ
|
γ
|
δ
|
δ
|
δ
|
ε
|
ε
|
ε
|
ζ
|
ζ
|
ζ
|
η
|
η
|
η
|
θ
|
θ
|
θ
|
ι
|
ι
|
ι
|
κ
|
κ
|
κ
|
λ
|
λ
|
λ
|
μ
|
μ
|
μ
|
ν
|
ν
|
ν
|
ξ
|
ξ
|
ξ
|
ο
|
ο
|
ο
|
π
|
π
|
π
|
ρ
|
ρ
|
ρ
|
ς
|
ς
|
ς
|
σ
|
σ
|
σ
|
τ
|
τ
|
τ
|
υ
|
υ
|
υ
|
φ
|
φ
|
φ
|
χ
|
χ
|
χ
|
ψ
|
ψ
|
ψ
|
ω
|
ω
|
ω
|
ϑ
|
ϑ
|
ϑ
|
ϒ
|
ϒ
|
ϒ
|
ϖ
|
ϖ
|
ϖ
|
•
|
•
|
•
|
…
|
…
|
…
|
′
|
′
|
′
|
″
|
″
|
″
|
‾
|
‾
|
‾
|
⁄
|
⁄
|
⁄
|
℘
|
℘
|
℘
|
ℑ
|
ℑ
|
ℑ
|
ℜ
|
ℜ
|
ℜ
|
™
|
™
|
™
|
ℵ
|
ℵ
|
ℵ
|
←
|
←
|
←
|
↑
|
↑
|
↑
|
→
|
→
|
→
|
↓
|
↓
|
↓
|
↔
|
↔
|
↔
|
↵
|
↵
|
↵
|
⇐
|
⇐
|
⇐
|
⇑
|
⇑
|
⇑
|
⇒
|
⇒
|
⇒
|
⇓
|
⇓
|
⇓
|
⇔
|
⇔
|
⇔
|
∀
|
∀
|
∀
|
∂
|
∂
|
∂
|
∃
|
∃
|
∃
|
∅
|
∅
|
∅
|
∇
|
∇
|
∇
|
∈
|
∈
|
∈
|
∉
|
∉
|
∉
|
∋
|
∋
|
∋
|
∏
|
∏
|
∏
|
∑
|
∑
|
−
|
−
|
−
|
−
|
∗
|
∗
|
∗
|
√
|
√
|
√
|
∝
|
∝
|
∝
|
∞
|
∞
|
∞
|
∠
|
∠
|
∠
|
∧
|
∧
|
⊥
|
∨
|
∨
|
⊦
|
∩
|
∩
|
∩
|
∪
|
∪
|
∪
|
∫
|
∫
|
∫
|
∴
|
∴
|
∴
|
∼
|
∼
|
∼
|
≅
|
≅
|
≅
|
≈
|
≈
|
≅
|
≠
|
≠
|
≠
|
≡
|
≡
|
≡
|
≤
|
≤
|
≤
|
≥
|
≥
|
≥
|
⊂
|
⊂
|
⊂
|
⊃
|
⊃
|
⊃
|
⊄
|
⊄
|
⊄
|
⊆
|
⊆
|
⊆
|
⊇
|
⊇
|
⊇
|
⊕
|
⊕
|
⊕
|
⊗
|
⊗
|
⊗
|
⊥
|
⊥
|
⊥
|
⋅
|
⋅
|
⋅
|
⌈
|
⌈
|
⌈
|
⌉
|
⌉
|
⌉
|
⌊
|
⌊
|
⌊
|
⌋
|
⌋
|
⌋
|
◊
|
◊
|
◊
|
♠
|
♠
|
♠
|
♣
|
♣
|
♣
|
♥
|
♥
|
♥
|
♦
|
♦
|
♦
|
|
 
|
|
¡
|
¡
|
¡
|
¢
|
¢
|
¢
|
£
|
£
|
£
|
¤
|
¤
|
¤
|
¥
|
¥
|
¥
|
¦
|
¦
|
¦
|
§
|
§
|
§
|
¨
|
¨
|
¨
|
©
|
©
|
©
|
ª
|
ª
|
ª
|
«
|
«
|
«
|
¬
|
¬
|
¬
|
­
|
­
|
®
|
®
|
®
|
|
¯
|
¯
|
¯
|
°
|
°
|
d°
|
±
|
±
|
±
|
²
|
²
|
²
|
³
|
³
|
³
|
´
|
´
|
´
|
µ
|
µ
|
µ
|