Download - Cors michael
CORS and JavascriptIntegration in the browser
Michael Neale@michaelneale
developer.cloudbees.com
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
Thursday, 12 September 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
Thursday, 12 September 13
For example
Thursday, 12 September 13
CI serverApp service
JSON !!111
repos
Thursday, 12 September 13
but - same origin policy?
http://en.wikipedia.org/wiki/Same-origin_policy
Thursday, 12 September 13
same origin policy
Thursday, 12 September 13
but - same origin policy?
Web security model - not bad track record.
Not going to change... so, how to work around:
Thursday, 12 September 13
integration middleware?
Thursday, 12 September 13
Overkill
Thursday, 12 September 13
JSON-P
All JSON world - add “padding”.
JSON P: take pure json, make it a function call - then eval it.
Single Origin policy doesn’t apply to resource loading
Thursday, 12 September 13
jsonp: Most glorious hack ever
Thursday, 12 September 13
JSON-P
JSON: { “foo” : 42 }
JSONP: callback({ “foo” : 42 });
Widely supported (both by servers and of course jquery makes it transparent)
Thursday, 12 September 13
JSON-P
What it is really doing: creating script tags, and making your browser “eval” the lot. Each time.
Don’t think too hard about it...
Thursday, 12 September 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?
Thursday, 12 September 13
JSON-P
Also, JSON is not Javascript
JSON can be safely read - no eval
JSON-P only eval
JSONP is GET only
Thursday, 12 September 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
Thursday, 12 September 13
CORS
Thursday, 12 September 13
Oy, they’re my sisters yer lookin atNOT THESE:
Thursday, 12 September 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
Thursday, 12 September 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
Thursday, 12 September 13
How it worksbrowser server
http OPTIONS (Origin: http://boo.com)
Access-Control-Allow.... etc
direct http GET (as allowed by Access headers)
...
pre-flight
your app
Thursday, 12 September 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.
Thursday, 12 September 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)
Thursday, 12 September 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.
Thursday, 12 September 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
Thursday, 12 September 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)
Thursday, 12 September 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)
Thursday, 12 September 13
Authorization
requests
authorization
identity/auth
pre-flight
your app
browser
Thursday, 12 September 13
DebuggingPesky pre-flight checks are often opaque - may show up as “cancelled” requests without a reason.
Use chrome://net-internals/#events
Thursday, 12 September 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.
Thursday, 12 September 13
Thursday, 12 September 13
Thursday, 12 September 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)
Thursday, 12 September 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!!
Thursday, 12 September 13
Servlet Filter
https://github.com/cloudbees/cors-plugin/blob/master/src/main/java/org/jvnet/hudson/plugins/
cors/JenkinsCorsFilter.java
Thursday, 12 September 13
Thank you
Michael Nealehttps://twitter.com/michaelneale
https://developer-blog.cloudbees.com
Thursday, 12 September 13