Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

docs(security): improve xsrf description and add it to http chapter as well #2652

Merged
merged 1 commit into from
Oct 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 54 additions & 30 deletions public/docs/ts/latest/guide/security.jade
Original file line number Diff line number Diff line change
Expand Up @@ -200,40 +200,64 @@ h2#http HTTP-level vulnerabilities

h3#xsrf Cross-site request forgery
:marked
In a cross-site request forgery, an attacker tricks the user into visiting a
_different_ page and has them, for example, 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 ensure 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`. 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
`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.

CSRF 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` through providing a custom
binding for that type by adding either of the following to your providers list:
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.

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`.

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.

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.

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.

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").
{ provide: XSRFStrategy, useValue: new CookieXSRFStrategy('myCookieName', 'My-Header-Name')}
{ provide: XSRFStrategy, useClass: MyXSRFStrategy}
{ provide: XSRFStrategy, useClass: MyXSRFStrategy }

:marked
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
[Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet](https://www.owasp.org/index.php/CSRF_Prevention_Cheat_Sheet). The Stanford University
paper [Robust Defenses for Cross-Site Request Forgery](https://seclab.stanford.edu/websec/csrf/csrf.pdf) is also a rich source of detail.
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any particular reason why you're changing the link syntax here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We want links to external sites to appear in a new browser tab by default. Can't specify that in markdown

<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.

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)
:marked
Expand Down
25 changes: 22 additions & 3 deletions public/docs/ts/latest/guide/server-communication.jade
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ block includes
- [Always handle errors](#error-handling).
- [Send data to the server](#update).
<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">
<li> [Search parameters](#search-parameters).</li>
<li> [More fun with observables](#more-observables).</li>
</ul>
- [Guarding against Cross-Site Request Forgery](#xsrf)
- [Appendix: Tour of Heroes in-memory server](#in-mem-web-api).

A <live-example>live example</live-example> illustrates these topics.
Expand All @@ -46,7 +47,7 @@ block demos-list
:marked
- [The Tour of Heroes *HTTP* client demo](#http-client).
- [Fall back to !{_Promise}s](#promises).
- [Cross-origin requests: Wikipedia example](#cors).
- [Cross-Origin Requests: Wikipedia example](#cors).
- [More fun with observables](#more-observables).

:marked
Expand Down Expand Up @@ -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).

h2#cors Cross-origin requests: Wikipedia example
h2#cors Cross-Origin Requests: Wikipedia example
:marked
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.
Expand Down Expand Up @@ -628,6 +629,24 @@ block wikipedia-jsonp+
You added the `debounceTime`, `distinctUntilChanged`, and `switchMap` operators to the RxJS `Observable` class
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we repeat the same content here? should this link to the original doc, so we don't have two sources of truth that can diverge?

Copy link
Contributor Author

@wardbell wardbell Oct 23, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought about that. We need some context here. I only repeat the intro and this is material that shouldn't change even if our implementation does. I didn't think making up a new summary description would make a difference. I'll crisp it up in the Http chapter.

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
.l-main-section
:marked
Expand Down