docs(security): hide TOC for Dart; other minor copyedits (#3017)

This commit is contained in:
Patrice Chalin 2016-12-20 14:14:58 -08:00 committed by Filipe Silva
parent a74f8fb3b1
commit 0dfd37e5a9
3 changed files with 132 additions and 129 deletions

View File

@ -1,20 +1,17 @@
<!--#docregion -->
<h3>Bypass Security Component</h3>
<!--#docregion dangerous-url -->
<!--#docregion URL -->
<h4>An 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>
<!--#enddocregion dangerous-url -->
<!--#enddocregion URL -->
<!--#docregion iframe-videoid -->
<!--#docregion iframe -->
<h4>Resource URL:</h4>
<p><label>Showing: <input (input)="updateVideoUrl($event.target.value)"></label></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>
<!--#enddocregion iframe-videoid -->
<!--#enddocregion -->

View File

@ -6,7 +6,7 @@ import { Component } from '@angular/core';
selector: 'inner-html-binding',
templateUrl: 'inner-html-binding.component.html',
})
// #docregion inner-html-controller
// #docregion class
export class InnerHtmlBindingComponent {
// For example, a user/attacker-controlled value from a URL.
htmlSnippet = 'Template <script>alert("0wned")</script> <b>Syntax</b>';

View File

@ -8,17 +8,19 @@ block includes
For more information about the attacks and mitigations described below, see [OWASP Guide Project](https://www.owasp.org/index.php/Category:OWASP_Guide_Project).
.l-main-section
+ifDocsFor('ts')
.l-main-section
:marked
# Contents:
* [Reporting vulnerabilities](#report-issues).
* [Best practices](#best-practices).
* [Preventing cross-site scripting (XSS)](#xss).
* [Trusting safe values](#bypass-security-apis).
* [HTTP-Level vulnerabilities](#http).
* [Auditing Angular applications](#code-review).
:marked
# Contents:
* [Reporting vulnerabilities](#report-issues).
* [Best practices](#best-practices).
* [Preventing cross-site scripting (XSS)](#xss).
* [Trusting safe values](#bypass-security-apis).
* [HTTP-Level vulnerabilities](#http).
* [Auditing Angular applications](#code-review).
Try the <live-example></live-example> of the code shown in this page.
.l-main-section
@ -103,15 +105,17 @@ h2#xss Preventing cross-site scripting (XSS)
a value that an attacker might control into `innerHTML` normally causes an XSS
vulnerability. For example, code contained in a `<script>` tag is executed:
+makeExcerpt('app/inner-html-binding.component.ts ()', 'inner-html-controller')
+makeExcerpt('app/inner-html-binding.component.ts', 'class')
:marked
Angular recognizes the value as unsafe and automatically sanitizes it, which removes the `<script>`
tag but keeps safe content such as the text content of the `<script>` tag, or the `<b>` element.
block html-sanitization
:marked
Angular recognizes the value as unsafe and automatically sanitizes it, which removes the `<script>`
tag but keeps safe content such as the text content of the `<script>` tag, or the `<b>` element.
figure.image-display
img(src='/resources/images/devguide/security/binding-inner-html.png'
alt='A screenshot showing interpolated and bound HTML values')
figure.image-display
img(src='/resources/images/devguide/security/binding-inner-html.png'
alt='A screenshot showing interpolated and bound HTML values')
:marked
### Avoid direct use of the DOM APIs
@ -144,136 +148,138 @@ figure.image-display
the server. Do not generate Angular templates on the server side using a templating language; doing this
carries a high risk of introducing template-injection vulnerabilities.
.l-main-section
h2#bypass-security-apis Trusting safe values
:marked
Sometimes applications genuinely need to include executable code, display an `<iframe>` from some
URL, or construct potentially dangerous URLs. To prevent automatic sanitization in any of these
situations, you can tell Angular that you inspected a value, checked how it was generated, and made
sure it will always be secure. But **be careful**! If you trust a value that might be malicious, you
are introducing a security vulnerability into your application. If in doubt, find a professional
security reviewer.
block bypass-security-apis
.l-main-section
h2#bypass-security-apis Trusting safe values
:marked
Sometimes applications genuinely need to include executable code, display an `<iframe>` from some
URL, or construct potentially dangerous URLs. To prevent automatic sanitization in any of these
situations, you can tell Angular that you inspected a value, checked how it was generated, and made
sure it will always be secure. But **be careful**! If you trust a value that might be malicious, you
are introducing a security vulnerability into your application. If in doubt, find a professional
security reviewer.
You can mark a value as trusted by injecting `DomSanitizer` and calling one of the
following methods:
You can mark a value as trusted by injecting `DomSanitizer` and calling one of the
following methods:
* `bypassSecurityTrustHtml`
* `bypassSecurityTrustScript`
* `bypassSecurityTrustStyle`
* `bypassSecurityTrustUrl`
* `bypassSecurityTrustResourceUrl`
* `bypassSecurityTrustHtml`
* `bypassSecurityTrustScript`
* `bypassSecurityTrustStyle`
* `bypassSecurityTrustUrl`
* `bypassSecurityTrustResourceUrl`
Remember, whether a value is safe depends on context, so you need to choose the right context for
your intended use of the value. Imagine that the following template needs to bind a URL to a
`javascript:alert(...)` call:
Remember, whether a value is safe depends on context, so you need to choose the right context for
your intended use of the value. Imagine that the following template needs to bind a URL to a
`javascript:alert(...)` call:
+makeExcerpt('app/bypass-security.component.html ()', 'dangerous-url')
+makeExcerpt('app/bypass-security.component.html', 'URL')
:marked
Normally, Angular automatically sanitizes the URL, disables the dangerous code, and
in development mode, logs this action to the console. To prevent
this, you can mark the URL value as a trusted URL using the `bypassSecurityTrustUrl` call:
:marked
Normally, Angular automatically sanitizes the URL, disables the dangerous code, and
in development mode, logs this action to the console. To prevent
this, you can mark the URL value as a trusted URL using the `bypassSecurityTrustUrl` call:
+makeExcerpt('app/bypass-security.component.ts ()', 'trust-url')
+makeExcerpt('app/bypass-security.component.ts ()', 'trust-url')
figure.image-display
img(src='/resources/images/devguide/security/bypass-security-component.png'
alt='A screenshot showing an alert box created from a trusted URL')
figure.image-display
img(src='/resources/images/devguide/security/bypass-security-component.png'
alt='A screenshot showing an alert box created from a trusted URL')
:marked
If you need to convert user input into a trusted value, use a
controller method. The template below allows users to enter a YouTube video ID and load the
corresponding video in an `<iframe>`. The `<iframe src>` attribute is a resource URL security
context, because an untrusted source can, for example, smuggle in file downloads that unsuspecting users
could execute. So call a method on the controller to construct a trusted video URL, that causes
Angular to then allow binding into `<iframe src>`:
:marked
If you need to convert user input into a trusted value, use a
controller method. The template below allows users to enter a YouTube video ID and load the
corresponding video in an `<iframe>`. The `<iframe src>` attribute is a resource URL security
context, because an untrusted source can, for example, smuggle in file downloads that unsuspecting users
could execute. So call a method on the controller to construct a trusted video URL, that causes
Angular to then allow binding into `<iframe src>`:
+makeExcerpt('app/bypass-security.component.html ()', 'iframe-videoid')
+makeExcerpt('app/bypass-security.component.ts ()', 'trust-video-url')
+makeExcerpt('app/bypass-security.component.html', 'iframe')
+makeExcerpt('app/bypass-security.component.ts ()', 'trust-video-url')
.l-main-section
h2#http HTTP-level vulnerabilities
:marked
Angular has built-in support to help prevent two common HTTP vulnerabilities, cross-site request
forgery (CSRF or XSRF) and cross-site script inclusion (XSSI). Both of these must be mitigated primarily
on the server side, but Angular ships helpers to make integration on the client side easier.
block http
.l-main-section
h2#http HTTP-level vulnerabilities
:marked
Angular has built-in support to help prevent two common HTTP vulnerabilities, cross-site request
forgery (CSRF or XSRF) and cross-site script inclusion (XSSI). Both of these must be mitigated primarily
on the server side, but Angular ships helpers to make integration on the client side easier.
h3#xsrf Cross-site request forgery
:marked
In a cross-site request forgery (CSRF or XSRF), an attacker tricks the user into visiting
a different web page (e.g. `evil.com`) with malignant code that secretly sends a malicious request
to your application's web server (e.g. `example-bank.com`).
Assume the user is logged into the application at `example-bank.com`.
The user opens an email and clicks a link to `evil.com` which opens in a new tab.
The `evil.com` page immediately sends a malicious request to `example-bank.com`.
Perhaps it's a request to transfer money from the user's account to the attacker's account.
The browser automatically sends the `example-bank.com` cookies (including the authentication cookie) with this request.
h3#xsrf Cross-site request forgery
:marked
In a cross-site request forgery (CSRF or XSRF), an attacker tricks the user into visiting
a different web page (e.g. `evil.com`) with malignant code that secretly sends a malicious request
to your application's web server (e.g. `example-bank.com`).
The `example-bank.com` server, if it lacks XSRF protection, can't tell the difference between a legitimate request from the application
and the forged request from `evil.com`.
Assume the user is logged into the application at `example-bank.com`.
The user opens an email and clicks a link to `evil.com` which opens in a new tab.
To prevent this, the application must ensure that a user request originates from the real
application, not from a different site.
The server and client must cooperate to thwart this attack.
The `evil.com` page immediately sends a malicious request to `example-bank.com`.
Perhaps it's a request to transfer money from the user's account to the attacker's account.
The browser automatically sends the `example-bank.com` cookies (including the authentication cookie) with this request.
In a common anti-XSRF technique, the application server sends a randomly
generated authentication token in a cookie.
The client code reads the cookie and adds a custom request header with the token in all subsequent requests.
The server compares the received cookie value to the request header value and rejects the request if the values are missing or don't match.
The `example-bank.com` server, if it lacks XSRF protection, can't tell the difference between a legitimate request from the application
and the forged request from `evil.com`.
This technique is effective because all browsers implement the _same origin policy_. Only code from the website
on which cookies are set can read the cookies from that site and set custom headers on requests to that site.
That means only your application can read this cookie token and set the custom header. The malicious code on `evil.com` can't.
To prevent this, the application must ensure that a user request originates from the real
application, not from a different site.
The server and client must cooperate to thwart this attack.
Angular's `http` has built-in support for the client-side half of this technique in its `XSRFStrategy`.
The default `CookieXSRFStrategy` is turned on automatically.
Before sending an HTTP request, the `CookieXSRFStrategy` looks for a cookie called `XSRF-TOKEN` and
sets a header named `X-XSRF-TOKEN` with the value of that cookie.
The server must do its part by setting the
initial `XSRF-TOKEN` cookie and confirming that each subsequent state-modifying request
includes a matching `XSRF-TOKEN` cookie and `X-XSRF-TOKEN` header.
In a common anti-XSRF technique, the application server sends a randomly
generated authentication token in a cookie.
The client code reads the cookie and adds a custom request header with the token in all subsequent requests.
The server compares the received cookie value to the request header value and rejects the request if the values are missing or don't match.
XSRF/CSRF tokens should be unique per user and session, have a large random value generated by a
cryptographically secure random number generator, and should expire in a day or two.
This technique is effective because all browsers implement the _same origin policy_. Only code from the website
on which cookies are set can read the cookies from that site and set custom headers on requests to that site.
That means only your application can read this cookie token and set the custom header. The malicious code on `evil.com` can't.
Your server may use a different cookie or header name for this purpose.
An Angular application can customize cookie and header names by providing its own `CookieXSRFStrategy` values.
code-example(language="typescript").
{ provide: XSRFStrategy, useValue: new CookieXSRFStrategy('myCookieName', 'My-Header-Name') }
:marked
Or you can implement and provide an entirely custom `XSRFStrategy`:
Angular's `http` has built-in support for the client-side half of this technique in its `XSRFStrategy`.
The default `CookieXSRFStrategy` is turned on automatically.
Before sending an HTTP request, the `CookieXSRFStrategy` looks for a cookie called `XSRF-TOKEN` and
sets a header named `X-XSRF-TOKEN` with the value of that cookie.
code-example(language="typescript").
{ provide: XSRFStrategy, useClass: MyXSRFStrategy }
The server must do its part by setting the
initial `XSRF-TOKEN` cookie and confirming that each subsequent state-modifying request
includes a matching `XSRF-TOKEN` cookie and `X-XSRF-TOKEN` header.
:marked
For information about CSRF at the Open Web Application Security Project (OWASP), see
<a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29" target="_blank">Cross-Site Request Forgery (CSRF)</a> and
<a href="https://www.owasp.org/index.php/CSRF_Prevention_Cheat_Sheet" target="_blank">Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet</a>.
The Stanford University paper
<a href="https://seclab.stanford.edu/websec/csrf/csrf.pdf" target="_blank">Robust Defenses for Cross-Site Request Forgery</a> is a rich source of detail.
XSRF/CSRF tokens should be unique per user and session, have a large random value generated by a
cryptographically secure random number generator, and should expire in a day or two.
See also Dave Smith's easy-to-understand
<a href="https://www.youtube.com/watch?v=9inczw6qtpY" target="_blank" title="Cross Site Request Funkery Securing Your Angular Apps From Evil Doers">talk on XSRF at AngularConnect 2016</a>.
Your server may use a different cookie or header name for this purpose.
An Angular application can customize cookie and header names by providing its own `CookieXSRFStrategy` values.
code-example(language="typescript").
{ provide: XSRFStrategy, useValue: new CookieXSRFStrategy('myCookieName', 'My-Header-Name') }
:marked
Or you can implement and provide an entirely custom `XSRFStrategy`:
h3#xssi Cross-site script inclusion (XSSI)
:marked
Cross-site script inclusion, also known as JSON vulnerability, can allow an attacker's website to
read data from a JSON API. The attack works on older browsers by overriding native JavaScript
object constructors, and then including an API URL using a `<script>` tag.
code-example(language="typescript").
{ provide: XSRFStrategy, useClass: MyXSRFStrategy }
This attack is only successful if the returned JSON is executable as JavaScript. Servers can
prevent an attack by prefixing all JSON responses to make them non-executable, by convention, using the
well-known string `")]}',\n"`.
:marked
For information about CSRF at the Open Web Application Security Project (OWASP), see
<a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29" target="_blank">Cross-Site Request Forgery (CSRF)</a> and
<a href="https://www.owasp.org/index.php/CSRF_Prevention_Cheat_Sheet" target="_blank">Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet</a>.
The Stanford University paper
<a href="https://seclab.stanford.edu/websec/csrf/csrf.pdf" target="_blank">Robust Defenses for Cross-Site Request Forgery</a> is a rich source of detail.
Angular's `Http` library recognizes this convention and automatically strips the string
`")]}',\n"` from all responses before further parsing.
See also Dave Smith's easy-to-understand
<a href="https://www.youtube.com/watch?v=9inczw6qtpY" target="_blank" title="Cross Site Request Funkery Securing Your Angular Apps From Evil Doers">talk on XSRF at AngularConnect 2016</a>.
For more information, see the XSSI section of this [Google web security blog
post](https://security.googleblog.com/2011/05/website-security-for-webmasters.html).
h3#xssi Cross-site script inclusion (XSSI)
:marked
Cross-site script inclusion, also known as JSON vulnerability, can allow an attacker's website to
read data from a JSON API. The attack works on older browsers by overriding native JavaScript
object constructors, and then including an API URL using a `<script>` tag.
This attack is only successful if the returned JSON is executable as JavaScript. Servers can
prevent an attack by prefixing all JSON responses to make them non-executable, by convention, using the
well-known string `")]}',\n"`.
Angular's `Http` library recognizes this convention and automatically strips the string
`")]}',\n"` from all responses before further parsing.
For more information, see the XSSI section of this [Google web security blog
post](https://security.googleblog.com/2011/05/website-security-for-webmasters.html).
.l-main-section
h2#code-review Auditing angular applications