You are on page 1of 62

REST

Security by Example
SANS AppSec 2014

About
Frank Kim
SANS Ins?tute
Curriculum Lead, Applica?on Security
Author, Secure Coding in Java

Outline

Authen?ca?on
Encryp?on
Valida?on
Wrap Up

Authen?ca?on
Process of establishing and verifying an iden?ty
Can be based on three factors
Something you know
Something you have
Something you are

Java EE Authen?ca?on
Congura?on in web.xml
!

1 <security-constraint>!
2
<web-resource-collection>!
3
<web-resource-name>Example</web-resource-name>!
4
<url-pattern>/*</url-pattern>!
5
</web-resource-collection>!
6!
7
<auth-constraint>!
8
<role-name>user</role-name>!
9
<role-name>admin</role-name>!
10
</auth-constraint>!
11 </security-constraint>!
12!
13 <login-config>!
14
<auth-method>FORM</auth-method>!
15
<form-login-config>!
16
<form-login-page>/login.jsp</form-login-page>!
17
<form-error-page>/loginerror.jsp</form-error-page>!
18
</form-login-config>!
19 </login-config>!

JAX-RS SecurityContext!
getAuthenticationScheme()!
Returns String authen?ca?on scheme used to protect
the resource
BASIC, FORM, CLIENT_CERT

getUserPrincipal()!
Returns Principal object containing the username

isUserInRole(String role)!
Returns a boolean indica?ng if the user has the specied
logical role

Photo Sharing Site


Demo

Photo Sharing Site API


h]p://www.sparklr.com:8080/sparklr2/photos?&format=json
!
{ "photos" : [
{ "id":"1"
{ "id":"3"
{ "id":"5"
}!

!
, "name":"photo1.jpg" } , !
, "name":"photo3.jpg" } , !
, "name":"photo5.jpg" }] !

Issues
Userid/password authen?ca?on is ne
If the API is used only by your site

But what if your API needs to be used by


Other web apps
Mobile apps
Na?ve apps

Do you want these apps to


Have your password?
Have full access to your account?
9

10

OAuth
Way to authen?cate a service
Valet key metaphor coined by Eran Hammer-Lahav

Authoriza?on token with limited rights


You agree which rights are granted
You can revoke rights at any ?me
Can gracefully upgrade rights if needed

11

OAuth Roles
Client

- Photo prin?ng service


called Tonr

User
- Person using the app
- Also known as the
"resource owner"

Server

- Photo sharing service


called Sparklr
- Also known as the
"resource server"

12

Simplied OAuth Flow


Client

User
1) You log in to Tonr

- Photo prin?ng service


called Tonr

2) Tonr needs pictures to print and


redirects you to Sparklr's log in page

Server

- Photo sharing service


called Sparklr

3) You log in to Sparklr directly


13

Simplied OAuth Flow


Client

User
6) You are happy
prin<ng and viewing
your pictures

- Photo prin?ng service


called Tonr

5) Tonr stores the "access token"


with your account

Server

- Photo sharing service


called Sparklr

4) Sparklr returns an OAuth


"access token"
14

Photo Prin?ng Site


Demo

15

Detailed OAuth Flow


1) Via browser: Tonr starts OAuth process
Once you click the "Authorize" bu]on
http://www.sparklr.com:8080/sparklr2/oauth/authorize?
client_id=tonr&redirect_uri=http://www.tonr.com:8080/
tonr2/sparklr/photos&
response_type=code&
scope=read write&state=92G53T

16

Detailed OAuth Flow


1) Via browser: Tonr starts OAuth process
Once you click the "Authorize" bu]on
http://www.sparklr.com:8080/sparklr2/oauth/authorize?
client_id=tonr&redirect_uri=http://www.tonr.com:8080/
tonr2/sparklr/photos&
response_type=code&
scope=read write&state=92G53T

17

Detailed OAuth Flow


2) Via browser: Sparklr redirects back to Tonr
http://www.tonr.com:8080/tonr2/sparklr/photos?
code=cOuBX6&state=92G53T

18

Detailed OAuth Flow


3) Via "Client": Tonr sends OAuth request to
Sparklr using client id/password
Request:
POST /sparklr2/oauth/token HTTP/1.1
Authorization: Basic dG9ucjpzZWNyZXQ=
grant_type=authorization_code&code=cOuBX6&
redirect_uri=http://www.tonr.com:8080/tonr2/sparklr/photos

Response:
{"access_token":"5881ce86-3ed0-4427-8a6b-42aef1068dfb",
"token_type":"bearer","expires_in":"42528",
"scope":"read write"}

19

Detailed OAuth Flow


3) Via "Client": Tonr sends OAuth request to
Sparklr using client id/password
Request:
POST /sparklr2/oauth/token HTTP/1.1
Authorization: Basic dG9ucjpzZWNyZXQ=
grant_type=authorization_code&code=cOuBX6&
redirect_uri=http://www.tonr.com:8080/tonr2/sparklr/photos

Response:
{"access_token":"5881ce86-3ed0-4427-8a6b-42aef1068dfb",
"token_type":"bearer","expires_in":"42528",
"scope":"read write"}

20

Detailed OAuth Flow


3) Via "Client": Tonr sends OAuth request to
Sparklr using client id/password
Request:
POST /sparklr2/oauth/token HTTP/1.1
Authorization: Basic dG9ucjpzZWNyZXQ=
grant_type=authorization_code&code=cOuBX6&
redirect_uri=http://www.tonr.com:8080/tonr2/sparklr/photos

Response:
{"access_token":"5881ce86-3ed0-4427-8a6b-42aef1068dfb",
"token_type":"bearer","expires_in":"42528",
"scope":"read write"}

21

Detailed OAuth Flow


3) Via "Client": Tonr sends OAuth request to
Sparklr using client id/password
Request:
POST /sparklr2/oauth/token HTTP/1.1
Authorization: Basic dG9ucjpzZWNyZXQ=
grant_type=authorization_code&code=cOuBX6&
redirect_uri=http://www.tonr.com:8080/tonr2/sparklr/photos

Response:
{"access_token":"5881ce86-3ed0-4427-8a6b-42aef1068dfb",
"token_type":"bearer","expires_in":"42528",
"scope":"read write"}

22

Detailed OAuth Flow


4) Via "Client": Tonr gets pictures from Sparklr
All Requests include:
Authorization: Bearer 5881ce86-3ed0-4427-8a6b-42aef1068dfb

23

When to Use OAuth


Use OAuth for consuming APIs from
Third-party web apps
Mobile apps
Na?ve apps

Don't need to use OAuth


If API is only consumed by the user within the
same web app
If APIs are only consumed server to server
24

Benets
No passwords shared between web apps
No passwords stored on mobile devices
Limits impact of security incidents
If Tonr gets hacked Sparklr revokes OAuth access
If Sparklr gets hacked you change your Sparklr
password but don't have to do anything on Tonr
If you lose your mobile device you revoke the
access Sparklr gave to the Tonr mobile app
25

OAuth Versions
Version

1.0
1.0a
2.0

Comments
- Has a security aw related to session xa?on
- Dont use it
- Stable and well understood
- Uses a signature to exchange creden?als and signs every request
- Signatures are more of a pain than it seems
- Spec is nal with good support

26

OAuth 2.0
Authoriza?on Grant Types
Grant Type

Descrip<on

Authoriza?on Code

- Op?mized for conden?al clients


- Uses a authoriza?on code from the Server
- User doesn't see the access token

Implicit Grant

- Op?mized for script heavy web apps


- Does not use an authoriza?on code from the Server
- User can see the access token

- Use in cases where the User trusts the Client


Resource Owner
Password Creden?als - Exposes User creden?als to the Client

Client Creden?als

- Client gets an access token based on Client creden?als


only

27

OAuth 2.0
Access Token Types
Bearer
Large random token
Need SSL to protect it in transit
Server needs to store it securely like a user
password

Mac
Uses a nonce to prevent replay
Does not require SSL
OAuth 1.0 only supported a mac type token
28

Outline

Authen?ca?on
Encryp?on
Valida?on
Wrap Up

29

Session Hijacking
mybank.com
Vic?m

Internet"

Public WiFi "


Network"

A]acker

1) Vic<m goes to mybank.com via HTTP

30

Session Hijacking
mybank.com
Vic?m

Internet"

Public WiFi "


Network"

A]acker

2) AMacker snis the public wi network and


steals the JSESSIONID

31

Session Hijacking
mybank.com
Vic?m

Internet"

Public WiFi "


Network"

A]acker

3) AMacker uses the stolen JSESSIONID


to access the vic<m's session

32

Enable SSL in web.xml


!
1 <security-constraint>!
2
<web-resource-collection>!
3
<web-resource-name>Example</web-resource-name>!
4
<url-pattern>/*</url-pattern>!
5
</web-resource-collection>!
6!
7
...!
8!
9
<user-data-constraint>!
10
<transport-guarantee>!
11
CONFIDENTIAL!
12
</transport-guarantee>!
13
</user-data-constraint>!
14 </security-constraint>!

33

JAX-RS SecurityContext!
iSecure()!
Returns a boolean indica?ng whether the
request was made via HTTPS

34

Secure Flag
Ensures that the Cookie is only sent via SSL
Congure in web.xml as of Servlet 3.0
<session-config>
<cookie-config>

<secure>true</secure>
</cookie-config>
</session-config>!

Programma?cally
Cookie cookie = new Cookie("mycookie", "test");!
cookie.setSecure(true);!

35

Strict-Transport-Security
Tells browser to only talk to the server via HTTPS
First ?me your site accessed via HTTPS and the header
is used the browser stores the cer?cate info
Subsequent requests to HTTP automa?cally use HTTPS

Supported browsers
Implemented in Firefox and Chrome
Dened in RFC 6797

Strict-Transport-Security:max-age=seconds
! ! ! ! ! ! ! ! ! [; includeSubdomains]!
36

Outline

Authen?ca?on
Encryp?on
Valida?on
Wrap Up

37

Restrict Input
Restrict to POST
Use @POST annota?on

Restrict the Content-Type


Use @Consumes({MediaType.APPLICATION_JSON})!
Invalid Content-Type results in HTTP 415 Unsupported Media Type

Restrict to Ajax if applicable


Check X-Requested-With:XMLHttpRequest header

Restrict response types


Check Accept header for valid response types
38

Cross-Site Request Forgery (CSRF)


Vic?m browser

1) Vic?m signs on to mybank


a]acker.com

2) Vic?m visits
a]acker.com

3) Page contains
CSRF code
<form ac?on=h]ps://mybank.com/transfer.jsp
method=POST>
<input name=recipient value=a]acker>
<input name=amount value=1000>
</form>
<script>document.forms[0].submit()</script>

mybank.com

4) Browser sends
the request to mybank
POST /transfer.jsp HTTP/1.1
Cookie: <mybank authen?ca?on cookie>
recipient=a]acker&amount=1000
39

CSRF and OAuth 2.0


How can an a]acker use CSRF to take over
your account?
Many sites allow logins from third-party iden?ty
providers like Facebook
Many iden?ty providers use OAuth
A]acker can automa?cally associate your account
with an a]acker controlled Facebook account


40

OAuth CSRF Research


Accounts at many sites could be taken over
using OAuth CSRF
Stack Exchange, woot.com, IMDB, Goodreads, SoundCloud, Pinterest,
Groupon, Foursquare, SlideShare, Kickstarter, and others

Research by Rich Lundeen


h]p://webstersprodigy.net/2013/05/09/common-oauth-issue-you-
can-use-to-take-over-accounts

Prior research by Stephen Sclafani


h]p://stephensclafani.com/2011/04/06/oauth-2-0-csrf-vulnerability


41

OAuth CSRF A]ack Flow


1) Create a]acker controlled Facebook account
2) Vic?m is signed on to provider account (i.e.
Stack Exchange)
3) Lure vic?m into visi?ng an evil site with
OAuth CSRF code
CSRF code sends OAuth authoriza?on request

4) A]acker's Facebook account now controls


vic?m provider account
42

Linking Stack Exchange with an


Evil Facebook Account

Image from h]p://webstersprodigy.net/2013/05/09/common-oauth-issue-you-can-use-to-take-over-accounts

43

CSRF Protec?on
Spec denes a "state" parameter that must be
included in the redirect to the Client
Value must be non-guessable and ?ed to session

Client sends "state" to Server:


http://www.sparklr.com:8080/sparklr2/oauth/authorize?
client_id=tonr&redirect_uri=http://www.eviltonr.com:8080/
tonr2/sparklr/photos&
response_type=code&
scope=read write&state=92G53T

Server sends "state" back to Client ater authoriza?on:


http://www.tonr.com:8080/tonr2/sparklr/photos?
code=cOuBX6&state=92G53T
44

OAuth CSRF Protec?on


Demo

45

OWASP 1-Liner
Deliberately vulnerable applica?on
Intended for demos and training
Created by John Wilander @johnwilander

More informa?on at
h]ps://www.owasp.org/index.php/OWASP_1-
Liner

46

JSON CSRF
Demo

47

Normal JSON Message



{"id":0,"nickName":"John",!
"oneLiner":"I LOVE Java!",!
"timestamp":"2013-05-27T17:04:23"}!

48

Forged JSON Message


!
{"id": 0, "nickName": "John",!
"oneLiner": "I hate Java!",!
"timestamp": "20111006"}//=dummy!

49

CSRF A]ack Form


<form id="target" method="POST"!
action="https://local.1-liner.org:8444/ws/
vulnerable/oneliners" !
enctype="text/plain" !
style="visibility:hidden">!
!
<input type="text" !
name='{"id": 0, "nickName": "John",!
"oneLiner": "I hate Java!",!
"timestamp": "20111006"}//' !
value="dummy" />!
!
<input type="submit" value="Go" />!
</form>!

50

CSRF A]ack Form


<form id="target" method="POST"!
action="https://local.1-liner.org:8444/ws/
vulnerable/oneliners" !
enctype="text/plain" !
style="visibility:hidden">!
!
<input type="text" !
name='{"id": 0, "nickName": "John",!
"oneLiner": "I hate Java!",!
"timestamp": "20111006"}//' !
value="dummy" />!
!
<input type="submit" value="Go" />!
</form>!

51

Forged JSON Message


!
{"id": 0, "nickName": "John",!
"oneLiner": "I hate Java!",!
"timestamp": "20111006"}//=dummy!

52

CSRF Defense
Must include something random in the request
Use an an?-CSRF token

OWASP CSRFGuard
Wri]en by Eric Sheridan @eric_sheridan
Can inject an?-CSRF token using
JSP Tag library - for manual, ne grained protec?on
JavaScript DOM manipula?on - for automated protec?on
requiring minimal eort

Filter that intercepts requests and validates tokens


53

CSRFGuard JSP Tags


Tags for token name and value
<form name="test1" action="protect.html">!
<input type="text" name="text" value="text"/>!
<input type="submit" name="submit" value="submit"/>!
<input type="hidden" name="<csrf:token-name/>"!
value="<csrf:token-value/>"/> !
</form>

Tag for name/value pair (delimited with "=")


<a href="protect.html?<csrf:token/>">protect.html</a>!

Convenience tags for forms and links as well


<csrf:form> and <csrf:a>!
!
Examples from h]ps://www.owasp.org/index.php/CSRFGuard_3_Token_Injec?on

54

CSRFGuard DOM Manipula?on


Include JavaScript in every page that needs CSRF protec?on
<script src="/securish/JavaScriptServlet"></script>!

JavaScript used to hook the open and send methods


XMLHttpRequest.prototype._open = XMLHttpRequest.prototype.open;!
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {!
// store a copy of the target URL!
this.url = url; !
this._open.apply(this, arguments);!
}!
!
XMLHttpRequest.prototype._send = XMLHttpRequest.prototype.send;!
XMLHttpRequest.prototype.send = function(data) {!
if(this.onsend != null) {!
// call custom onsend method to modify the request!
this.onsend.apply(this, arguments);!
}!
this._send.apply(this, arguments);!
}!

55

Protec?ng XHR Requests


CSRFGuard sends two HTTP headers
XMLHttpRequest.prototype.onsend = function(data) {!
if(isValidUrl(this.url)) {!
this.setRequestHeader("X-Requested-With", !
"OWASP CSRFGuard Project")!
this.setRequestHeader("OWASP_CSRFTOKEN", !
"EDTF-U8O6-J91L-RZOW-4X09-KEXB-K9B3-4OIV");!
}!
};!

56

JSON CSRF Protec?on


Demo

57

Outline

Authen?ca?on
Encryp?on
Valida?on
Wrap Up

58

Summary
Authen?ca?on

Can use userid/password for services consumed by


your app
Use OAuth for third-party web apps and mobile apps

Encryp?on

Use SSL
Use Secure ag
Use Strict-Transport-Security header

Valida?on

Restrict input
Protect your apps against CSRF
59

Thanks!
Frank Kim
wim@sans.org

@sansappsec

References
JAX-RS 2.0

h]p://jcp.org/en/jsr/detail?id=339
h]ps://jax-rs-spec.java.net/nonav/2.0/apidocs

OAuth 2.0 Specica?on

h]p://tools.iey.org/html/rfc6749
h]p://oauth.net

Spring Security OAuth

h]p://www.springsource.org/spring-security-oauth

OAuth: The Big Picture

h]p://pages.apigee.com/oauth-big-picture-ebook.html

OAuth CSRF issues

h]p://webstersprodigy.net/2013/05/09/common-oauth-issue-you-can-use-to-take-over-accounts
h]p://stephensclafani.com/2011/04/06/oauth-2-0-csrf-vulnerability

OWASP 1-Liner

h]ps://www.owasp.org/index.php/OWASP_1-Liner

CSRFGuard

h]ps://www.owasp.org/index.php/Category:OWASP_CSRFGuard_Project

h]p://ericsheridan.blogspot.com/2010/12/how-csrfguard-protects-ajax.html
62