Vladyslav Hesal
Github @arantir
Twitter @hesalx
Authentication security in single-page applications
The problem
The difficulties:
Common attacks:
Existing authentication solutions:
Raw Sessions
Existing authentication solutions:
OAuth2 Resource Owner Password Credentials
OAuth2 Implicit Grant
OAuth2 Implicit Grant
Existing authentication solutions:
Perfect case:
Security is not simple ;(�
How does many web-app authentication works:
How does many SPA authentication works:
Client
Server
Possible issues:
SPA authentication steps:
Login form flaws:
Login form XSS prevention:
Just a regular HTML form!
Login form XSRF prevention:
Just a good old XSRF-token.
✓ Out-of-the-box for majority of frameworks.
How it works?
POST /login
Host: auth.example.com
username=john&password=12345
303 See Other
Set-Cookie: session=dNt4...pwK; domain=auth.example.com; HttpOnly; Secure
Location: https://client.example.com/token#B7E6...GJQvtW
OAuth2 Implicit Grant + Password Credentials Grant without useless garbage.
SPA authentication steps:
HttpOnly Cookie or Authentication Header?
Use both!
| XSRF | Stealing via XSS |
HttpOnly Cookie | ✓ | ✗ |
Authorization Header | ✗ | ✓ |
Cookie + Header | ✗ | ✗ |
Two-factor Access Token
Two-factor Access Token
Almost anything you want, just like OAuth2 bearer token.
(as long as it’s impossible to guess one part from another)
How it works?
POST /login
Host: auth.example.com
username=john&password=12345
303 See Other
Set-Cookie: session=dNt4...pwK; domain=auth.example.com; HttpOnly; Secure
Set-Cookie: salt=C5rE...q2cX; domain=*.example.com; HttpOnly; Secure
Location: https://client.example.com/token#B7E6...GJQvtW
SPA authentication steps:
SPA authentication steps:
Refreshing authorization credentials
Utilizing <iframe>
Refreshing authorization credentials
Utilizing <iframe>
WAT?
Refreshing authorization credentials
Utilizing <iframe>
Cross-Origin Resource Sharing (http://www.w3.org/TR/cors/)
7.1.4 Simple Cross-Origin Request
If the manual redirect flag is unset and the response has an HTTP status code of 301, 302, 303, 307, or 308:
Apply the redirect steps.
Refreshing authorization credentials
Utilizing <iframe>
X-Frame-Options (http://tools.ietf.org/html/rfc7034)
The X-Frame-Options HTTP header field indicates a policy that specifies whether the browser should *render* the transmitted resource within a <frame> or an <iframe>.
DENY� A browser receiving content with this header field MUST NOT� *display* this content in any frame.
Not applied to redirects!
How it works?
<iframe src=”/authorize”></iframe>
GET /authorize
Host: auth.example.com
Cookie: session=dNt4...pwK
303 See Other
Set-Cookie: salt=143M...Op6; domain=*.example.com; HttpOnly; Secure
Location: https://client.example.com/token#48XpM...FMLKJ
How it can also work?
GET /authorize
Host: auth.example.com
Cookie: session=dNt4...pwK
303 See Other
Set-Cookie: salt=143M...Op6; domain=api.example.com; HttpOnly; Secure
Location: https://api.example.com/authorize?nonce=tRljm...DCoAz
303 See Other
Location: https://client.example.com/token#48XpM...FMLKJ
Concerns
SPA authentication steps:
Perfect case:
Is it simple?
Independent login page | “Hello World” web application | ✓ |
Redirects | Browser does it for you | ✓ |
Cookie | Browser does it for you | ✓ |
IFrame | Nothing more than creating a tag with JS | ✓ |
Authorization header | You would do that anyway | ✓ |
Subdomains | But you know, there’s no silver bullets | Varying |
More complex cases
Single-domain case
More complex cases
Independent auth server case
The future
That's all folks!