640 likes | 781 Views
REST Security with JAX-RS. JavaOne 2013. About. Frank Kim SANS Institute Curriculum Lead, Application Security Author, Secure Coding in Java. Outline. Authentication Encryption Validation Wrap Up. Authentication. Process of establishing and verifying an identity
E N D
REST Security with JAX-RS JavaOne 2013
About • Frank Kim • SANS Institute • Curriculum Lead, Application Security • Author, Secure Coding in Java
Outline • Authentication • Encryption • Validation • Wrap Up
Authentication • Process of establishing and verifying an identity • Can be based on three factors • Something you know • Something you have • Something you are
Java EE Authentication • Configuration 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 authentication scheme used to protect the resource • BASIC, FORM, CLIENT_CERT • getUserPrincipal() • Returns Principal object containing the username • isUserInRole(String role) • Returns a boolean indicating if the user has the specified logical role
Photo Sharing Site Demo
Photo Sharing Site API http://www.sparklr.com:8080/sparklr2/photos?&format=json { "photos" : [ { "id":"1" , "name":"photo1.jpg" } , { "id":"3" , "name":"photo3.jpg" } , { "id":"5" , "name":"photo5.jpg" }] }
Issues • Userid/password authentication is fine • If the API is used only by your site • But what if your API needs to be used by • Other web apps • Mobile apps • Native apps • Do you want these apps to • Have your password? • Have full access to your account?
OAuth • Way to authenticate a service • Valet key metaphor coined by Eran Hammer-Lahav • Authorization token with limited rights • You agree which rights are granted • You can revoke rights at any time • Can gracefully upgrade rights if needed
OAuth Roles Client - Photo printing service called Tonr User - Photo sharing service called Sparklr - Also known as the "resource server" Server - Person using the app - Also known as the "resource owner"
Simplified OAuth Flow Client - Photo printing service called Tonr 2) Tonr needs pictures to print and redirects you to Sparklr's log in page User Server 1) You log in to Tonr - Photo sharing service called Sparklr 3) You log in to Sparklr directly
Simplified OAuth Flow Client - Photo printing service called Tonr 5) Tonr stores the "access token" with your account User Server 6) You are happy printing and viewing your pictures - Photo sharing service called Sparklr 4) Sparklr returns an OAuth "access token"
Photo Printing Site Demo
Detailed OAuth Flow • Via browser: Tonr starts OAuth process • Once you click the "Authorize" button 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
Detailed OAuth Flow • Via browser: Tonr starts OAuth process • Once you click the "Authorize" button 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
Detailed OAuth Flow 2) Via browser: Sparklr redirects back to Tonr http://www.tonr.com:8080/tonr2/sparklr/photos? code=cOuBX6&state=92G53T
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"}
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"}
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"}
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"}
Detailed OAuth Flow 4) Via "Client": Tonr gets pictures from Sparklr All Requests include: Authorization: Bearer 5881ce86-3ed0-4427-8a6b-42aef1068dfb
When to Use OAuth • Use OAuth for consuming APIs from • Third-party web apps • Mobile apps • Native 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
Benefits • 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
OAuth 2.0 Access Token Types • Bearer • Large random token • Need SSL to protect it in transit • Server needs to store it securely hashed like a user password • Mac • Uses a nonce to prevent replay • Does not require SSL • OAuth 1.0 only supported a mac type token
Outline • Authentication • Encryption • Validation • Wrap Up
Session Hijacking Internet mybank.com Public WiFi Network Victim 1) Victim goes to mybank.com via HTTP Attacker
Session Hijacking Internet mybank.com Public WiFi Network Victim 2) Attacker sniffs the public wifi network and steals the JSESSIONID Attacker
Session Hijacking Internet mybank.com Public WiFi Network Victim 3) Attacker uses the stolen JSESSIONID to access the victim's session Attacker
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>
JAX-RS SecurityContext • iSecure() • Returns a boolean indicating whether the request was made via HTTPS
Secure Flag • Ensures that the Cookie is only sent via SSL • Configure in web.xml as of Servlet 3.0 <session-config> <cookie-config><secure>true</secure> </cookie-config></session-config> • Programmatically Cookie cookie = new Cookie("mycookie", "test"); cookie.setSecure(true);
Strict-Transport-Security • Tells browser to only talk to the server via HTTPS • First time your site accessed via HTTPS and the header is used the browser stores the certificate info • Subsequent requests to HTTP automatically use HTTPS • Supported browsers • Implemented in Firefox and Chrome • Defined in RFC 6797 Strict-Transport-Security: max-age=seconds [; includeSubdomains]
Outline • Authentication • Encryption • Validation • Wrap Up
Restrict Input • Restrict to POST • Use @POSTannotation • 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
Cross-Site Request Forgery (CSRF) Victim browser 1) Victim signs on to mybank 2) Victim visits mybank.com attacker.com attacker.com 3) Page contains CSRF code 4) Browser sends <form action=https://mybank.com/transfer.jsp method=POST> <input name=recipient value=attacker> <input name=amount value=1000> </form> <script>document.forms[0].submit()</script> the request to mybank POST /transfer.jsp HTTP/1.1 Cookie: <mybank authentication cookie> recipient=attacker&amount=1000
CSRF and OAuth 2.0 • How can an attacker use CSRF to take over your account? • Many sites allow logins from third-party identity providers like Facebook • Many identity providers use OAuth • Attacker can automatically associate your account with an attacker controlled Facebook account
OAuth CSRF Research • Accounts at many sites could be taken over using OAuthCSRF • Stack Exchange, woot.com, IMDB, Goodreads, SoundCloud, Pinterest, Groupon, Foursquare, SlideShare, Kickstarter, and others • Research by Rich Lundeen • http://webstersprodigy.net/2013/05/09/common-oauth-issue-you-can-use-to-take-over-accounts • Prior research by Stephen Sclafani • http://stephensclafani.com/2011/04/06/oauth-2-0-csrf-vulnerability
OAuth CSRF Attack Flow • Create attacker controlled Facebook account • Victim is signed on to provider account (i.e. Stack Exchange) • Lure victim into visiting an evil site with OAuth CSRF code • CSRF code sends OAuth authorization request 4) Attacker's Facebook account now controls victim provider account
Linking Stack Exchange with an Evil Facebook Account • Image from http://webstersprodigy.net/2013/05/09/common-oauth-issue-you-can-use-to-take-over-accounts
CSRF Protection • Spec defines a "state" parameter that must be included in the redirect to the Client • Value must be non-guessable and tied 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 after authorization: http://www.tonr.com:8080/tonr2/sparklr/photos? code=cOuBX6&state=92G53T
OWASP 1-Liner • Deliberately vulnerable application • Intended for demos and training • Created by John Wilander @johnwilander • More information at • https://www.owasp.org/index.php/OWASP_1-Liner
JSON CSRF Demo
Normal JSON Message {"id":0,"nickName":"John", "oneLiner":"I LOVE Java!", "timestamp":"2013-05-27T17:04:23"}
Forged JSON Message {"id": 0, "nickName": "John", "oneLiner": "I hate Java!", "timestamp": "20111006"}//=dummy
CSRF Attack 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>