Skip to content

Commit 9f0ef96

Browse files
JinjiangJustineo
andauthored
Update (vuejs#1042)
* updated from afe7421c to 34df294b * translated new part in components.md * translated 1st half of security.md * translated 2nd half of security.md * kept writing-guide.md original * Update components.md * Update security.md * Apply suggestions from code review Co-Authored-By: GU Yiling <[email protected]> * Update security.md * Apply suggestions from code review Co-Authored-By: GU Yiling <[email protected]> * Update security.md Co-authored-by: GU Yiling <[email protected]>
1 parent 91a7eac commit 9f0ef96

34 files changed

+469
-47
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@
2929
"hoek": "^6.1.2",
3030
"request": "^2.85.0"
3131
}
32-
}
32+
}

pre-deploy.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Promise.all([
3939
installation
4040
.replace(/vue_version: .*/, 'vue_version: ' + version)
4141
.replace(/gz_size:.*/g, `gz_size: "${prodSize}"`)
42-
.replace(/\/vue@[\d\.]+\//g, `/vue@${version}/`)
42+
.replace(/\/vue@[\d\.]+/g, `/vue@${version}`)
4343
)
4444
console.log(`\nSuccessfully updated Vue version and gzip file size.\n`)
4545
}).catch(err => {

src/images/oxford-comma.jpg

217 KB
Loading

src/resources/partners.md

+91-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ partners_list:
4444
description:
4545
"Modus Create is a digital product agency that supports clients with business and product strategy consulting, customer experience, cloud services, and Agile software delivery. Our official partnerships with Atlassian, AWS, InVision, Cloudflare, GitHub, Ionic Framework, and Vue.js reinforce our proven results with digital transformation with organizations from startups to the Fortune 100."
4646
proficiencies:
47-
- VueJs
47+
- name: Vue.js
48+
url: https://moduscreate.com/partners/vue/?utm_source=Vue&utm_medium=Partner-Page&utm_campaign=Vue_partnerpage
4849
- name: AWS
4950
url: https://moduscreate.com/partners/aws/?utm_source=Vue&utm_medium=Partner-Page&utm_campaign=Vue_partnerpage
5051
- name: Atlassian
@@ -84,4 +85,93 @@ partners_list:
8485
name: YouTube
8586
class: youtube
8687
url: 'https://www.youtube.com/moduscreate'
88+
-
89+
name: Monterail
90+
logo: Monterail.png
91+
description:
92+
"Monterail is a full-service software development company with 100+ experts on board delivering meaningful software for start-ups, SMBs and enterprises. We build for the Web with Ruby on Rails, Python, JavaScript, and Agile. We guarantee this: a product so qualitative and aligned with your vision, you’ll swear it was built in-house."
93+
proficiencies:
94+
- name: VueJs
95+
url: https://hi.monterail.co/2NqPUa6
96+
- name: Ruby on Rails
97+
url: https://hi.monterail.co/31RvfBm
98+
- name: Javascript
99+
url: https://hi.monterail.co/34cWQhR
100+
- name: Python
101+
url: https://hi.monterail.co/2MXHLeb
102+
- name: Services
103+
url: https://www.monterail.com/services
104+
- name: Projects
105+
url: https://www.monterail.com/projects
106+
location: Wrocław, Poland
107+
languages:
108+
- English
109+
- Polish
110+
url_text: www.monterail.com
111+
url_link: www.monterail.com/?utm_campaign=Vue.js&utm_source=partner-list
112+
hire_url: www.monterail.com/contact
113+
114+
social_links:
115+
-
116+
name: Github
117+
class: github
118+
url: 'https://github.com/monterail'
119+
-
120+
name: Linkedin
121+
class: linkedin
122+
url: 'https://www.linkedin.com/company/monterail'
123+
-
124+
name: Facebook
125+
class: facebook
126+
url: 'https://www.facebook.com/monterail/'
127+
-
128+
name: Twitter
129+
class: twitter
130+
url: 'https://twitter.com/monterail'
131+
-
132+
name: Instagram
133+
class: instagram
134+
url: 'https://www.instagram.com/monterail/'
135+
-
136+
name: Rangle
137+
logo: https://res.cloudinary.com/rangle/image/upload/q_auto,f_auto/vuejs.org/rangle_black_lockup_n6q48z.png
138+
description:
139+
"Rangle is a global digital consultancy that helps ambitious organizations outperform the competition in the most demanding markets. We work closely with our clients as one team to imagine, design, and deliver human-centered digital experiences that create lasting results and real business value. Anchored in innovation and lean startup best-practices, our unique delivery and partnership model is purposed-built to this task."
140+
proficiencies:
141+
- name: Building Products
142+
url: https://rangle.io/#build-a-product/?utm_source=referral&utm_medium=partner&utm_campaign=vue-partners
143+
- name: Improving Experiences
144+
url: https://rangle.io/#improve-an-experience/?utm_source=referral&utm_medium=partner&utm_campaign=vue-partners
145+
- name: Training & Coaching
146+
url: https://rangle.io/#level-up-your-team/?utm_source=referral&utm_medium=partner&utm_campaign=vue-partners
147+
- name: Agile Transformation
148+
url: https://rangle.io/#adopt-agile-delivery/?utm_source=referral&utm_medium=partner&utm_campaign=vue-partners
149+
- name: Business Transformation
150+
url: https://rangle.io/#transform-your-business/?utm_source=referral&utm_medium=partner&utm_campaign=vue-partners
151+
location: Toronto, ON, CA Atlanta, GA, USA Amsterdam, Netherlands Tokyo, Japan
152+
languages:
153+
- English
154+
- French
155+
- Dutch
156+
url_text: rangle.io
157+
url_link: rangle.io/?utm_source=referral&utm_medium=partner&utm_campaign=vue-partners
158+
hire_url: rangle.io/contact-us/?utm_source=referral&utm_medium=partner&utm_campaign=vue-partners
159+
160+
social_links:
161+
-
162+
name: GitHub
163+
class: github
164+
url: 'https://github.com/rangle'
165+
-
166+
name: LinkedIn
167+
class: linkedin
168+
url: 'https://www.linkedin.com/company/rangle/'
169+
-
170+
name: Twitter
171+
class: twitter
172+
url: 'https://twitter.com/rangleio'
173+
-
174+
name: Instagram
175+
class: instagram
176+
url: 'https://www.instagram.com/rangleio/?hl=en'
87177
---

src/resources/themes.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ order: 804
2020
<h2 :id="partner.name">{{partner.name}}</h2>
2121
<blockquote class="theme-partner-description" v-html="partnerDescription"></blockquote>
2222
<div class="themes-grid">
23-
<div v-for="product in partner.products" :key="product.name" class="item-preview">
23+
<div v-for="product in partner.products" :key="product.url" class="item-preview">
2424
<a class="item-preview-img" :href="product.url" rel="sponsored">
2525
<img :src="product.image" :alt="`${product.name} - ${product.description}`" loading="lazy">
2626
</a>

src/v2/cookbook/adding-instance-properties.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ new Vue({
5757
})
5858
```
5959

60-
日志中会先出现 `"My App"`,然后出现 `"The name of some other app"`,因为 `this.appName` 在实例被创建之后被 `data` [覆写了](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch5.md)。我们通过 `$` 为实例属性设置作用域来避免这种事情发生。你还可以根据你的喜好使用自己的约定,诸如 `$_appName``ΩappName`,来避免和插件或未来的插件相冲突。
60+
日志中会先出现 `"My App"`,然后出现 `"The name of some other app"`,因为 `this.appName` 在实例被创建之后被 `data` [覆写了](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/objects-classes/ch5.md)。我们通过 `$` 为实例属性设置作用域来避免这种事情发生。你还可以根据你的喜好使用自己的约定,诸如 `$_appName``ΩappName`,来避免和插件或未来的插件相冲突。
6161

6262
## 真实的示例:通过 axios 替换 Vue Resource
6363

src/v2/cookbook/unit-testing-vue-components.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,11 @@ import Foo from './Foo.vue'
150150
describe('Foo', () => {
151151
it('renders a message and responds correctly to user input', () => {
152152
const wrapper = shallowMount(Foo, {
153-
data: {
154-
message: 'Hello World',
155-
username: ''
153+
data() {
154+
return {
155+
message: 'Hello World',
156+
username: ''
157+
}
156158
}
157159
})
158160

src/v2/guide/comparison.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -226,5 +226,5 @@ Polymer 是另一个由谷歌赞助的项目,事实上也是 Vue 的一个灵
226226

227227
Riot 3.0 提供了一个类似于基于组件的开发模型 (在 Riot 中称之为 Tag),它提供了小巧精美的 API。Riot 和 Vue 在设计理念上可能有许多相似处。尽管相比 Riot ,Vue 要显得重一点,Vue 还是有很多显著优势的:
228228

229-
- 更好的性能。Riot 使用了 [遍历 DOM 树](http://riotjs.com/compare/#virtual-dom-vs-expressions-binding) 而不是虚拟 DOM,但实际上用的还是脏检查机制,因此和 AngularJS 患有相同的性能问题。
229+
- 更好的性能。Riot 使用了 [遍历 DOM 树](https://v3.riotjs.now.sh/compare/#virtual-dom-vs-expressions-binding) 而不是虚拟 DOM,但实际上用的还是脏检查机制,因此和 AngularJS 患有相同的性能问题。
230230
- 更多成熟工具的支持。Vue 提供官方支持 [webpack](https://github.com/vuejs/vue-loader)[Browserify](https://github.com/vuejs/vueify),而 Riot 是依靠社区来建立集成系统。

src/v2/guide/components-edge-cases.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ methods: {
233233
}
234234
```
235235

236-
查阅[这个 fiddle](https://jsfiddle.net/chrisvfritz/1Leb7up8/) 可以了解到完整的代码。注意,即便如此,如果你发现自己不得不在单个组件里做很多建立和清理的工作,最好的方式通常还是创建更多的模块化组件。在这个例子中,我们推荐创建一个可复用的 `<input-datepicker>` 组件。
236+
查阅[这个 fiddle](https://jsfiddle.net/09jvu65m/) 可以了解到完整的代码。注意,即便如此,如果你发现自己不得不在单个组件里做很多建立和清理的工作,最好的方式通常还是创建更多的模块化组件。在这个例子中,我们推荐创建一个可复用的 `<input-datepicker>` 组件。
237237

238238
想了解更多程序化侦听器的内容,请查阅[实例方法 / 事件](https://cn.vuejs.org/v2/api/#实例方法-事件)相关的 API。
239239

src/v2/guide/components.md

+2
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,8 @@ new Vue({
603603

604604
你可以在[这里](https://jsfiddle.net/chrisvfritz/o3nycadu/)查阅并体验完整的代码,或在[这个版本](https://jsfiddle.net/chrisvfritz/b2qj69o1/)了解绑定组件选项对象,而不是已注册组件名的示例。
605605

606+
请留意,这个 attribute 可以用于常规 HTML 元素,但这些元素将被视为组件,这意味着所有的 attribute **都会作为 DOM attribute 被绑定**。对于像 `value` 这样的 property,若想让其如预期般工作,你需要使用 [`.prop` 修饰器](../api/#v-bind)
607+
606608
到目前为止,关于动态组件你需要了解的大概就这些了,如果你阅读完本页内容并掌握了它的内容,我们会推荐你再回来把[动态和异步组件](components-dynamic-async.html)读完。
607609

608610
## 解析 DOM 模板时的注意事项

src/v2/guide/deployment.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ NODE_ENV=production browserify -g envify -e main.js | uglifyjs -c -m > build.js
9494

9595
#### Rollup
9696

97-
使用 [rollup-plugin-replace](https://github.com/rollup/rollup-plugin-replace)
97+
使用 [@rollup/plugin-replace](https://github.com/rollup/plugins/tree/master/packages/replace)
9898

9999
``` js
100-
const replace = require('rollup-plugin-replace')
100+
const replace = require('@rollup/plugin-replace')
101101
rollup({
102102
// ...
103103
plugins: [

src/v2/guide/events.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ new Vue({
158158
methods: {
159159
warn: function (message, event) {
160160
// 现在我们可以访问原生事件对象
161-
if (event) event.preventDefault()
161+
if (event) {
162+
event.preventDefault()
163+
}
162164
alert(message)
163165
}
164166
}

src/v2/guide/join.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ Vue.js 的社区正在急速增长中,如果你正在阅读本文,这说明
4949

5050
### 翻译文档
5151

52-
Vue 已经在全球范围内传播开来,核心团队成员甚至来自至少 6 个时区。[论坛](https://forum.vuejs.org/) 已有 7 种语言,数字还在持续增长。我们许多文档都有[积极维护的翻译](https://github.com/vuejs?utf8=%E2%9C%93&query=vuejs.org)。我们非常为 Vue 的国际影响力骄傲,但我们还能做得更好。
52+
Vue 已经在全球范围内传播开来,核心团队成员甚至来自至少 6 个时区。[论坛](https://forum.vuejs.org/) 已有 7 种语言,数字还在持续增长。我们许多文档都有[积极维护的翻译](https://github.com/vuejs?utf8=%E2%9C%93&q=vuejs.org)。我们非常为 Vue 的国际影响力骄傲,但我们还能做得更好。
5353

5454
我希望现在你正在使用你的首选语言阅读这篇文档,如果不是,你愿意帮助我们翻译它吗?
5555

src/v2/guide/security.md

+172
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
---
2+
title: 安全
3+
type: guide
4+
order: 504
5+
---
6+
7+
## 报告安全漏洞
8+
9+
当我们收到一个安全漏洞报告,将给予其最高优先级,并由全职贡献者停下手中的工作处理此事。如发现任何安全漏洞,请邮件给 [[email protected]](mailto:[email protected])
10+
11+
虽然发现新安全漏洞是比较罕见的事,我们仍推荐始终使用最新版本的 Vue 及其官方的周边库,以确保应用尽可能安全。
12+
13+
## Vue 的安全措施
14+
15+
### HTML 内容
16+
17+
不论使用模板还是渲染函数,内容都会被自动转义。也就是说对于这份模板:
18+
19+
```html
20+
<h1>{{ userProvidedString }}</h1>
21+
```
22+
23+
如果 `userProvidedString` 包含了:
24+
25+
```js
26+
'<script>alert("hi")</script>'
27+
```
28+
29+
则它会被转义成为如下 HTML:
30+
31+
```html
32+
&lt;script&gt;alert(&quot;hi&quot;)&lt;/script&gt;
33+
```
34+
35+
因此避免了脚本注入。该转义通过诸如 `textContent` 的浏览器原生的 API 完成,所以除非浏览器本身存在安全漏洞,否则不会存在安全漏洞。
36+
37+
### Attribute 绑定
38+
39+
同样地,动态 attribute 绑定也会自动被转义。也就是说对于这份模板:
40+
41+
```html
42+
<h1 v-bind:title="userProvidedString">
43+
hello
44+
</h1>
45+
```
46+
47+
如果 `userProvidedString` 包含了:
48+
49+
```js
50+
'" onclick="alert(\'hi\')'
51+
```
52+
53+
则它会被转义成为如下 HTML:
54+
55+
```html
56+
&quot; onclick=&quot;alert('hi')
57+
```
58+
59+
因此避免了通过闭合 `title` attribute 而注入新的任意 HTML。该转义通过诸如 `setAttribute` 的浏览器原生的 API 完成,所以除非浏览器本身存在安全漏洞,否则不会存在安全漏洞。
60+
61+
## 潜在危险
62+
63+
在任何 web 应用中,允许未过滤的用户提供的内容成为 HTML、CSS 或 JavaScript 都有潜在的危险,因此应当尽可能避免。尽管如此,有些情况下的风险是可接受的。
64+
65+
例如,类似 CodePen 和 JSFiddle 这样的服务允许用户提供的内容直接被执行,但这是预期行为,且在 iframe 中以某种程度被隔离在沙箱中。当一些重要功能不可避免地依赖引入一些安全漏洞,您的团队需要自行在该功能的重要性和漏洞带来的最坏场景间进行权衡。
66+
67+
### 注入 HTML
68+
69+
如你之前学到的,Vue 会自动转义 HTML 内容,以避免向应用意外注入可执行的 HTML。然而,某些情况下你清楚这些 HTML 是安全的,这时你可以显式地渲染 HTML 内容:
70+
71+
- 使用模板:
72+
```html
73+
<div v-html="userProvidedHtml"></div>
74+
```
75+
76+
- 使用渲染函数:
77+
```js
78+
h('div', {
79+
domProps: {
80+
innerHTML: this.userProvidedHtml
81+
}
82+
})
83+
```
84+
85+
- 使用基于 JSX 的渲染函数:
86+
```jsx
87+
<div domPropsInnerHTML={this.userProvidedHtml}></div>
88+
```
89+
90+
<p class="tip">注意永远不要认为用户提供的 HTML 是 100% 安全的,除非在一个 iframe 沙盒或应用中只有这些 HTML 的作者可以看到的那部分。除此之外,允许用户撰写其自己的 Vue 模板会带来类似的危险。</p>
91+
92+
### 注入 URL
93+
94+
在类似这样的 URL 中:
95+
96+
```html
97+
<a v-bind:href="userProvidedUrl">
98+
click me
99+
</a>
100+
```
101+
102+
如果没有对该 URL 进行“过滤”以防止通过 javascript: 来执行 JavaScript,则会有潜在的安全问题。有一些库如 [sanitize-url](https://www.npmjs.com/package/@braintree/sanitize-url) 可以帮助你做这件事,但请注意:
103+
104+
<p class="tip">只要你是在前端进行 URL 过滤,那么就已经有安全问题了。用户提供的 URL 永远需要通过后端在入库之前进行过滤。然后这个问题就会在*每个*客户端连接该 API 是被阻止,包括原生移动应用。还要注意,甚至对于被过滤过的 URL,Vue 仍无法帮助你保证它们会跳转到安全的目的地。</p>
105+
106+
### 注入样式
107+
108+
来看这个示例:
109+
110+
```html
111+
<a
112+
v-bind:href="sanitizedUrl"
113+
v-bind:style="userProvidedStyles"
114+
>
115+
click me
116+
</a>
117+
```
118+
119+
让我们假设 `sanitizedUrl` 已经被过滤过了,所以这已经是一个完全真实的 URL 且没有 JavaScript。但通过 `userProvidedStyles`,恶意用户仍可以提供 CSS 来进行“点击诈骗”,例如将链接的样式设置为一个透明的方框覆盖在“登录”按钮之上。然后再把 `https://user-controlled-website.com/` 做成你的应用的登录页的样子,它们就可能获取一个用户真实的登录信息。
120+
121+
你可以想象到,允许用户为一个 `<style>` 元素提供内容,将产生甚至更严重的安全漏洞,以使得用户完全控制整个页面的样式。这就是为什么要在模板内避免渲染 style 标签,例如:
122+
123+
```html
124+
<style>{{ userProvidedStyles }}</style>
125+
```
126+
127+
为了确保用户完全远离点击诈骗,我们推荐只允许在一个 iframe 沙盒内进行 CSS 的完全控制。或让用户通过一个样式绑定来控制,我们推荐使用其[对象语法](class-and-style.html#对象语法-1)且只允许用户提供特定的可以安全控制的 property 的值。例如:
128+
129+
```html
130+
<a
131+
v-bind:href="sanitizedUrl"
132+
v-bind:style="{
133+
color: userProvidedColor,
134+
background: userProvidedBackground
135+
}"
136+
>
137+
click me
138+
</a>
139+
```
140+
141+
### 注入 JavaScript
142+
143+
我们强烈不鼓励使用 Vue 渲染 `<script>` 元素,因为模板和渲染函数永远不应该产生副作用。然而,这并不是唯一包含可能在运行时会被视为 JavaScript 的字符串。
144+
145+
每个 HTML 元素都有接受 JavaScript 字符串作为其值的 attribute,如 `onclick``onfocus``onmouseenter`。将用户提供的 JavaScript 绑定到它们任意当中都是一个潜在的安全风险,因此应该避免。
146+
147+
<p class="tip">请注意,永远不要认为用户提供的 JavaScript 是 100% 安全的,除非在一个 iframe 沙盒或应用中只有这些 JavaScript 的作者可以看到的那部分。</p>
148+
149+
有的时候我们会收到在 Vue 模板中可以产生跨站脚本攻击 (XSS) 的安全漏洞报告。一般情况下,我们不会将这样的案例视为真正的安全漏洞,因为从以下两个可能允许 XSS 的场景看,不存在可行的办法来保护开发者:
150+
151+
1. 开发者显式地要求 Vue 将用户提供的、未经过滤的内容作为 Vue 模板进行渲染。这是无法避免的不安全,Vue 没有办法知道其源头。
152+
153+
2. 开发者向 Vue 挂载包含服务端渲染或用户提供的内容的 HTML 的整个页面。这实质上和问题 \#1 是相同的,但是有的时候开发者可能没有意识到。这会使得攻击者提供作为普通 HTML 安全但对于 Vue 模板不安全的 HTML 以导致安全漏洞。最佳实践是永远不要向 Vue 挂载可能包含服务端渲染或用户提供的内容。
154+
155+
## 最佳实践
156+
157+
通用的规则是只要允许执行未过滤的用户提供的内容 (不论作为 HTML、JavaScript 甚至 CSS),你就可能令自己处于被攻击的境地。这些建议实际上不论使用 Vue 还是别的框架甚至不使用框架,都是成立的。
158+
159+
除了上述关于[潜在危险](#潜在危险)的建议,我们也推荐自行熟悉以下资料:
160+
161+
- [HTML5 Security Cheat Sheet](https://html5sec.org/)
162+
- [OWASP's Cross Site Scripting (XSS) Prevention Cheat Sheet](https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet)
163+
164+
然后利用学到的知识,对那些包含了第三方组件或通过其它方式影响渲染到 DOM 的内容的依赖的源代码进行重新审查,以发现潜在的危险模式。
165+
166+
## 后端协作
167+
168+
HTTP 安全漏洞,诸如伪造跨站请求 (CSRF/XSRF) 和跨站脚本注入 (XSSI),都是后端重点关注的方向,因此并不是 Vue 所担心的。尽管如此,和后端团队交流学习如何和他们的 API 最好地进行交互,例如在表单提交时提交 CSRF token,永远是件好事。
169+
170+
## 服务端渲染 (SSR)
171+
172+
使用 SSR 时存在额外的安全考量,因此请确认遵循[我们的 SSR 文档](https://ssr.vuejs.org/zh/)中概括出的最佳实践以避免安全漏洞。

0 commit comments

Comments
 (0)