本页面介绍了Angular内置的针对常见的Web应用程序漏洞和跨站脚本攻击等攻击的内置保护。 它不包括应用程序级别的安全性,如身份验证(此用户是谁?)和受权(此用户能够作什么?)。javascript
有关下述攻击和缓解的更多信息,请参阅OWASP指南项目。php
要报告Angular自己的漏洞,请发送电子邮件至security@angular.io。java
有关Google如何处理安全问题的更多信息,请参阅Google的安全理念。git
跨站点脚本(XSS)使攻击者可以将恶意代码注入到网页中。 例如,此类代码能够窃取用户数据(特别是登陆数据)或执行操做以模拟用户。 这是网络上最多见的攻击之一。github
要阻止XSS攻击,您必须防止恶意代码进入DOM(文档对象模型)。 例如,若是攻击者能够诱使你在DOM中插入一个<script>标签,他们能够在你的网站上运行任意代码。 攻击并不局限于<script>标记 - DOM中的许多元素和属性容许执行代码,例如<img onerror =“...”>和<a href="javascript:...">。 若是攻击者控制的数据进入DOM,则预计存在安全漏洞。web
要系统地阻止XSS错误,Angular默认将全部值视为不可信。 当一个值经过属性,属性,样式,类绑定或插值从模板插入到DOM中时,Angular会清理并转义不受信任的值。api
Angular模板与可执行代码相同:模板中的HTML,属性和绑定表达式(但不包括绑定的值)是值得信赖的。 这意味着应用程序必须防止攻击者能够控制的值永远不会变成模板的源代码。 切勿经过链接用户输入和模板来生成模板源代码。 为了防止这些漏洞,请使用脱机模板编译器,也称为模板注入。浏览器
消毒是对不可信值的检查,将其转化为能够安全插入DOM的值。 在许多状况下,消毒不会完全改变值。消毒取决于上下文:CSS中的无害值在URL中多是危险的。安全
Angular定义了如下安全上下文:
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不会自动保护您免受安全漏洞的侵害。 例如,文档和许多第三方API包含不安全的方法。 避免直接与DOM进行交互,而应尽量使用Angular模板。
内容安全策略(CSP)是一种防护XSS的纵深防护技术。 要启用CSP,请将Web服务器配置为返回适当的Content-Security-Policy HTTP标头。 请阅读Web基础知识网站上的内容安全策略。
脱机模板编译器能够防止模板注入整个类的漏洞,并大大提升应用程序性能。在生产部署中使用脱机模板编译器; 不要动态生成模板。 Angular信任模板代码,所以生成模板(特别是包含用户数据的模板)绕开了Angular的内置保护。
在服务器上构建的HTML容易受到注入攻击。 将模板代码注入Angular应用程序与将可执行代码注入应用程序相同:它使攻击者能够彻底控制应用程序。 为防止出现这种状况,请使用自动转义值的模板语言来防止服务器上的XSS漏洞。 不要使用模板语言在服务器端生成Angular模板; 这样作带来了引入模板注入漏洞的高风险。
有时应用程序真的须要包含可执行代码,从某个URL显示<iframe>,或构建潜在的危险URL。 为了防止在这些状况下出现自动消毒,您能够告诉Angular您检查了一个值,检查它是如何生成的,并确保它始终是安全的。 不过要当心。 若是您信任可能具备恶意的值,则会在您的应用中引入安全漏洞。 若有疑问,请找专业的安全审查员。
要将值标记为可信,请注入DomSanitizationService并调用如下方法之一:
请记住,值是否安全取决于上下文,所以请选择正确的上下文以用于您预期的值使用。 想象一下,如下模板须要将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应用程序必须遵循与常规Web应用程序相同的安全原则,而且必须进行审核。 应该在安全审查中审核的特定于Angular的API(例如bypassSecurityTrust方法)在文档中标记为安全敏感。