Upload
michael-neale
View
5.506
Download
6
Embed Size (px)
DESCRIPTION
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.
Citation preview
CORS and JavascriptIntegration in the browser
Michael Neale@michaelneale
Friday, 25 October 13
Integration in the browser
Lots of services, microservicesEverything has an APIJSON == lingua franca
Why have servers that are just text pumps:Integrate into new apps in the browser
Friday, 25 October 13
For example
Friday, 25 October 13
CI serverApp service
JSON !!111
repos
Friday, 25 October 13
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:
Friday, 25 October 13
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 doesn’t apply to resource loading (script tags)
Friday, 25 October 13
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 make it transparent)
Friday, 25 October 13
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’t think too hard about it...
Friday, 25 October 13
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
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
CORS
http://en.wikipedia.org/wiki/Cross-origin_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
CORS
Friday, 25 October 13
Oy, they’re my sisters yer lookin atNOT THESE:
Friday, 25 October 13
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
CORS - client side ex.
$.ajax({ dataType : "json",
xhrFields: { withCredentials: true } ...
});
Friday, 25 October 13
How it worksMost 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
How it worksbrowser server
http OPTIONS (Origin: http://boo.com)
Access-Control-Allow.... etc
direct http GET /POST (as allowed by Access headers)
...
pre-flight
your app
Friday, 25 October 13
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
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
Common patternAccess-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
MiddlewareAll app server environments have a way to do the Right Thing with CORS headers:
Rack-cors: rubyServlet-filter: javaNode: express middlewareetc...
(it isn’t hard, just not as easy as it should be)http://stackoverflow.com/questions/7067966/how-to-allow-cors-in-express-nodejs
Friday, 25 October 13
Other CORS headersAccess-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
AuthorizationYou can use per request tokens, eg OAuth
OpenID and OAuth based sessions will work
(browser has done redirect “dance” - Access-Control-Allow-Credentials: true -- needed to ensure cookies/auth info flows with requests)
Friday, 25 October 13
Authorization
requests
authorization
identity/auth
pre-flight
your app
browser
Friday, 25 October 13
DebuggingPesky pre-flight checks are often opaque - may show up as “cancelled” requests without a reason.
Use chrome://net-internals/#events
Friday, 25 October 13
DebuggingFollowing 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
Friday, 25 October 13
Friday, 25 October 13
Debuggingt=1374052796709 [st=262] +URL_REQUEST_BLOCKED_ON_DELEGATE [dt=0]t=1374052796709 [st=262] CANCELLEDt=1374052796709 [st=262] -URL_REQUEST_START_JOB --> net_error = -3 (ERR_ABORTED)
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
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
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
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
Read more
enable-cors.org
Friday, 25 October 13
Thank you
Michael Nealehttps://twitter.com/michaelneale
https://developer-blog.cloudbees.com
Friday, 25 October 13