Security on Single Page Application (JakartaJS Apr 2014)

Security on Single Page Application (JakartaJS Apr 2014)

0fe18dfd87b3e48c0a45280e07cf96c6?s=128

Giovanni Sakti

April 30, 2014
Tweet

Transcript

  1. Hi, my name is Giovanni @giosakti - @starqle

  2. Today’s Topic

  3. Security on Single Page Application (SPA)

  4. 1. SPA Characteristic 2. SPA and API Server 3. Securing

    Client-Side Codes 4. Authentication 5. Authorization 6. Determine Your Needs
  5. SPA Characteristic 1/6

  6. SPA is “desktop” application that lives on the browser

  7. SPA makes use of heavy client-side scripting (js, dart, etc)

  8. ‘Normal’ web app Http Request

  9. ‘Normal’ web app Http Request Http Request Http Request

  10. SPA Http Request etc..

  11. SPA etc.. Http Request Http Request Http Request

  12. None
  13. SPA and API Server 2/6

  14. Http Request Http Request Client API Server

  15. Http Request Http Request Client API Server Have to be

    secured Have to be secured Have to be secured
  16. Securing Client-Side Codes 3/6

  17. Security 101 ! “Do not ever, ever trust the client”

  18. Security 101 ! “You can’t control what you don’t own”

  19. SPA characteristics makes more code available on the client

  20. How to Solve?

  21. Minify. Uglify. Mangle. ! Everything

  22. …function(){app.service(“Session”,["sessionStore","UserSession",function(a,b) {return this.signedIn=!!window.sessionStorage.getItem(a),this.signedOut=! this.signedIn,this.signedIn? (this.currentUser=JSON.parse(window.sessionStorage.getItem(a)).data,this.user Session=new b({login:this.currentUser.username,password:"",remember_me:! 1,auth_token:this.currentUser.authentication_token})): (this.currentUser=null,this.userSession=new b({login:"",password:"",remember_me:!

    1,auth_token:""})),this.putSessionData=function(c){return window.sessionStorage.setItem(a,JSON.stringify(c)),this.signedIn=! 0,this.signedOut=!this.signedIn,this.currentUser=c.data,this.userSession=new b({login:c.data.username,password:"",remember_me:! 1,auth_token:c.data.authentication_token}) },this.removeSessionData=function(){return window.sessionStorage.removeItem(a),this.signedIn=!1,this.signedOut=! this.signedIn,this.currentUser=null,this.userSession=new b({login:””,password:”",remember_me:! 1,auth_token:""})},this}])}.call(this),function(){app.constant("apiHost"... https://github.com/mishoo/UglifyJS
  23. Do Not ! Put Facebook / Twitter secret on your

    js / templates
  24. Authentication 4/6

  25. Don’t confuse between authentication and authorization

  26. None
  27. Authentication is the gateway

  28. None
  29. Authorization is the checkpoint after the gateway

  30. Common authentication methods

  31. Username and Password ! either love it or hate it..

  32. Token-based

  33. Two-factor: Use username/password and token

  34. Authentication Scheme

  35. ‘Normal’ web app Send login & password Track States Track

    session, return cookies Http request, put cookie in request header Return HTML
  36. SPA Track States

  37. SPA Track States Http request, send login & password Return

    JSON Http request, send login & password Return JSON
  38. SPA Track States Http request, send login & password Return

    JSON Http request, send login & password Return JSON wow much bad
  39. SPA Track States Send login & password Return expirable auth

    code Http request, send expirable auth code Return JSON Variant 1
  40. Where to store those expirable auth codes?

  41. cookies ! always get sent on every request for same

    domain Have maximum size of 4096K Usually gets deleted when the browser is closed or when expiration date is set ! document.cookie  =  “auth_key=12345678;  expires=….”
  42. HTML5 sessionStorage ! Do not get sent with request Have

    maximum size of around ~5mb Gets deleted when the tab/window is closed ! sessionStorage.setItem(‘auth_key’,’12345678’)
  43. HTML5 localStorage ! Do not get sent with request Have

    maximum size of around ~5mb Can be stored forever as long as you don’t uninstall your browser ! localStorage.setItem(‘auth_key’,’12345678’)
  44. Examples

  45.    UserSession::$save  =  -­‐>          $http.post  apiHost

     +  "users/sign_in",              data:                  login:  @login                  password:  @password                  remember_me:  (if  @remember_me  then  1  else  0)
  46.    def  create          #  Find  the

     login  on  the  db          resource  =  resource_class.find_for_database_authentication(login:   params[:data][:login])          raise  "Invalid  login  or  password"  if  resource.nil?   !        #  If  login  is  found,  continue  with  password  verification          password_valid  =  resource.valid_password?(params[:data][:password])          raise  "Invalid  login  or  password"  unless  password_valid   !        #  Create  authentication  information          create_authentication!(resource)   !        #  Render  the  response          render  json:  resource,                serializer:  Api::SessionSerializer,              status:  201  #  created      end
  47.    #  Function  for  storing  session  data      @putSessionData

     =  (sessionData)  -­‐>          window.sessionStorage.setItem(sessionStore,   JSON.stringify(sessionData))   !        @signedIn  =  true          @signedOut  =  not  @signedIn          @currentUser  =  sessionData.data          @userSession  =  new  UserSession(              login:  sessionData.data.username              password:  ""              remember_me:  false              auth_token:  sessionData.data.authentication_token          )
  48.    #  Wrap  an  action  in  a  resource  with  auth_token

         #  Treat  each  kind  of  action  accordingly      tokenWrapper  =  (resource,  action)  -­‐>          resource['_'  +  action]  =  resource[action]   !        if  action  in  ['save',  'update']              resource[action]  =  (params,  data,  success,  error)  -­‐>                  resource['_'  +  action]  angular.extend({},  params  or  {},                      username:  authTokenHandler.getUsername()                      auth_token:  authTokenHandler.getAuthToken()                  ),  data,  success,  error          else              resource[action]  =  (params,  success,  error)  -­‐>                  resource["_"  +  action]  angular.extend({},  params  or  {},                      username:  authTokenHandler.getUsername()                      auth_token:  authTokenHandler.getAuthToken()                  ),  success,  error
  49. Track States Send login & password Return expirable auth code

    Http request, send expirable auth code & permanent identifier Return JSON Variant 2 Return permanent identifier Expirable auth code can be stored on sessionStorage ! Permanent identifier can be stored on localStorage
  50. Authorization 5/6

  51. Selective Data Access ! .. This only happens on the

    API Server
  52. id: 1, name: giovanni id: 2, name: john id: 3,

    name: robert id: 4, name: sean id: 5, name: roger id: 1, name: giovanni id: 3, name: robert id: 5, name: roger Logged  in  as  John,   John  is  staff
  53. id: 1, name: giovanni id: 2, name: john id: 3,

    name: robert id: 4, name: sean id: 5, name: roger id: 1, name: giovanni id: 2, name: john id: 3, name: robert id: 4, name: sean id: 5, name: roger Logged  in  as  Giovanni,   John  is  admin
  54. id: 1, name: giovanni id: 2, name: john id: 3,

    name: robert id: 4, name: sean id: 5, name: roger 403 forbidden Not  logged  in
  55. Selective View Access ! This can happens only on the

    client or both the client and the API server
  56. If you chose to do it only on the client..

    Http Request send everything + { access: [‘viewDashboard’, ‘viewUsers’] }
  57. If you chose to do it both on the server

    and client (more secure) Http Request send only necessary templates Can i access dashboard? send dashboard-related templates
  58. Determine Your Needs 6/6

  59. That was too much work..!

  60. Okay, you don’t actually have to do everything..

  61. Create a heuristic to determine your app information sensitiveness

  62. 1. Can guests see all views? - Concern => send

    ping to server 1st - Not a concern => store authorization on client ! 2. Are many of your users access your app from public/shared pc? - Quick Session timeout - Disable ‘remember me’ feature …
  63. … 3. Are your applications utilize very sensitive information ?

    (e.g. credit cards, etc) - Do not store it on client. ever. - https for transaction is a must! - 3rd party payment tools ! 4. Are your applications have separate admin area to control the whole application? - Use separate domain for the admin area. Or better yet, different server too - Obsfucate the url. http://app.com/xyzabc rather than http:// app.com/admin …
  64. Conclusion

  65. The thing about security is..

  66. .. understanding of its importance only happens after the damage

    was done.
  67. Thanks! @giosakti - @starqle