docs(security): Add security documentation.
Substantially rewritten, based on original content by Brian Clarkio and Ward Bell and contributions from Naomi Black.
This commit is contained in:
parent
9107eeeee8
commit
fb179d9690
|
@ -0,0 +1,25 @@
|
||||||
|
/// <reference path="../_protractor/e2e.d.ts" />
|
||||||
|
'use strict';
|
||||||
|
describe('Security E2E Tests', () => {
|
||||||
|
beforeAll(function() { browser.get(''); });
|
||||||
|
|
||||||
|
it('sanitizes innerHTML', () => {
|
||||||
|
let interpolated = element(By.className('e2e-inner-html-interpolated'));
|
||||||
|
expect(interpolated.getText())
|
||||||
|
.toContain('Template <script>alert("0wned")</script> <b>Syntax</b>');
|
||||||
|
let bound = element(By.className('e2e-inner-html-bound'));
|
||||||
|
expect(bound.getText()).toContain('Template alert("0wned") Syntax');
|
||||||
|
let bold = element(By.css('.e2e-inner-html-bound b'));
|
||||||
|
expect(bold.getText()).toContain('Syntax');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('binds trusted URLs', () => {
|
||||||
|
let dangerousUrl = element(By.className('e2e-dangerous-url'));
|
||||||
|
expect(dangerousUrl.getAttribute('href')).toMatch(/^javascript:alert/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('binds trusted resource URLs', () => {
|
||||||
|
let iframe = element(By.className('e2e-iframe'));
|
||||||
|
expect(iframe.getAttribute('src')).toMatch(/^https:\/\/www.youtube.com\//);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,20 @@
|
||||||
|
// #docregion
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
import { BypassSecurityComponent } from './bypass-security.component';
|
||||||
|
import { InnerHtmlBindingComponent } from './inner-html-binding.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
template: `
|
||||||
|
<h1>Security</h1>
|
||||||
|
<inner-html-binding></inner-html-binding>
|
||||||
|
<bypass-security></bypass-security>
|
||||||
|
`,
|
||||||
|
directives: [
|
||||||
|
BypassSecurityComponent,
|
||||||
|
InnerHtmlBindingComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AppComponent {
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!--#docregion -->
|
||||||
|
<h3>Bypass Security Component</h3>
|
||||||
|
|
||||||
|
<!--#docregion dangerous-url -->
|
||||||
|
<h4>A dangerous URL:</h4>
|
||||||
|
<p><a class="e2e-dangerous-url" [href]="dangerousUrl">Click me.</a></p>
|
||||||
|
<!--#enddocregion dangerous-url -->
|
||||||
|
|
||||||
|
<!--#docregion iframe-videoid -->
|
||||||
|
<h4>Resource URL:</h4>
|
||||||
|
<p><label>Showing: <input (input)="updateVideoUrl($event.target.value)"></label></p>
|
||||||
|
<iframe class="e2e-iframe" width="640" height="390" [src]="videoUrl"></iframe>
|
||||||
|
<!--#enddocregion iframe-videoid -->
|
||||||
|
|
||||||
|
<!--#enddocregion -->
|
|
@ -0,0 +1,33 @@
|
||||||
|
// #docplaster
|
||||||
|
// #docregion
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { DomSanitizationService, SafeResourceUrl, SafeUrl } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'bypass-security',
|
||||||
|
templateUrl: 'app/bypass-security.component.html',
|
||||||
|
})
|
||||||
|
export class BypassSecurityComponent {
|
||||||
|
dangerousUrl: SafeUrl;
|
||||||
|
videoUrl: SafeResourceUrl;
|
||||||
|
|
||||||
|
// #docregion trust-url
|
||||||
|
constructor(private sanitizer: DomSanitizationService) {
|
||||||
|
// javascript: URLs are dangerous if attacker controlled. Angular sanitizes them in data
|
||||||
|
// binding, but we can explicitly tell Angular to trust this value:
|
||||||
|
this.dangerousUrl = sanitizer.bypassSecurityTrustUrl('javascript:alert("Hi there")');
|
||||||
|
// #enddocregion trust-url
|
||||||
|
this.updateVideoUrl('PUBnlbjZFAI');
|
||||||
|
}
|
||||||
|
|
||||||
|
// #docregion trust-video-url
|
||||||
|
updateVideoUrl(id: string) {
|
||||||
|
// 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.
|
||||||
|
this.videoUrl =
|
||||||
|
this.sanitizer.bypassSecurityTrustResourceUrl('https://www.youtube.com/embed/' + id);
|
||||||
|
}
|
||||||
|
// #enddocregion trust-video-url
|
||||||
|
}
|
||||||
|
// #enddocregion
|
|
@ -0,0 +1,6 @@
|
||||||
|
<!-- #docregion -->
|
||||||
|
<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>
|
|
@ -0,0 +1,14 @@
|
||||||
|
// #docregion
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
moduleId: module.id,
|
||||||
|
selector: 'inner-html-binding',
|
||||||
|
templateUrl: 'inner-html-binding.component.html',
|
||||||
|
})
|
||||||
|
// #docregion inner-html-controller
|
||||||
|
export class InnerHtmlBindingComponent {
|
||||||
|
// E.g. a user/attacker controlled value from a URL.
|
||||||
|
htmlSnippet = 'Template <script>alert("0wned")</script> <b>Syntax</b>';
|
||||||
|
}
|
||||||
|
// #enddocregion inner-html-controller
|
|
@ -0,0 +1,8 @@
|
||||||
|
// #docregion
|
||||||
|
import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
|
// #docregion import
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
// #enddocregion import
|
||||||
|
|
||||||
|
bootstrap(AppComponent);
|
|
@ -0,0 +1,26 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- #docregion -->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Angular Content Security</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
|
||||||
|
<!-- Polyfill(s) for older browsers -->
|
||||||
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
|
||||||
|
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||||
|
<script src="node_modules/reflect-metadata/Reflect.js"></script>
|
||||||
|
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||||
|
|
||||||
|
<script src="systemjs.config.js"></script>
|
||||||
|
<script>
|
||||||
|
System.import('app').catch(function(err){ console.error(err); });
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<app-root>Loading...</app-root>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"description": "Content Security",
|
||||||
|
"files": [
|
||||||
|
"!**/*.d.ts",
|
||||||
|
"!**/*.js"
|
||||||
|
],
|
||||||
|
"tags": ["security"]
|
||||||
|
}
|
|
@ -73,6 +73,11 @@
|
||||||
"intro": "Learn how to apply CSS styles to components."
|
"intro": "Learn how to apply CSS styles to components."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"security": {
|
||||||
|
"title": "Security",
|
||||||
|
"intro": "Prevent security vulnerabilities"
|
||||||
|
},
|
||||||
|
|
||||||
"hierarchical-dependency-injection": {
|
"hierarchical-dependency-injection": {
|
||||||
"title": "Hierarchical Dependency Injectors",
|
"title": "Hierarchical Dependency Injectors",
|
||||||
"navTitle": "Hierarchical Injectors",
|
"navTitle": "Hierarchical Injectors",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
!= partial("../../../_includes/_ts-temp")
|
|
@ -73,6 +73,11 @@
|
||||||
"intro": "Learn how to apply CSS styles to components."
|
"intro": "Learn how to apply CSS styles to components."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"security": {
|
||||||
|
"title": "Security",
|
||||||
|
"intro": "Prevent security vulnerabilities"
|
||||||
|
},
|
||||||
|
|
||||||
"hierarchical-dependency-injection": {
|
"hierarchical-dependency-injection": {
|
||||||
"title": "Hierarchical Dependency Injectors",
|
"title": "Hierarchical Dependency Injectors",
|
||||||
"navTitle": "Hierarchical Injectors",
|
"navTitle": "Hierarchical Injectors",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
!= partial("../../../_includes/_ts-temp")
|
|
@ -78,6 +78,11 @@
|
||||||
"intro": "Learn how to apply CSS styles to components."
|
"intro": "Learn how to apply CSS styles to components."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"security": {
|
||||||
|
"title": "Security",
|
||||||
|
"intro": "Prevent security vulnerabilities"
|
||||||
|
},
|
||||||
|
|
||||||
"hierarchical-dependency-injection": {
|
"hierarchical-dependency-injection": {
|
||||||
"title": "Hierarchical Dependency Injectors",
|
"title": "Hierarchical Dependency Injectors",
|
||||||
"navTitle": "Hierarchical Injectors",
|
"navTitle": "Hierarchical Injectors",
|
||||||
|
|
|
@ -0,0 +1,246 @@
|
||||||
|
block includes
|
||||||
|
include ../_util-fns
|
||||||
|
:marked
|
||||||
|
# Security
|
||||||
|
Web application security has many aspects. This documentation describes Angular's built in
|
||||||
|
protections against common web application vulnerabilities and attacks, such as Cross Site
|
||||||
|
Scripting Attacks. It does not cover application level security, such as authentication (_Who is
|
||||||
|
this user?_) or authorization (_What can this user do?_).
|
||||||
|
|
||||||
|
The [Open Web Application Security Project (OWASP)](https://www.owasp.org/index.php/Category:OWASP_Guide_Project)
|
||||||
|
has further information on the attacks and mitigations described below.
|
||||||
|
|
||||||
|
.l-main-section
|
||||||
|
:marked
|
||||||
|
# Table Of 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)
|
||||||
|
|
||||||
|
p Try the #[+liveExampleLink2()] of the code shown in this chapter.
|
||||||
|
|
||||||
|
.l-main-section
|
||||||
|
h2#report-issues Reporting Vulnerabilities
|
||||||
|
:marked
|
||||||
|
Email us at [security@angular.io](mailto:security@angular.io) to report vulnerabilities in
|
||||||
|
Angular itself.
|
||||||
|
|
||||||
|
For further details on how Google handles security issues please refer to [Google's security
|
||||||
|
philosophy](https://www.google.com/about/appsecurity/).
|
||||||
|
|
||||||
|
.l-main-section
|
||||||
|
h2#best-practices Best Practices
|
||||||
|
:marked
|
||||||
|
* **Keep current with the latest Angular library releases.**
|
||||||
|
We regularly update our Angular libraries and these updates may fix security defects discovered in
|
||||||
|
previous version. Check the Angular [change
|
||||||
|
log](https://github.com/angular/angular/blob/master/CHANGELOG.md) for security-related updates.
|
||||||
|
|
||||||
|
* **Don't modify your copy of Angular.**
|
||||||
|
Private, customized versions of Angular tend to fall behind the current version and may neglect
|
||||||
|
important security fixes and enhancements. Instead, share your Angular improvements with the
|
||||||
|
community and make a pull request.
|
||||||
|
|
||||||
|
* **Avoid Angular APIs marked in the documentation as “[_Security Risk_](#bypass-security-apis)”.**
|
||||||
|
|
||||||
|
.l-main-section
|
||||||
|
h2#xss Preventing Cross-Site Scripting (XSS)
|
||||||
|
:marked
|
||||||
|
[Cross-Site Scripting (XSS)](https://en.wikipedia.org/wiki/Cross-site_scripting) enables attackers
|
||||||
|
to inject malicious code into web pages. Such code can then for example steal user's data (in
|
||||||
|
particular their login data), or perform actions impersonating the user. This is one of the most
|
||||||
|
common attacks on the web.
|
||||||
|
|
||||||
|
To block XSS attacks, we must prevent malicious code from entering the DOM. For example, if an
|
||||||
|
attacker can trick us into inserting a `<script>` tag in the DOM, they can run arbitrary code on
|
||||||
|
our website. The attack is not limited to `<script>` tags - many elements and properties in the
|
||||||
|
DOM allow code execution, for example `<img onerror="...">`, `<a href="javascript:...">`. If
|
||||||
|
attacker controlled data enters the DOM, we have to expect security vulnerabilities.
|
||||||
|
|
||||||
|
### Angular’s Cross-site Scripting Security Model
|
||||||
|
|
||||||
|
To systematically block XSS bugs, Angular treats all values as untrusted by default. When a value
|
||||||
|
is inserted into the DOM from a template, via property, attribute, style, or class binding, or via
|
||||||
|
interpolation, Angular will sanitize and escape untrusted values.
|
||||||
|
|
||||||
|
### Sanitization and security contexts
|
||||||
|
|
||||||
|
Sanitization inspects an untrusted value and turns it into a value that is safe to insert into
|
||||||
|
the DOM. In many cases, values do not get changed by this at all. Sanitization depends on context:
|
||||||
|
a value that is harmless in CSS is potentially dangerous in a URL.
|
||||||
|
|
||||||
|
Angular defines four security contexts: HTML, style, URL, and resource URL.
|
||||||
|
|
||||||
|
* HTML is used when interpreting a value as HTML, e.g. when binding to `innerHtml`
|
||||||
|
* Style is used when binding CSS into the `style` property
|
||||||
|
* URL is used for URL properties such as `<a href>`
|
||||||
|
* Resource URLs are URLs that will be loaded and executed as code, e.g. in `<script src>`
|
||||||
|
|
||||||
|
Angular sanitizes untrusted values for the first three items; sanitizing resource URLs is not
|
||||||
|
possible as they contain arbitrary code. In development mode, Angular prints a console warning
|
||||||
|
when it has to change a value during sanitization.
|
||||||
|
|
||||||
|
### Sanitization example
|
||||||
|
|
||||||
|
The template below binds the value of `htmlSnippet`, once by interpolating it into an element's
|
||||||
|
content, and once by binding it to the `innerHTML` property of an element.
|
||||||
|
|
||||||
|
+makeExample('security/ts/app/inner-html-binding.component.html')(format=".")
|
||||||
|
:marked
|
||||||
|
Interpolated content is always escaped - the HTML is not interpreted, and the browser displays
|
||||||
|
angle brackets in the elements text content.
|
||||||
|
|
||||||
|
For the HTML to be interpreted, we must bind to an HTML property, such as `innerHTML`. But binding
|
||||||
|
a potentially attacker controlled value into `innerHTML` would normally cause an XSS
|
||||||
|
vulnerability. For example, code contained in a `<script>` tag would be executed.
|
||||||
|
+makeExample('security/ts/app/inner-html-binding.component.ts', 'inner-html-controller')(format=".")
|
||||||
|
:marked
|
||||||
|
Angular recognizes the value as unsafe, and automatically sanitizes it. It 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')
|
||||||
|
:marked
|
||||||
|
### Avoid direct use of the DOM APIs
|
||||||
|
|
||||||
|
The built-in browser DOM APIs do not automatically protect you from security vulnerabilities.
|
||||||
|
For example, `document`, the node available through `ElementRef`, and many third party APIs
|
||||||
|
contain unsafe methods. Avoid directly interacting with the DOM, and instead use Angular
|
||||||
|
templates where possible.
|
||||||
|
|
||||||
|
### Content Security Policy
|
||||||
|
|
||||||
|
A [Content Security Policy (CSP)](https://developer.mozilla.org/en-
|
||||||
|
US/docs/Web/Security/CSP/Introducing_Content_Security_Policy) is a defense-in-depth technique to
|
||||||
|
prevent XSS. To enable CSP, configure your web server to return an appropriate
|
||||||
|
`Content-Security-Policy` HTTP header. Learn more at
|
||||||
|
[OWASP](https://www.owasp.org/index.php/Content_Security_Policy).
|
||||||
|
|
||||||
|
<a id="offline-template-compiler"></a>
|
||||||
|
### Use the Offline Template Compiler
|
||||||
|
|
||||||
|
The offline template compiler prevents a whole class of vulnerabilities called template injection,
|
||||||
|
and also greatly improves application performance. Use the offline template compiler in production
|
||||||
|
deployments. Do not dynamically generate templates. Angular trusts template code, so generating
|
||||||
|
templates, in particular containing user data, circumvents Angular's built-in protections. See the
|
||||||
|
[Dynamic Forms Cookbook](../cookbook/dynamic-form.html) on how to dynamically construct forms in a
|
||||||
|
safe way.
|
||||||
|
|
||||||
|
### Server side XSS protection
|
||||||
|
|
||||||
|
HTML constructed on the server is vulnerable to injection attacks. When generating server side
|
||||||
|
HTML, e.g. for the initial page load of the Angular application, make sure to use a templating
|
||||||
|
language that automatically escapes values to prevent XSS vulnerabilities on the server. Do not
|
||||||
|
generate Angular templates on the server side using a templating language, 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 this situation,
|
||||||
|
you can tell Angular that you inspected a value, checked how it is generated, and made sure it is
|
||||||
|
always secure. But **be careful**! If you trust a value that can be malicious, you will likely
|
||||||
|
introduce a security vulnerability into your application. If in doubt, find a professional
|
||||||
|
security reviewer.
|
||||||
|
|
||||||
|
You can mark a value as trusted by injecting `DomSanitizationService`, and calling one of the
|
||||||
|
following methods.
|
||||||
|
|
||||||
|
* `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 the following template needs to bind a URL to a
|
||||||
|
`javascript:alert(...)` call.
|
||||||
|
|
||||||
|
+makeExample('security/ts/app/bypass-security.component.html', 'dangerous-url')(format=".")
|
||||||
|
:marked
|
||||||
|
Normally, Angular would automatically sanitize the URL and disable the dangerous code. To prevent
|
||||||
|
this, we can mark the URL value as a trusted URL using the `bypassSecurityTrustUrl` call:
|
||||||
|
|
||||||
|
+makeExample('security/ts/app/bypass-security.component.ts', 'trust-url')(format=".")
|
||||||
|
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 we need to convert user input into a trusted value, it can be convenient to do so in a
|
||||||
|
controller method. The template below allows users to enter a YouTube video ID, and load the
|
||||||
|
corresponding video in an `<iframe>`. `<iframe src>` is a resource URL, because an untrusted
|
||||||
|
source can e.g. smuggle in file downloads that unsuspecting users would execute. So we call a
|
||||||
|
method on the controller to construct a new, trusted video URL, which is then bound to the
|
||||||
|
`<iframe src>`.
|
||||||
|
|
||||||
|
+makeExample('security/ts/app/bypass-security.component.html', 'iframe-videoid')(format=".")
|
||||||
|
+makeExample('security/ts/app/bypass-security.component.ts', 'trust-video-url')(format=".")
|
||||||
|
|
||||||
|
.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 (XSRF) and Cross-site Script Inclusion (XSSI). Both of these must be primarily mitigated
|
||||||
|
on the server side, but Angular ships helpers to make integration on the client side easier.
|
||||||
|
|
||||||
|
h3#xsrf Cross-site Request Forgery (XSRF)
|
||||||
|
:marked
|
||||||
|
In a Cross-site Request Forgery (XSRF or CSRF), an attacker tricks the user into visiting a
|
||||||
|
_different_ page, and has them e.g. submit a form that sends a request to your application's
|
||||||
|
web server. If the user is logged into your application, the browser will send authentication
|
||||||
|
cookies, and the attacker could - for example - cause a bank transfer in the user's name with
|
||||||
|
the right request.
|
||||||
|
|
||||||
|
To prevent this, your application must make sure that user requests originate in your own
|
||||||
|
application, not on a different site. A common technique is that the server sends a randomly
|
||||||
|
generated authentication token in a cookie, often with the name `XSRF-TOKEN`. Cookies can only
|
||||||
|
be read by the website on which they are set, so only your own application can read this token. On
|
||||||
|
each API request, the server then validates the client by checking that the token is sent back,
|
||||||
|
usually in an HTTP header called `X-XSRF-TOKEN`.
|
||||||
|
|
||||||
|
The Angular `http` client has built-in support for this technique. The default
|
||||||
|
`CookieXSRFStrategy` looks for a cookie called `XSRF-TOKEN` and sets an HTTP request header named
|
||||||
|
`X-XSRF-TOKEN` with the value of that cookie on every request. The server must set the
|
||||||
|
`XSRF-TOKEN` cookie, and validate the response header for each state modifying request.
|
||||||
|
|
||||||
|
XSRF tokens should be unique per user and session, have a large random value generated by a
|
||||||
|
cryptographically secure random number generator, and expire.
|
||||||
|
|
||||||
|
Angular applications can customize cookie and header names by binding their own
|
||||||
|
`CookieXSRFStrategy` value, or implement an entirely custom `XSRFStrategy` by providing a custom
|
||||||
|
binding for that type.
|
||||||
|
|
||||||
|
Learn about Cross Site Request Forgery (XSRF) at the Open Web Application Security Project (OWASP)
|
||||||
|
[here](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29) and
|
||||||
|
[here](https://www.owasp.org/index.php/CSRF_Prevention_Cheat_Sheet). This [Stanford University
|
||||||
|
paper](https://seclab.stanford.edu/websec/csrf/csrf.pdf) is a rich source of detail.
|
||||||
|
|
||||||
|
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 browser 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 it 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.
|
||||||
|
|
||||||
|
Learn more in 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
|
||||||
|
:marked
|
||||||
|
Angular applications should follow the same security principles as regular web applications, and
|
||||||
|
should be audited as such. Angular specific APIs that should be audited in a security review,
|
||||||
|
such as the [_bypassSecurityTrust_](#bypass-security-apis) APIs, are marked in the documentation
|
||||||
|
as security sensitive.
|
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
Binary file not shown.
After Width: | Height: | Size: 238 KiB |
Loading…
Reference in New Issue