Skip to content

Commit fbfa1ab

Browse files
authored
Update translation of 3-frames-and-windows/06-clickjacking (#719)
Update translation of 3-frames-and-windows/06-clickjacking (#719)
1 parent 72e4ee6 commit fbfa1ab

File tree

9 files changed

+99
-81
lines changed

9 files changed

+99
-81
lines changed

1-js/01-getting-started/3-code-editors/article.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
[IDE](https://en.wikipedia.org/wiki/Integrated_development_environment)(集成开发环境)是用于管理整个项目具有强大功能的编辑器。顾名思义,它不仅仅是一个编辑器,而且还是个完整的开发环境。
1010

11-
IDE 加载项目(通常包含很多文件),并且允许在不同文件之间切换。IDE 还提供基于整个项目(不仅仅是打开的文件)的自动补全功能,集成版本控制(如 [git](https://git-scm.com/))、集成测试环境等一些其他“项目层面”的东西。
11+
IDE 加载项目(通常包含很多文件),并且允许在不同文件之间导航(navigation)。IDE 还提供基于整个项目(不仅仅是打开的文件)的自动补全功能,集成版本控制(如 [git](https://git-scm.com/))、集成测试环境等一些其他“项目层面”的东西。
1212

1313
如果你还没考虑好选哪一款 IDE,可以考虑下面两个:
1414

1-js/03-code-quality/01-debugging-chrome/article.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
资源(Sources)面板包含三个部分:
2828

29-
1. **文件浏览(File Navigator)** 区域列出了 HTML、JavaScript、CSS 和包括图片在内的其他依附于此页面的文件。Chrome 扩展程序也会显示在这。
29+
1. **文件导航(File Navigator)** 区域列出了 HTML、JavaScript、CSS 和包括图片在内的其他依附于此页面的文件。Chrome 扩展程序也会显示在这。
3030
2. **代码编辑(Code Editor)** 区域展示源码。
3131
3. **JavaScript 调试(JavaScript Debugging)** 区域是用于调试的,我们很快就会来探索它。
3232

1-js/05-data-types/06-iterable/article.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11

2-
# Iterable(可迭代对象)
2+
# Iterable object(可迭代对象)
33

4-
**Iterable**(可迭代对象)是数组的泛化。这个概念是说任何对象都可以被定制为可在 `for..of` 循环中使用的对象。
4+
**可迭代(Iterable** 对象是数组的泛化。这个概念是说任何对象都可以被定制为可在 `for..of` 循环中使用的对象。
55

6-
数组本身就是可迭代的。但不仅仅是数组。很多其他内建对象也都可以迭代,例如字符串也是可以迭代的
6+
数组是可迭代的。但不仅仅是数组。很多其他内建对象也都是可迭代的。例如字符串也是可迭代的
77

8-
如果从技术上讲,对象不是数组,而是表示某物的集合(列表,集合),`for..of` 是一个能够遍历它的很好的语法,因此,让我们看看如何使其工作
8+
如果从技术上讲,对象不是数组,而是表示某物的集合(列表,集合),`for..of` 是一个能够遍历它的很好的语法,因此,让我们来看看如何使其发挥作用
99

1010

1111
## Symbol.iterator

1-js/13-modules/02-import-export/article.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ say.*!*bye*/!*('John'); // Bye, John!
160160

161161
大部分情况下,开发者倾向于使用第二种方式,以便每个“东西”都存在于它自己的模块中。
162162

163-
当然,这需要大量文件,因为每个东西都需要自己的模块,但这根本不是问题。实际上,如果文件具有良好的命名,并且文件夹结构得当,那么代码导航会变得更容易
163+
当然,这需要大量文件,因为每个东西都需要自己的模块,但这根本不是问题。实际上,如果文件具有良好的命名,并且文件夹结构得当,那么代码导航(navigation)会变得更容易
164164

165165
模块提供了特殊的默认导出 `export default` 语法,以使“一个模块只做一件事”的方式看起来更好。
166166

Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
# 点击劫持攻击
22

3-
“点击劫持” 攻击即允许恶意网页**以用户的名义**点击 “受害站点”。
3+
“点击劫持”攻击允许恶意页面 **以用户的名义** 点击“受害网站”。
44

5-
许多站点都被这样攻击过,包括 Twitter、Facebook 和 Paypal 等等许多网站。当然,目前它们都已修复这个问题
5+
许多网站都被黑客以这种方式攻击过,包括 Twitter、Facebook 和 Paypal 等许多网站。当然,它们都已经被修复了
66

77
## 原理
88

99
原理十分简单。
1010

11-
以下以 Facebook 为例解释点击劫持是如何运作的
11+
我们以 Facebook 为例,解释点击劫持是如何完成的
1212

13-
1. 访问者被恶意网页吸引。此处略过如何被吸引的
14-
2. 页面上存在一个看起来无害的链接(比如:“马上有钱” 或者 “点我,超好玩!”)。
15-
3. 恶意网页在该链接之上放置一个透明 `<iframe>` 标签,其中 `src` 指向 facebook.com,如此一来,“点赞” 按钮恰好在链接上面。通常用 `z-index` 实现
16-
4. 如果用户试图点击该链接,实际上是点到了 “点赞” 按钮上
13+
1. 访问者被恶意页面吸引。怎样吸引的不重要
14+
2. 页面上有一个看起来无害的链接(例如:“变得富有”或者“点我,超好玩!”)。
15+
3. 恶意页面在该链接上方放置了一个透明的 `<iframe>`,其 `src` 来自于 facebook.com,这使得“点赞”按钮恰好位于该链接上面。这通常是通过 `z-index` 实现的
16+
4. 用户尝试点击该链接时,实际上点击的是“点赞”按钮
1717

1818
## 示例
1919

20-
以下是恶意网页的一般代码。为了更好的说明问题,`<iframe>` 标签设置成半透明状态(真正的恶意网页为全透明状态):
20+
这是恶意页面看起来的样子。为了清楚起见,我们将 `<iframe>` 设置成了半透明的(在真正的恶意页面中,它是全透明的):
2121

2222
```html run height=120 no-beautify
2323
<style>
@@ -27,138 +27,138 @@ iframe { /* 来自受害网站的 iframe */
2727
position: absolute;
2828
top:0; left:-20px;
2929
*!*
30-
opacity: 0.5; /* 真实为 opacity:0 */
30+
opacity: 0.5; /* 在实际中为 opacity:0 */
3131
*/!*
3232
z-index: 1;
3333
}
3434
</style>
3535

36-
<div>马上有钱:</div>
36+
<div>点击即可变得富有:</div>
3737

3838
<!-- 来自受害网站的 url -->
3939
*!*
4040
<iframe src="/clickjacking/facebook.html"></iframe>
4141

42-
<button>点我!点我!</button>
42+
<button>点这里!</button>
4343
*/!*
4444

45-
<div>...你会变帅(我才是帅黑客😜)!</div>
45+
<div>……你很酷(我实际上是一名帅气的黑客)!</div>
4646
```
4747

4848
完整的攻击示例如下:
4949

5050
[codetabs src="clickjacking-visible" height=160]
5151

52-
例子中的半透明 `<iframe src="facebook.html">` 覆盖在按钮之上。点击按钮实际上点击在 iframe 标签上,但由于 iframe 标签透明,这一动作对用户不可见
52+
在上面这个示例中,我们有一个半透明的 `<iframe src="facebook.html">`,我们可以看到,它位于按钮之上。点击按钮实际上会点击在 iframe 上,但这对用户不可见,因为 iframe 是透明的
5353

54+
结果,如果访问者登陆了 Facebook(“记住我”通常是打开的),那么这个行为就会点一个“赞”。Twitter 上是 "Follow" 按钮。
5455

55-
因此,若访问者曾登陆 Facebook(“记住我” 开关打开),这个动作会使用户在 Facebook 上进行 “Like” 操作。Twitter 上是 “Follow” 操作。
56-
57-
下面的例子相同,但 `iframe` 设置为 `opacity:0` 更符合实际情况:
56+
下面是相同的示例,但 `iframe` 的透明度设置为了 `opacity:0`,更符合实际情况:
5857

5958
[codetabs src="clickjacking" height=160]
6059

61-
只需要在恶意网页中的链接正上方放置 `<iframe>`,点击按钮就能发起攻击。通常用 CSS 就能实现
60+
我们进行攻击所需要做的 —— 就是将 `<iframe>` 放置在恶意页面中,使得按钮恰好位于链接的正上方。这样当用户点击链接时,他们实际上点击的是按钮。这通常可以通过 CSS 实现
6261

63-
```smart header="点击劫持作用于点击事件,而非键盘事件"
64-
此攻击仅影响鼠标操作
62+
```smart header="点击劫持是对点击事件,而非键盘事件"
63+
此攻击仅影响鼠标行为(或者类似的行为,例如在手机上的点击)
6564
66-
从技术上讲,可以用 iframe 中的文本域覆盖原有的文本域实现攻击。所以当访问者试图聚焦网页中的 input 标签时,实际上聚焦的是 iframe 中的 input 标签
65+
键盘输入很难重定向。从技术上讲,我们可以用 iframe 的文本区域覆盖原有的文本区域实现攻击。因此,当访问者试图聚焦页面中的输入时,实际上聚焦的是 iframe 中的输入
6766
68-
但是这里有个问题。访问者的所有输入都会被隐藏,因为该 iframe 是不可见的。
67+
但是这里有个问题。访问者键入的所有内容都会被隐藏,因为该 iframe 是不可见的。
6968
7069
当用户无法在屏幕上看到自己输入的字符时,通常会停止打字。
7170
```
7271

7372
## 传统防御(弱 👎)
7473

75-
最古老的防御是一段禁止在非顶层页面中打开网页的 JavaScript 代码(所谓的 “framebusting”)。
74+
最古老的防御措施是一段用于禁止在 frame 中打开页面的 JavaScript 代码(所谓的 “framebusting”)。
7675

77-
如下所示
76+
它看起来像这样
7877

7978
```js
8079
if (top != window) {
8180
top.location = window.location;
8281
}
8382
```
8483

85-
意思是:window 强制置顶,如果没在顶层,自动置顶
84+
意思是说:如果 window 发现它不在顶部,那么它将自动使其自身位于顶部
8685

87-
这个方法并不可靠,因为有许多方式可以绕过这个限制。下面就介绍几个
86+
这个方法并不可靠,因为有许多方式可以绕过这个限制。下面我们就介绍几个
8887

89-
### 阻塞顶层容器
88+
### 阻止顶级导航
9089

91-
[beforeunload](info:onload-ondomcontentloaded#window.onbeforeunload) 事件中阻塞 `top.location` 变更过渡
90+
我们可以阻止因更改 [beforeunload](info:onload-ondomcontentloaded#window.onbeforeunload) 事件处理程序中的 `top.location` 而引起的过渡(transition)
9291

93-
顶层页面(从属于黑客)在 `beforeunload` 上添加一个处理方法:当 `iframe` 试图变更 `top.location` 时,访问者会收到询问是否离开的消息。
92+
顶级页面(从属于黑客)在 `beforeunload` 上设置了一个用于阻止的处理程序,像这样:
9493

95-
如下所示:
9694
```js
9795
window.onbeforeunload = function() {
98-
window.onbeforeunload = null;
99-
return "Want to leave without learning all the secrets (he-he)?";
96+
return false;
10097
};
10198
```
10299

103-
大多数情况下,由于并不知道 iframe 的存在,访问者看到的只是顶层页面,即本来就要访问的页面,由此认为没有必要离开,所以会回答否。则 `top.location` 并不会变化!
100+
`iframe` 试图更改 `top.location` 时,访问者会收到一条消息,询问他们是否要离开页面。
101+
102+
在大多数情况下,访问者会做出否定的回答,因为他们并不知道还有这么一个 iframe,他们所看到的只有顶级页面,他们没有理由离开。所以 `top.location` 不会变化!
104103

105-
作用如下
104+
演示示例
106105

107106
[codetabs src="top-location"]
108107

109-
### 沙箱属性
108+
### Sandbox 特性
110109

111-
一个受 `sandbox` 属性限制的对象是导航。沙箱化的 iframe 不能变更 `top.location`
110+
`sandbox` 特性的限制之一就是导航。沙箱化的 iframe 不能更改 `top.location`
112111

113-
但可以添加带有 `sandbox="allow-scripts allow-forms"` 的 iframe 标签。从而放开限制,允许脚本和表单在 iframe 中执行。但 `allow-top-navigation` 禁止了 `top.location` 的变更
112+
但我们可以添加具有 `sandbox="allow-scripts allow-forms"` 的 iframe。从而放开限制,允许脚本和表单。但我们没添加 `allow-top-navigation`,因此更改 `top.location` 是被禁止的
114113

115114
代码如下:
116115

117116
```html
118117
<iframe *!*sandbox="allow-scripts allow-forms"*/!* src="facebook.html"></iframe>
119118
```
120119

121-
当然还有其他绕过这个弱鸡防御的方法
120+
还有其他方式可以绕过这个弱鸡防御
122121

123122
## X-Frame-Options
124123

125-
服务端 header 字段 `X-Frame-Options` 能够允许或禁止 frame 内页面的显示
124+
服务器端 header `X-Frame-Options` 可以允许或禁止在 frame 中显示页面
126125

127-
这个 header 必须由 **服务端** 发送:若浏览器发现 `<meta>` 标签里有该字段,则会忽略此字段。即`<meta http-equiv="X-Frame-Options"...>` 不生效
126+
它必须被完全作为 HTTP-header 发送:如果浏览器在 HTML `<meta>` 标签中找到它,则会忽略它。因此`<meta http-equiv="X-Frame-Options"...>` 没有任何作用
128127

129-
header 有三个值
128+
这个 header 可能包含 3 个值
130129

131130

132131
`DENY`
133-
: 始终禁止 frame 中的页面加载
132+
: 始终禁止在 frame 中显示此页面
134133

135134
`SAMEORIGIN`
136-
: 允许和父页面同一来源的 frame 进行页面加载
135+
: 允许在和父文档同源的 frame 中显示此页面
137136

138137
`ALLOW-FROM domain`
139-
: 允许和父页面同一给定域的 frame 进行页面加载
138+
: 允许在来自给定域的父文档的 frame 中显示此页面
140139

141140
例如,Twitter 使用的是 `X-Frame-Options: SAMEORIGIN`
142141

143142
````online
144-
如下所示
143+
结果如下
145144
146145
```html
147146
<iframe src="https://twitter.com"></iframe>
148147
```
149148
149+
<!-- ebook: prerender/ chrome headless dies and timeouts on this iframe -->
150150
<iframe src="https://twitter.com"></iframe>
151151
152-
取决于浏览器行为,以上 `iframe` 要么显示为空,要么提醒你浏览器不允许内部页面加载
152+
上面这个 `iframe` 可能为空,或者通过 alert 告知你浏览器不允许以这种方式导航至该页面,这取决于你的浏览器
153153
````
154154

155-
## 显示不可用功能
155+
## 显示禁用的功能
156156

157-
`X-Frame-Options` 存在副作用。它无差别地禁止合法站点在 frame 中显示我们的网页
157+
`X-Frame-Options` 有一个副作用。其他的网站即使有充分的理由也无法在 frame 中显示我们的页面
158158

159-
所以还有其他措施...例如,把设置了 `height: 100%; width: 100%;``<div>` “覆盖” 在页面上,这样就能监听所有的点击事件。在 `window == top` 或无需防御的情况下,此 `<div>` 则应该隐藏起来
159+
因此,还有其他解决方案……例如,我们可以用一个样式为 `height: 100%; width: 100%;``<div>` “覆盖”页面,这样它就能拦截所有点击。如果 `window == top` 或者我们确定不需要保护时,再将该 `<div>` 移除
160160

161-
代码示例如下
161+
像这样
162162

163163
```html
164164
<style>
@@ -173,31 +173,49 @@ window.onbeforeunload = function() {
173173
</style>
174174

175175
<div id="protector">
176-
<a href="/" target="_blank">Go to the site</a>
176+
<a href="/" target="_blank">前往网站</a>
177177
</div>
178178

179179
<script>
180-
// 如果顶层 window 来自不同的域,会报错
181-
// 但是此处并没有报错
180+
// 如果顶级窗口来自其他源,这里则会出现一个 error
181+
// 但是在本例中没有问题
182182
if (top.document.domain == document.domain) {
183183
protector.remove();
184184
}
185185
</script>
186186
```
187187

188-
演示如下
188+
演示示例
189189

190190
[codetabs src="protector"]
191191

192+
## Samesite cookie 特性
193+
194+
`samesite` cookie 特性也可以阻止点击劫持攻击。
195+
196+
具有 `samesite` 特性的 cookie 仅在网站是通过直接方式打开(而不是通过 frame 或其他方式)的情况下才发送到网站。更多细节请见 <info:cookie#samesite>
197+
198+
如果网站,例如 Facebook,在其身份验证 cookie 中具有 `samesite` 特性,像这样:
199+
200+
```
201+
Set-Cookie: authorization=secret; samesite
202+
```
203+
204+
……那么,当在另一个网站中的 iframe 中打开 Facebook 时,此类 cookie 将不会被发送。因此,攻击将失败。
205+
206+
当不实用 cookie 时,`samesite` cookie 特性将不会有任何影响。这可以使其他网站能够轻松地在 iframe 中显示我们公开的、未进行身份认证的页面。
207+
208+
然而,这也可能会使得劫持攻击在少数情况下起作用。例如,通过检查 IP 地址来防止重复投票的匿名投票网站仍然会受到点击劫持的攻击,因为它不使用 cookie 对用户身份进行验证。
209+
192210
## 总结
193211

194-
点击劫持是一种 “欺骗” 用户在不知情下点击恶意站点的方式。如果是重要的点击操作,这是非常危险的。
212+
点击劫持是一种“诱骗”用户在不知情的情况下点击恶意网站的方式。如果是重要的点击操作,这是非常危险的。
195213

196-
黑客可以通过信息提交一个链接到他的恶意网页,或者通过某些手段引诱访问者访问他的网页。当然还有许多其他变体
214+
黑客可以通过信息发布指向他的恶意页面的链接,或者通过某些手段引诱访问者访问他的页面。当然还有很多其他变体
197215

198-
一方面 —— 这种攻击方式是“浅层”的:黑客只需要拦截一次点击。但另一方面,如果被这次点击之后会开启另一个控制开关,那么黑客同样用狡猾的提示强制用户点击这些控制按钮
216+
一方面 —— 这种攻击方式是“浅层”的:黑客所做的只是拦截一次点击。但另一方面,如果黑客知道在点击之后将出现另一个控件,则他们可能还会使用狡猾的消息来迫使用户也点击它们
199217

200-
这种攻击相当危险,因为在设计交互界面时,通常不会考虑到可能会有黑客代替真正的访问者点击界面。所以许多意想不到的地方可能发现攻击漏洞
218+
这种攻击相当危险,因为在设计交互界面时,我们通常不会考虑到可能会有黑客代表用户点击界面。所以,在许多意想不到的地方可能发现攻击漏洞
201219

202-
- 推荐在网页上(或整个站点)使用 `X-Frame-Options: SAMEORIGIN`,这不会被 frame 内部读取
203-
- 若要允许的页面在 frame 中显示,用一个 `<div>` 遮盖,这样仍然是安全的
220+
- 建议在那些不希望被在 frame 中查看的页面上(或整个网站上)使用 `X-Frame-Options: SAMEORIGIN`
221+
- 如果我们希望允许在 frame 中显示我们的页面,那我们使用一个 `<div>` 对整个页面进行遮盖,这样也是安全的

3-frames-and-windows/06-clickjacking/clickjacking-visible.view/index.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
}
2020
</style>
2121

22-
<div>Click to get rich now:</div>
22+
<div>点击即可变得富有:</div>
2323

24-
<!-- The url from the victim site -->
24+
<!-- 来自受害网站的 url -->
2525
<iframe src="facebook.html"></iframe>
2626

27-
<button>Click here!</button>
27+
<button>点这里!</button>
2828

29-
<div>...And you're cool (I'm a cool hacker actually)!</div>
29+
<div>……你很酷(我实际上是一名帅气的黑客)!</div>
3030

3131
</body>
3232
</html>

3-frames-and-windows/06-clickjacking/clickjacking.view/index.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
}
2020
</style>
2121

22-
<div>Click to get rich now:</div>
22+
<div>点击即可变得富有:</div>
2323

24-
<!-- The url from the victim site -->
24+
<!-- 来自受害网站的 url -->
2525
<iframe src="facebook.html"></iframe>
2626

27-
<button>Click here!</button>
27+
<button>点这里!</button>
2828

29-
<div>...And you're cool (I'm a cool hacker actually)!</div>
29+
<div>……你很酷(我实际上是一名帅气的黑客)!</div>
3030

3131
</body>
3232
</html>

3-frames-and-windows/06-clickjacking/protector.view/iframe.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<body>
2121

2222
<div id="protector">
23-
<a href="/" target="_blank">Go to the site</a>
23+
<a href="/" target="_blank">前往网站</a>
2424
</div>
2525

2626
<script>
@@ -31,11 +31,11 @@
3131

3232
</script>
3333

34-
This text is always visible.
34+
文本一直是可见的。
3535

36-
But if the page was open inside a document from another domain, the div over it would prevent any actions.
36+
但是,如果该页面是在来自另一个域的文档中打开的,则该页面上的 div 将阻止所有行为。
3737

38-
<button onclick="alert(1)">Click wouldn't work in that case</button>
38+
<button onclick="alert(1)">在这种情况下,点击不起作用</button>
3939

4040
</body>
4141
</html>

3-frames-and-windows/06-clickjacking/top-location.view/index.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131

3232
<body>
3333

34-
<p>After a click on the button the visitor gets a "strange" question about whether they want to leave.</p>
34+
<p>点击该按钮后,访问者会收到一条关于他们是否要离开的“奇怪”问题。</p>
3535

36-
<p>Probably they would respond "No", and the iframe protection is hacked.</p>
36+
<p>他们可能会回答“否”,这样就保护了 iframe 不被黑。</p>
3737

38-
<button onclick="attack()">Add a "protected" iframe</button>
38+
<button onclick="attack()">添加一个“受保护的” iframe</button>
3939

4040
</body>
4141
</html>

0 commit comments

Comments
 (0)