AngularDart 4.0 高級-安全

本頁面介紹了Angular內置的針對常見的Web應用程序漏洞和跨站腳本攻擊等攻擊的內置保護。 它不包括應用程序級別的安全性,如身份驗證(此用戶是誰?)和受權(此用戶能夠作什麼?)。javascript

有關下述攻擊和緩解的更多信息,請參閱OWASP指南項目php

試試本頁面顯示的代碼的實例(查看源代碼)。html

報告漏洞

要報告Angular自己的漏洞,請發送電子郵件至security@angular.iojava

有關Google如何處理安全問題的更多信息,請參閱Google的安全理念git

最佳實踐

  • 隨時關注最新的Angular庫版本。 咱們會按期更新Angular庫,這些更新可能會修復先前版本中發現的安全缺陷。 檢查角度更改日誌中的安全相關更新。
  • 不要修改您的Angular副本。 Angular的私人定製版本傾向於落後於當前版本,可能不包含重要的安全修復和加強功能。 相反,與社區分享你的Angular改進,並提出請求。
  • 儘量避免在文檔中標記爲「安全風險」的Angular API。有關更多信息,請參閱本頁面的信任安全值部分。

防止跨站點腳本(XSS)

跨站點腳本(XSS)使攻擊者可以將惡意代碼注入到網頁中。 例如,此類代碼能夠竊取用戶數據(特別是登陸數據)或執行操做以模擬用戶。 這是網絡上最多見的攻擊之一。github

要阻止XSS攻擊,您必須防止惡意代碼進入DOM(文檔對象模型)。 例如,若是攻擊者能夠誘使你在DOM中插入一個<script>標籤,他們能夠在你的網站上運行任意代碼。 攻擊並不侷限於<script>標記 - DOM中的許多元素和屬性容許執行代碼,例如<img onerror =「...」><a href="javascript:...">。 若是攻擊者控制的數據進入DOM,則預計存在安全漏洞。web

Angular的跨站腳本安全模型

要系統地阻止XSS錯誤,Angular默認將全部值視爲不可信。 當一個值經過屬性,屬性,樣式,類綁定或插值從模板插入到DOM中時,Angular會清理並轉義不受信任的值。api

Angular模板與可執行代碼相同:模板中的HTML,屬性和綁定表達式(但不包括綁定的值)是值得信賴的。 這意味着應用程序必須防止攻擊者能夠控制的值永遠不會變成模板的源代碼。 切勿經過鏈接用戶輸入和模板來生成模板源代碼。 爲了防止這些漏洞,請使用脫機模板編譯器,也稱爲模板注入。瀏覽器

消毒和安全環境

消毒是對不可信值的檢查,將其轉化爲能夠安全插入DOM的值。 在許多狀況下,消毒不會完全改變值。消毒取決於上下文:CSS中的無害值在URL中多是危險的。安全

Angular定義瞭如下安全上下文:

  • 將值解釋爲HTML時使用HTML,例如綁定到innerHtml時。
  • 將CSS綁定到style屬性時使用Style
  • URL用於URL屬性,例如<a href>
  • 資源URL是一個將要做爲代碼加載和執行的URL,例如,在<script src>中。

Angular爲HTML,Style和URL清理不可信的值; 清理資源URL是不可能的,由於它們包含任意代碼。 在開發模式中,Angular在消毒過程當中必須更改一個值時纔會打印控制檯警告。

消毒示例

如下模板將htmlSnippet的值綁定到一個元素的內容,並將其綁定到元素的innerHTML屬性一次:

lib/src/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>

內插內容老是被轉義 - HTML不被解釋,瀏覽器在元素的文本內容中顯示尖括號。

要解釋HTML,請將其綁定到諸如innerHTML之類的HTML屬性。 可是將攻擊者可能控制的值綁定到innerHTML中一般會致使XSS漏洞。 例如,包含在<script>標籤中的代碼被執行:

lib/src/inner_html_binding_component.dart (class)

class InnerHtmlBindingComponent {
  // For example, a user/attacker-controlled value from a URL.
  var htmlSnippet = 'Template <script>alert("0wned")</script> <b>Syntax</b>';
}

Angular認爲這個值是不安全的,並自動清理它,這會移除<script>元素,但會保留文本和<b>元素等安全內容。

避免直接使用DOM API

內置的瀏覽器DOM API不會自動保護您免受安全漏洞的侵害。 例如,文檔和許多第三方API包含不安全的方法。 避免直接與DOM進行交互,而應儘量使用Angular模板。

