W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
跨站腳本(XSS)允許攻擊者將惡意代碼注入到頁(yè)面中。這些代碼可以偷取用戶(hù)數(shù)據(jù) (特別是它們的登錄數(shù)據(jù)),還可以冒充用戶(hù)執(zhí)行操作。它是 Web 上最常見(jiàn)的攻擊方式之一。
為了防范 XSS 攻擊,你必須阻止惡意代碼進(jìn)入 DOM。比如,如果某個(gè)攻擊者能騙你把 <script>
標(biāo)簽插入到 DOM,就可以在你的網(wǎng)站上運(yùn)行任何代碼。 除了 <script>
,攻擊者還可以使用很多 DOM 元素和屬性來(lái)執(zhí)行代碼,比如 <img onerror="...">
、<a href="javascript:...">
。 如果攻擊者所控制的數(shù)據(jù)混進(jìn)了 DOM,就會(huì)導(dǎo)致安全漏洞。
為了系統(tǒng)性的防范 XSS 問(wèn)題,Angular 默認(rèn)把所有值都當(dāng)做不可信任的。 當(dāng)值從模板中以屬性(Property
)、DOM 元素屬性(Attribte
)、CSS 類(lèi)綁定或插值等途徑插入到 DOM 中的時(shí)候, Angular 將對(duì)這些值進(jìn)行無(wú)害化處理(Sanitize
),對(duì)不可信的值進(jìn)行編碼。
Angular 的模板同樣是可執(zhí)行的:模板中的 HTML、Attribute 和綁定表達(dá)式(還沒(méi)有綁定到值的時(shí)候)會(huì)被當(dāng)做可信任的。 這意味著應(yīng)用必須防止把可能被攻擊者控制的值直接編入模板的源碼中。永遠(yuǎn)不要根據(jù)用戶(hù)的輸入和原始模板動(dòng)態(tài)生成模板源碼! 使用離線模板編譯器是防范這類(lèi)“模板注入”漏洞的有效途徑。
無(wú)害化處理會(huì)審查不可信的值,并將它們轉(zhuǎn)換成可以安全插入到 DOM 的形式。多數(shù)情況下,這些值并不會(huì)在處理過(guò)程中發(fā)生任何變化。 無(wú)害化處理的方式取決于所在的環(huán)境:一個(gè)在 CSS 里面無(wú)害的值,可能在 URL 里很危險(xiǎn)。
Angular 定義了四個(gè)安全環(huán)境 - HTML,樣式,URL,和資源 URL:
innerHTML
時(shí)。style
屬性時(shí)使用。URL
屬性時(shí)使用,比如 <a href>
。URL
的值需要作為代碼進(jìn)行加載并執(zhí)行,比如 <script src>
中的 URL
。
Angular 會(huì)對(duì)前三項(xiàng)中種不可信的值進(jìn)行無(wú)害化處理,但不能對(duì)第四種資源 URL
進(jìn)行無(wú)害化,因?yàn)樗鼈兛赡馨魏未a。在開(kāi)發(fā)模式下, 如果在進(jìn)行無(wú)害化處理時(shí)需要被迫改變一個(gè)值,Angular 就會(huì)在控制臺(tái)上輸出一個(gè)警告。
下面的例子綁定了 htmlSnippet 的值,一次把它放進(jìn)插值里,另一次把它綁定到元素的 innerHTML
屬性上。
Path:"src/app/inner-html-binding.component.html" 。
<h3>Binding innerHTML</h3>
<p>Bound value:</p>
<p class="e2e-inner-html-interpolated">{{htmlSnippet}}</p>
<p>Result of binding to innerHTML:</p>
<p class="e2e-inner-html-bound" [innerHTML]="htmlSnippet"></p>
插值的內(nèi)容總會(huì)被編碼 - 其中的 HTML 不會(huì)被解釋?zhuān)詾g覽器會(huì)在元素的文本內(nèi)容中顯示尖括號(hào)。
如果希望這段 HTML 被正常解釋?zhuān)捅仨毥壎ǖ揭粋€(gè) HTML 屬性上,比如 innerHTML
。但是如果把一個(gè)可能被攻擊者控制的值綁定到 innerHTML
就會(huì)導(dǎo)致 XSS 漏洞。 比如,包含在 <script>
標(biāo)簽的代碼就會(huì)被執(zhí)行:
Path:"src/app/inner-html-binding.component.ts (class)" 。
export class InnerHtmlBindingComponent {
// For example, a user/attacker-controlled value from a URL.
htmlSnippet = 'Template <script>alert("0wned")</script> <b>Syntax</b>';
}
Angular 認(rèn)為這些值是不安全的,并自動(dòng)進(jìn)行無(wú)害化處理。它會(huì)移除 <script>
標(biāo)簽,但保留安全的內(nèi)容,比如該片段中的 <b>
元素。
瀏覽器內(nèi)置的 DOM API 不會(huì)自動(dòng)保護(hù)你免受安全漏洞的侵害。比如 document
、通過(guò) ElementRef
拿到的節(jié)點(diǎn)和很多第三方 API,都可能包含不安全的方法。如果你使用能操縱 DOM 的其它庫(kù),也同樣無(wú)法借助像 Angular 插值那樣的自動(dòng)清理功能。 所以,要避免直接和 DOM 打交道,而是盡可能使用 Angular 模板。
瀏覽器內(nèi)置的 DOM API 不會(huì)自動(dòng)針對(duì)安全漏洞進(jìn)行防護(hù)。比如,document
(它可以通過(guò) ElementRef
訪問(wèn))以及其它第三方 API 都可能包含不安全的方法。 要避免直接與 DOM 交互,只要可能,就盡量使用 Angular 模板。
內(nèi)容安全策略(CSP) 是用來(lái)防范 XSS 的縱深防御技術(shù)。 要打開(kāi) CSP,請(qǐng)配置你的 Web 服務(wù)器,讓它返回合適的 HTTP 頭 Content_Security_Policy
。 要了解關(guān)于內(nèi)容安全策略的更多信息,請(qǐng)參閱 HTML5Rocks 上的內(nèi)容安全策略簡(jiǎn)介。
離線模板編譯器阻止了一整套被稱(chēng)為“模板注入”的漏洞,并能顯著增強(qiáng)應(yīng)用程序的性能。盡量在產(chǎn)品發(fā)布時(shí)使用離線模板編譯器, 而不要?jiǎng)討B(tài)生成模板(比如在代碼中拼接字符串生成模板)。由于 Angular 會(huì)信任模板本身的代碼,所以,動(dòng)態(tài)生成的模板 —— 特別是包含用戶(hù)數(shù)據(jù)的模板 —— 會(huì)繞過(guò) Angular 自帶的保護(hù)機(jī)制。 要了解如何用安全的方式動(dòng)態(tài)創(chuàng)建表單,請(qǐng)參見(jiàn) 構(gòu)建動(dòng)態(tài)表單 一章。
服務(wù)器端構(gòu)造的 HTML 很容易受到注入攻擊。當(dāng)需要在服務(wù)器端生成 HTML 時(shí)(比如 Angular 應(yīng)用的初始頁(yè)面), 務(wù)必使用一個(gè)能夠自動(dòng)進(jìn)行無(wú)害化處理以防范 XSS 漏洞的后端模板語(yǔ)言。不要在服務(wù)器端使用模板語(yǔ)言生成 Angular 模板, 這樣會(huì)帶來(lái)很高的 “模板注入” 風(fēng)險(xiǎn)。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話(huà):173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: