Your SlideShare is downloading. ×
0
CORS and Javascript
Integration in the browser
Michael Neale
@michaelneale

Friday, 25 October 13
Integration in the browser
Lots of services, microservices
Everything has an API
JSON == lingua franca
Why have servers th...
For example

Friday, 25 October 13
JSON !!111

App service
Friday, 25 October 13

repos

CI server
but - same origin policy?

http://en.wikipedia.org/wiki/Same-origin_policy
Friday, 25 October 13
but - same origin policy?
Web security model - not bad track record.
Not going to change... so, how to work around:

Frida...
integration middleware?

Friday, 25 October 13
Overkill

Friday, 25 October 13
JSON-P
Add “padding”.
JSON P: take pure json, make it a function call - then
eval it in the browser.
Same Origin Policy do...
jsonp: Most glorious hack
ever

Friday, 25 October 13
JSON-P
JSON: { “foo” : 42 }
JSONP: callback({ “foo” : 42 });
Widely supported (both by servers and of course
jquery & co m...
direct to origin:
$.ajax({
dataType : "json"
...
});

Friday, 25 October 13
JSON-P cross domain
$.ajax({
dataType : "jsonp",
jsonp:'jsonp'
....
});

Friday, 25 October 13
JSON-P
What it is really doing: creating script tags, and
making your browser “eval” the lot. Each time, each
request.
Don...
JSON-P
Really misses the “spirit” of same-origin.
Security holes: any script you bring in has access to
your data/dom/priv...
JSON-P
Also, JSON is not Javascript
JSON can be safely read - no eval
JSON-P only eval
JSONP is GET only

Friday, 25 Octob...
CORS
http://en.wikipedia.org/wiki/Crossorigin_resource_sharing
Allows servers to specify who/what can access
endpoint dire...
CORS

Friday, 25 October 13
NOT THESE:

Friday, 25 October 13

Oy, they’re my sisters yer lookin at
CORS
Trivial to consume: plain web calls, direct.
Complexity: on the server/config side.
Browser support: complete(ish):
ht...
CORS - client side ex.
$.ajax({
dataType : "json",
xhrFields: {
withCredentials: true
}
...
});

Friday, 25 October 13
How it works
Most work is between browser and server, via http
headers.
“Pre flight checks”:
Browser passes Origin header t...
How it works
browser

server
http OPTIONS (Origin: http://boo.com)
Access-Control-Allow.... etc

preflight

direct http GET...
How it works
“Pre flight checks”:
Performed by browser, opaque to client app.
Browser enforces. You don’t see them.
Uses “O...
Security Theatre?
“Pre flight checks”:
Can be just an annoyance.
Access-Control-Allow-Origin: *

Downside: allows any scrip...
Common pattern
Access-Control-Allow-Origin: $origin-from-request

The returned value is really echoing back what Origin
wa...
Middleware
All app server environments have a way to do the
Right Thing with CORS headers:
Rack-cors: ruby
Servlet-filter: ...
Other CORS headers
Access-Control-Allow-Headers (headers to be
included in requests)
Access-Control-Allow-Methods: GET, PU...
Authorization
You can use per request tokens, eg OAuth
OpenID and OAuth based sessions will work
(browser has done redirec...
Authorization
requests
authorization your app
identity/auth
pre-flight

Friday, 25 October 13

browser
Debugging
Pesky pre-flight checks are often opaque - may
show up as “cancelled” requests without a reason.
Use chrome://net...
Debugging
Following screen cap shows it working...
note the match between Origin and Access-control if you don’t see those...
Friday, 25 October 13
Friday, 25 October 13
Debugging
t=1374052796709 [st=262]
t=1374052796709 [st=262]
t=1374052796709 [st=262]

+URL_REQUEST_BLOCKED_ON_DELEGATE
CAN...
My Minimal Setup
 Access-Control-Allow-Methods: GET, POST, PUT, DELETE
 Access-Control-Allow-Credentials: true
Access-Cont...
Example (express)
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Acce...
Example (rack/ruby)
gem install rack-cors
...
in config/application.rb:
...
config.middleware.use Rack::Cors do
allow do
o...
Read more
enable-cors.org

Friday, 25 October 13
Thank you

Michael Neale
https://twitter.com/michaelneale
https://developer-blog.cloudbees.com

Friday, 25 October 13
Upcoming SlideShare
Loading in...5
×

Cross site calls with javascript - the right way with CORS

8,987

Published on

Using CORS (cross origin resource sharing) you can easily and securely to cross site scripting in webapps - less servers and more integration from apis right in the browser

This was presented during Web Directions South, 2013, Sydney, Australia.

Published in: Technology, Business

Transcript of "Cross site calls with javascript - the right way with CORS"

  1. 1. CORS and Javascript Integration in the browser Michael Neale @michaelneale Friday, 25 October 13
  2. 2. Integration in the browser Lots of services, microservices Everything has an API JSON == lingua franca Why have servers that are just text pumps: Integrate into new apps in the browser Friday, 25 October 13
  3. 3. For example Friday, 25 October 13
  4. 4. JSON !!111 App service Friday, 25 October 13 repos CI server
  5. 5. but - same origin policy? http://en.wikipedia.org/wiki/Same-origin_policy Friday, 25 October 13
  6. 6. but - same origin policy? Web security model - not bad track record. Not going to change... so, how to work around: Friday, 25 October 13
  7. 7. integration middleware? Friday, 25 October 13
  8. 8. Overkill Friday, 25 October 13
  9. 9. JSON-P Add “padding”. JSON P: take pure json, make it a function call - then eval it in the browser. Same Origin Policy doesn’t apply to resource loading (script tags) Friday, 25 October 13
  10. 10. jsonp: Most glorious hack ever Friday, 25 October 13
  11. 11. JSON-P JSON: { “foo” : 42 } JSONP: callback({ “foo” : 42 }); Widely supported (both by servers and of course jquery & co make it transparent) Friday, 25 October 13
  12. 12. direct to origin: $.ajax({ dataType : "json" ... }); Friday, 25 October 13
  13. 13. JSON-P cross domain $.ajax({ dataType : "jsonp", jsonp:'jsonp' .... }); Friday, 25 October 13
  14. 14. JSON-P What it is really doing: creating script tags, and making your browser “eval” the lot. Each time, each request. Don’t think too hard about it... Friday, 25 October 13
  15. 15. JSON-P Really misses the “spirit” of same-origin. Security holes: any script you bring in has access to your data/dom/private parts. How secure is server serving up json-p? Friday, 25 October 13
  16. 16. JSON-P Also, JSON is not Javascript JSON can be safely read - no eval JSON-P only eval JSONP is GET only Friday, 25 October 13
  17. 17. CORS http://en.wikipedia.org/wiki/Crossorigin_resource_sharing Allows servers to specify who/what can access endpoint directly Use plain JSON, ALL HTTP Verbs: PUT, DELETE etc Friday, 25 October 13
  18. 18. CORS Friday, 25 October 13
  19. 19. NOT THESE: Friday, 25 October 13 Oy, they’re my sisters yer lookin at
  20. 20. CORS Trivial to consume: plain web calls, direct. Complexity: on the server/config side. Browser support: complete(ish): http://enable-cors.org/ All verbs, all data types Friday, 25 October 13
  21. 21. CORS - client side ex. $.ajax({ dataType : "json", xhrFields: { withCredentials: true } ... }); Friday, 25 October 13
  22. 22. How it works Most work is between browser and server, via http headers. “Pre flight checks”: Browser passes Origin header to server: Origin: http://www.example-social-network.com Server responds (header) saying what is allowed: Access-Control-Allow-Origin: http://www.example-social-network.com Friday, 25 October 13
  23. 23. How it works browser server http OPTIONS (Origin: http://boo.com) Access-Control-Allow.... etc preflight direct http GET /POST (as allowed by Access headers) ... Friday, 25 October 13 your app
  24. 24. How it works “Pre flight checks”: Performed by browser, opaque to client app. Browser enforces. You don’t see them. Uses “OPTION” http verb. Friday, 25 October 13
  25. 25. Security Theatre? “Pre flight checks”: Can be just an annoyance. Access-Control-Allow-Origin: * Downside: allows any script with right creds to pull data from you (do you want this? Think, as always) Friday, 25 October 13
  26. 26. Common pattern Access-Control-Allow-Origin: $origin-from-request The returned value is really echoing back what Origin was - checked off against a whitelist: Server needs to know whitelist, how to check, return value dynamically. Not a static web server config. SAD FACE. Friday, 25 October 13
  27. 27. Middleware All app server environments have a way to do the Right Thing with CORS headers: Rack-cors: ruby Servlet-filter: java Node: express middleware etc... (it isn’t hard, just not as easy as it should be) http://stackoverflow.com/questions/7067966/how-to-allowcors-in-express-nodejs Friday, 25 October 13
  28. 28. Other CORS headers Access-Control-Allow-Headers (headers to be included in requests) Access-Control-Allow-Methods: GET, PUT, POST, DELETE etc Access-Control-Allow-Credentials: boolean (lists always comma separated) Friday, 25 October 13
  29. 29. Authorization You can use per request tokens, eg OAuth OpenID and OAuth based sessions will work (browser has done redirect “dance” - AccessControl-Allow-Credentials: true -- needed to ensure cookies/auth info flows with requests) Friday, 25 October 13
  30. 30. Authorization requests authorization your app identity/auth pre-flight Friday, 25 October 13 browser
  31. 31. Debugging Pesky pre-flight checks are often opaque - may show up as “cancelled” requests without a reason. Use chrome://net-internals/#events Friday, 25 October 13
  32. 32. Debugging Following screen cap shows it working... note the match between Origin and Access-control if you don’t see those headers in response something is wrong. Friday, 25 October 13
  33. 33. Friday, 25 October 13
  34. 34. Friday, 25 October 13
  35. 35. Debugging t=1374052796709 [st=262] t=1374052796709 [st=262] t=1374052796709 [st=262] +URL_REQUEST_BLOCKED_ON_DELEGATE CANCELLED -URL_REQUEST_START_JOB --> net_error = -3 (ERR_ABORTED) [dt=0] This is it failing: look for “cancelled”. Could be due to incorrect headers returned, or perhaps Authorization failures (cookies, session etc) Friday, 25 October 13
  36. 36. My Minimal Setup  Access-Control-Allow-Methods: GET, POST, PUT, DELETE  Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: $ORIGIN $ORIGIN = if (inWhitelist(requestOriginHeader) return requestOriginHeader INCLUDE PORTS IN Access-Control-Allow-Origin!! Friday, 25 October 13
  37. 37. Example (express) app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "X-Requested-With"); next(); }); node and express js: http://enable-cors.org/server_expressjs.html Friday, 25 October 13
  38. 38. Example (rack/ruby) gem install rack-cors ... in config/application.rb: ... config.middleware.use Rack::Cors do allow do origins '*' resource '*', :headers => :any, :methods => [:get, :post, :options] end end https://github.com/cyu/rack-cors Friday, 25 October 13
  39. 39. Read more enable-cors.org Friday, 25 October 13
  40. 40. Thank you Michael Neale https://twitter.com/michaelneale https://developer-blog.cloudbees.com Friday, 25 October 13
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×