內容安全策略

內容安全策略(CSP)是一種防護XSS的縱深防護技術。 要啓用CSP,請將Web服務器配置爲返回適當的Content-Security-Policy HTTP標頭。 請閱讀Web基礎知識網站上的內容安全策略

使用脫機模板編譯器

脫機模板編譯器能夠防止模板注入整個類的漏洞,並大大提升應用程序性能。在生產部署中使用脫機模板編譯器; 不要動態生成模板。 Angular信任模板代碼,所以生成模板(特別是包含用戶數據的模板)繞開了Angular的內置保護。

服務器端XSS保護

在服務器上構建的HTML容易受到注入攻擊。 將模板代碼注入Angular應用程序與將可執行代碼注入應用程序相同:它使攻擊者能夠徹底控制應用程序。 爲防止出現這種狀況,請使用自動轉義值的模板語言來防止服務器上的XSS漏洞。 不要使用模板語言在服務器端生成Angular模板; 這樣作帶來了引入模板注入漏洞的高風險。

信任安全值

有時應用程序真的須要包含可執行代碼,從某個URL顯示<iframe>,或構建潛在的危險URL。 爲了防止在這些狀況下出現自動消毒,您能夠告訴Angular您檢查了一個值,檢查它是如何生成的,並確保它始終是安全的。 不過要當心。 若是您信任可能具備惡意的值,則會在您的應用中引入安全漏洞。 若有疑問,請找專業的安全審查員。

要將值標記爲可信,請注入DomSanitizationService並調用如下方法之一:

  • bypassSecurityTrustHtml
  • bypassSecurityTrustScript
  • bypassSecurityTrustStyle
  • bypassSecurityTrustUrl
  • bypassSecurityTrustResourceUrl

請記住,值是否安全取決於上下文,所以請選擇正確的上下文以用於您預期的值使用。 想象一下,如下模板須要將URL綁定到javascript:alert(...)調用:

lib/src/bypass_security_component.html (URL)

<h4>A untrusted URL:</h4>
<p><a class="e2e-dangerous-url" [href]="dangerousUrl">Click me</a></p>
<h4>A trusted URL:</h4>
<p><a class="e2e-trusted-url" [href]="trustedUrl">Click me</a></p>

一般,Angular會自動清理URL,禁用危險代碼,而且在開發模式下,將此操做記錄到控制檯。 爲防止出現這種狀況,請使用bypassSecurityTrustUrl調用將URL值標記爲受信任的URL:

lib/src/bypass_security_component.dart (excerpt)

BypassSecurityComponent(this.sanitizer) {
  // javascript: URLs are dangerous if attacker controlled.
  // Angular sanitizes them in data binding, but we can
  // explicitly tell Angular to trust this value:
  dangerousUrl = 'javascript:alert("Hi there")';
  trustedUrl = sanitizer.bypassSecurityTrustUrl('javascript:alert("Hi there")');

若是您須要將用戶輸入轉換爲可信值,請使用控制器方法。如下模板容許用戶輸入YouTube視頻ID並將相應的視頻加載到<iframe>中。<iframe src>屬性是資源URL安全上下文,由於不受信任的源也能夠,例如在用戶不知情可私自執行文件下載。 因此調用控制器上的一個方法來構建一個可信的視頻URL,這會致使Angular容許綁定到<iframe src>中:

lib/src/bypass_security_component.html (iframe)

<h4>Resource URL:</h4>
<p>Showing: {{dangerousVideoUrl}}</p>
<p>Trusted:</p>
<iframe class="e2e-iframe-trusted-src" width="640" height="390" [src]="videoUrl"></iframe>
<p>Untrusted:</p>
<iframe class="e2e-iframe-untrusted-src" width="640" height="390" [src]="dangerousVideoUrl"></iframe>

lib/src/bypass_security_component.dart (excerpt)

void updateVideoUrl(String id) {
  // Appending an ID to a YouTube URL is safe.
  // Always make sure to construct SafeValue objects as
  // close as possible to the input data, so
  // that it's easier to check if the value is safe.
  dangerousVideoUrl = 'https://www.youtube.com/embed/$id';
  videoUrl = sanitizer.bypassSecurityTrustResourceUrl(dangerousVideoUrl);
}

審計Angular應用程序

Angular應用程序必須遵循與常規Web應用程序相同的安全原則,而且必須進行審覈。 應該在安全審查中審覈的特定於Angular的API(例如bypassSecurityTrust方法)在文檔中標記爲安全敏感。

相關文章
相關標籤/搜索