docs(security): improve xsrf description and add it to http chapter as well (#2652)
This commit is contained in:
parent
c746c732aa
commit
ea7dff4d89
|
@ -200,40 +200,64 @@ h2#http HTTP-level vulnerabilities
|
||||||
|
|
||||||
h3#xsrf Cross-site request forgery
|
h3#xsrf Cross-site request forgery
|
||||||
:marked
|
:marked
|
||||||
In a cross-site request forgery, an attacker tricks the user into visiting a
|
In a cross-site request forgery (CSRF or XSRF), an attacker tricks the user into visiting
|
||||||
_different_ page and has them, for example, submit a form that sends a request to your application's
|
a different web page (e.g. `evil.com`) with malignant code that secretly sends a malicious request
|
||||||
web server. If the user is logged into your application, the browser will send authentication
|
to your application's web server (e.g. `example-bank.com`).
|
||||||
cookies, and the attacker could—for example—cause a bank transfer in the user's name with
|
|
||||||
the right request.
|
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.
|
||||||
|
|
||||||
To prevent this, your application must ensure that user requests originate in your own
|
The `example-bank.com` server, if it lacks XSRF protection, can't tell the difference between a legitimate request from the application
|
||||||
application, not on a different site. A common technique is that the server sends a randomly
|
and the forged request from `evil.com`.
|
||||||
generated authentication token in a cookie, often with the name `XSRF-TOKEN`. Only the website
|
|
||||||
on which cookies are set can read the cookies, 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
|
To prevent this, the application must ensure that a user request originates from the real
|
||||||
`CookieXSRFStrategy` looks for a cookie called `XSRF-TOKEN` and sets an HTTP request header named
|
application, not from a different site.
|
||||||
`X-XSRF-TOKEN` with the value of that cookie on every request. The server must set the
|
The server and client must cooperate to thwart this attack.
|
||||||
`XSRF-TOKEN` cookie and validate the response header for each state-modifying request.
|
|
||||||
|
|
||||||
CSRF tokens should be unique per user and session, have a large random value generated by a
|
In a common anti-XSRF technique, the application server sends a randomly
|
||||||
cryptographically secure random number generator, and expire.
|
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.
|
||||||
|
|
||||||
Angular applications can customize cookie and header names by binding their own
|
This technique is effective because all browsers implement the _same origin policy_. Only code from the website
|
||||||
`CookieXSRFStrategy` value or implement an entirely custom `XSRFStrategy` through providing a custom
|
on which cookies are set can read the cookies from that site and set custom headers on requests to that site.
|
||||||
binding for that type by adding either of the following to your providers list:
|
That means only your application can read this cookie token and set the custom header. The malicious code on `evil.com` can't.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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`:
|
||||||
|
|
||||||
code-example(language="typescript").
|
code-example(language="typescript").
|
||||||
{ provide: XSRFStrategy, useValue: new CookieXSRFStrategy('myCookieName', 'My-Header-Name')}
|
{ provide: XSRFStrategy, useClass: MyXSRFStrategy }
|
||||||
{ provide: XSRFStrategy, useClass: MyXSRFStrategy}
|
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
For information about CSRF at the Open Web Application Security Project (OWASP) see
|
For information about CSRF at the Open Web Application Security Project (OWASP), see
|
||||||
[Cross-Site Request Forgery (CSRF)](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29) and
|
<a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29" target="_blank">Cross-Site Request Forgery (CSRF)</a> and
|
||||||
[Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet](https://www.owasp.org/index.php/CSRF_Prevention_Cheat_Sheet). The Stanford University
|
<a href="https://www.owasp.org/index.php/CSRF_Prevention_Cheat_Sheet" target="_blank">Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet</a>.
|
||||||
paper [Robust Defenses for Cross-Site Request Forgery](https://seclab.stanford.edu/websec/csrf/csrf.pdf) is also a rich source of detail.
|
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.
|
||||||
|
|
||||||
|
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>.
|
||||||
|
|
||||||
h3#xssi Cross-site script inclusion (XSSI)
|
h3#xssi Cross-site script inclusion (XSSI)
|
||||||
:marked
|
:marked
|
||||||
|
|
|
@ -27,11 +27,12 @@ block includes
|
||||||
- [Always handle errors](#error-handling).
|
- [Always handle errors](#error-handling).
|
||||||
- [Send data to the server](#update).
|
- [Send data to the server](#update).
|
||||||
<li if-docs="ts"> [Fall back to promises](#promises).</li>
|
<li if-docs="ts"> [Fall back to promises](#promises).</li>
|
||||||
- [Cross-origin requests: Wikipedia example](#cors).
|
- [Cross-Origin Requests: Wikipedia example](#cors).
|
||||||
<ul if-docs="ts">
|
<ul if-docs="ts">
|
||||||
<li> [Search parameters](#search-parameters).</li>
|
<li> [Search parameters](#search-parameters).</li>
|
||||||
<li> [More fun with observables](#more-observables).</li>
|
<li> [More fun with observables](#more-observables).</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
- [Guarding against Cross-Site Request Forgery](#xsrf)
|
||||||
- [Appendix: Tour of Heroes in-memory server](#in-mem-web-api).
|
- [Appendix: Tour of Heroes in-memory server](#in-mem-web-api).
|
||||||
|
|
||||||
A <live-example>live example</live-example> illustrates these topics.
|
A <live-example>live example</live-example> illustrates these topics.
|
||||||
|
@ -46,7 +47,7 @@ block demos-list
|
||||||
:marked
|
:marked
|
||||||
- [The Tour of Heroes *HTTP* client demo](#http-client).
|
- [The Tour of Heroes *HTTP* client demo](#http-client).
|
||||||
- [Fall back to !{_Promise}s](#promises).
|
- [Fall back to !{_Promise}s](#promises).
|
||||||
- [Cross-origin requests: Wikipedia example](#cors).
|
- [Cross-Origin Requests: Wikipedia example](#cors).
|
||||||
- [More fun with observables](#more-observables).
|
- [More fun with observables](#more-observables).
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
|
@ -446,7 +447,7 @@ block hero-list-comp-add-hero
|
||||||
|
|
||||||
To understand the implications and consequences of subscriptions, watch [Ben Lesh's talk on observables](https://www.youtube.com/watch?v=3LKMwkuK0ZE) or his video course on [egghead.io](https://egghead.io/lessons/rxjs-rxjs-observables-vs-promises).
|
To understand the implications and consequences of subscriptions, watch [Ben Lesh's talk on observables](https://www.youtube.com/watch?v=3LKMwkuK0ZE) or his video course on [egghead.io](https://egghead.io/lessons/rxjs-rxjs-observables-vs-promises).
|
||||||
|
|
||||||
h2#cors Cross-origin requests: Wikipedia example
|
h2#cors Cross-Origin Requests: Wikipedia example
|
||||||
:marked
|
:marked
|
||||||
You just learned how to make `XMLHttpRequests` using the !{_Angular_Http} service.
|
You just learned how to make `XMLHttpRequests` using the !{_Angular_Http} service.
|
||||||
This is the most common approach for server communication, but it doesn't work in all scenarios.
|
This is the most common approach for server communication, but it doesn't work in all scenarios.
|
||||||
|
@ -628,6 +629,24 @@ block wikipedia-jsonp+
|
||||||
You added the `debounceTime`, `distinctUntilChanged`, and `switchMap` operators to the RxJS `Observable` class
|
You added the `debounceTime`, `distinctUntilChanged`, and `switchMap` operators to the RxJS `Observable` class
|
||||||
in `rxjs-operators` as [described above](#rxjs).
|
in `rxjs-operators` as [described above](#rxjs).
|
||||||
|
|
||||||
|
a#xsrf
|
||||||
|
.l-main-section
|
||||||
|
:marked
|
||||||
|
## Guarding against Cross-Site Request Forgery
|
||||||
|
|
||||||
|
In a cross-site request forgery (CSRF or XSRF), an attacker tricks the user into visiting
|
||||||
|
a different web page with malignant code that secretly sends a malicious request to your application's web server,
|
||||||
|
|
||||||
|
The server and client application must work together to thwart this attack.
|
||||||
|
Angular's `Http` client does its part by applying a default `CookieXSRFStrategy` automatically to all requests.
|
||||||
|
|
||||||
|
The `CookieXSRFStrategy` supports a common anti-XSRF technique in which the server sends a randomly
|
||||||
|
generated authentication token in a cookie named `XSRF-TOKEN`.
|
||||||
|
The HTTP client adds an `X-XSRF-TOKEN` header with that token value to subsequent requests.
|
||||||
|
The server receives both the cookie and the header, compares them, and processes the request only if the cookie and header match.
|
||||||
|
|
||||||
|
See the [XSRF topic on the Security page](security.html#xsrf) for more information about XSRF and Angular's `XSRFStrategy` counter measures.
|
||||||
|
|
||||||
a#in-mem-web-api
|
a#in-mem-web-api
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
|
Loading…
Reference in New Issue