Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Relaxing the Same Origin Policy

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers. →

Relaxing the Same Origin Policy

The Same Origin Policy is an important security layer for browsers, but in some case we need to deal with it and find a way to relax it.
This presentation describes 4 "standard" techniques to enable cross domain communication.

Presentation given to the RomaJS community in april 2014 (www.romajs.org)
Related source code with examples and playground available at https://github.com/marco-loche/RomaJS-SameOriginPolicyTalk

Avatar for Marco Loche

Marco Loche

April 23, 2014

More Decks by Marco Loche

Other Decks in Programming

Transcript

  1. ¡  A  mechanism  to  enforce  data  confidentiality   and  integrity.

      ¡  Pages  of  the  same  origin  can  manipulate   each  other's  DOM   ¡  Extended  to  other  aspects  :  HTTP  Cookies,   XMLHttpRequest  
  2. ¡  "origin"  of  a  URI  is  specified  in  RFC  6454,

      Section  4.   §  http://tools.ietf.org/html/rfc6454   ¡  For  HTML5     §  http://www.w3.org/TR/html5/browsers.html#origin   ¡   trusted  ===  {scheme,  host,  port}  
  3. §  http://www.example.com/index.html     ¡  Different  port   §  http://www.example.com:81/content/page2.html

      ¡  Different  protocol   §  https://www.example.com/content/page2.html   ¡  Different  Host  :  exact  matching  needed   §  http://api.example.com/content/page2.html   §  http://example.com/content/page2.html  
  4. Deal  with  the  policy!     ¡  document.domain  property  

    ¡  Cross-­‐document  messaging   ¡  JSONP   ¡  Cross-­‐Origin  Resource  Sharing  
  5. The  store  site  needs  to   acces  some  values  defined

      in  www  site     http://www.site1.local   http://store.site1.local   http://www.site1.local:3000/unrelaxed.html    
  6. http://www.site1.local:3000/relaxed.domain.html     <!DOCTYPE html>! <!--www.site1.local UNRELAXED-->! <html>! <head>! <title>Site

    1 - Unrelaxed</title>! <script>! var sensitiveValue = "SENSITIVE VALUE!”;! </script>! </head>! <body>! <h1>WWW Site 1</h1>! <p>This page demonstrate normal Same Origin Policy</p>! <iframe src="http:// store.site1.local:3000/index.html" name="store" style="height:400px"></ iframe>! </body>! </html>! http:///store.site1.local:3000/relaxed.domain.html     <!DOCTYPE html>! <!--store.site1.local-->! <html>! <head>! <title>Store Site 1</title>! </head>! <script>! function readInfo() {! alert('Accessing from '+location.host +' to a sensitive value ' + parent.sensitiveValue);! }! document.domain = 'site1.local';! </script>! <body>! <h1>Store Site 1</h1>! <input type="button" value="Read info" onclick="readInfo()">! </body>! </html>!
  7. ¡  All  modern  browsers  support   document.domain! ¡  BUT  

      §  Only  for  DOM  Access,  not  for  XHR   §  Only  if  applications  share  the  same  SLD   §  Can  be  interferred  by  other  application  in  same   SLD  (invoice.site1.local)   §  It’s  a  read/write  property  once  given  the  access     §  Do  not  use  it  in  shared  hosting  (as  w3c.org  says!)  
  8. SENDER   otherWindow.postMessage(! message, ! targetOrigin, ! [transfer]);! ! RECEIVER

      window.addEventListener(! !"message", ! !receiveMessage, ! !false); ! function receiveMessage(event) {! if (event.origin !== "http://example.org") ! !// DO STUFF HERE WITH event.data}!
  9.     ! ! function readInfo() {! parent.window.postMessage(! 'Give me

    sensitive value', ! 'http://www.site1.local:3000');! }! http://store.local:3000/relaxed.message.html    
  10.   sensitiveValue = "SENSITIVE VALUE!";! ! function receiver(event) {! if

    (event.origin == 'http://store.site1.local:3000’){! if (event.data == 'Give me sensitive value') {! event.source.postMessage(! ! sensitiveValue, event.origin);! alert(sensitiveValue);! }! }! }! window.addEventListener('message', receiver);! http://www.site1.local:3000/relaxed.message.html    
  11. ¡  www.caniuse.com/x-­‐doc-­‐messaging   ¡  BETTER:   §  2  actors  contract

      §  tabs/window  communication   ¡  BUT     §  Only  for  DOM  Access,  not  for  XHR   §  Risky  if  you  don’t    check  origin   §  Risky  if  you  don’t  check  the  expected  data  format   §  It’s  still  a  draft  
  12.   A  web  app  which  needs  to  access  a  REST

     API   http://www.site1.local   http://api.site2.local   GET !/messages!
  13. JSONP  relies  on  SOP  relaxing  for  <script>! ! <script !

    type="text/javascript" ! src="http://api.site2.local:3000/messages? callback=handleJsonp">! </script>!   Equivalent  to  :   ! <script type="text/javascript”>! !handleJsonp({ /** remote json data */ });! </script>!  
  14. JSONP  relies  on  SOP  relaxing  for  <script>! ! <script !

    type="text/javascript" ! src="http://api.site2.local:3000/messages? callback">! </script>!   Equivalent  to  :   ! <script type="text/javascript”>! ! { /** remote json data */ };! </script>!  
  15. ¡  It’s  allowed  by  SOP   ¡  Server  must  manage

     the  GET  parameter  callback to  generate  the  response ! ¡  COOL:   §  Supported  by  jQuery  (with  extended  features)     ▪  http://api.jquery.com/jquery.getjson/   §  Supported  by  ExpressJS     ▪  res.jsonp(object);!   ¡  BUT     §  Not  secure  :  browsers  accept  arbitrary  JS.   §  Incomplete  :  only  GET  
  16.   A  web  app  which  needs  to  access  a  REST

     API   http://www.site1.local   http://api.site2.local   GET !/messages! ! POST !/messages!
  17. ¡  W3C  Specification  (16  january  2014)   ¡  Enable  true

     cross  domain  communication  for   JavaScript  application   ¡  Build  on  top  of  the  XHR  
  18. CORS  Request   GET /cors HTTP/1.1 ! Origin: http://www.site1.local! Host:

    api.site2.local ! Accept-Language: en-US ! Connection: …! User-Agent: …! ! CORS  Response   Access-Control-Allow-Origin: http://www.site1.local! Access-Control-Allow-Credentials: true ! Content-Type: text/html; charset=utf-8!
  19. ¡  Complex  CORS  request     §  HTTP  verbs  :

     PUT  or  DELETE   §  Content-­‐Type     §  Custome  Headers   ¡  Preflight  request  +  actual  request  
  20. Preflight  CORS  Request   OPTIONS /cors HTTP/1.1 ! Origin: http://www.site1.local!

    Access-Control-Request-Method: PUT ! Access-Control-Request-Headers: X-Custom-Header! Host: api.site2.local ! Accept-Language: en-US ! Connection: …! User-Agent: …! ! Preflight  CORS  Response   Access-Control-Allow-Origin: http://www.site1.local! Access-Control-Allow-Methods: GET, POST, PUT ! Access-Control-Allow-Headers: X-Custom-Header! Access-Control-Max-Age: 3600! Content-Type: text/html; charset=utf-8!
  21. ActualCORS  Request   PUT /cors HTTP/1.1 ! Origin: http://www.site1.local! Host:

    api.site2.local ! X-Custom-Header: value! Accept-Language: en-US ! Connection: …! User-Agent: … !   Actual  CORS  Response   Access-Control-Allow-Origin: http://www.site1.local! Content-Type: text/html; charset=utf-8!
  22. Client  side:   ¡  Request  Object  Wrapper’s  Nicolas  Zakas  

    ¡  jQuery     Server  side:   ¡  ExpressJs  has  a  cors  module  
  23. ¡  Yes  some  :   ¡  Limitations  with  IE,  fully

      supported  by    IE  >=  10   ¡  http://caniuse.com/cors   ¡  Security  
  24. §  GO       §  Fork   §  Play

     !   §  Open  issues  for  comments  and  tak     https://github.com/marco-­‐loche/RomaJS-­‐SameOriginPolicyTalk    
  25. ¡  Intrested  ?  I’m  looking  for  Javascripter   ¡  join

     me  @capturator   §  Send  me  your  linkedin  profile   §  Send  me  your  github  profile