web security - cookies, domains and cors
DESCRIPTION
The presentation tells about performing cross domain ajax request. Subject included principles of preflight requests and limitations of cross origin resource sharing (CORS) policy. You will be able to find implementation examples for frontend (JavaScript, jQuery, AngularJS) and for backend (.Net, Ruby on Rails). Browser compatibility is covered in section ‘Limitation in IE 8,9‘ and there shown possible workarounds. And finally there are couple words about Content Security Policy – the latest approach in Web Application Security.TRANSCRIPT
What’s all about?
● Same-origin policy ● Cross domain requests use-cases ● Making requests with XHTTPRequest● CSRF attacks● Simple and not-so-simple requests● Cross-domain limitations & Access Control ● Back-end implementation examples● Limitation in Internet Explorer 8, 9● Workarounds (proxy, JSONP)● Content Security Policy
URL1 origin = URL2 origin
⇔
scheme, host and port are
equal
Exceptions:
• link
• img
• iframe
• object
• scripthttp://en.wikipedia.org/wiki/Same-origin_policy
http://
username:pass@
sub.domain.com
:8080
/folder/index.html
?id=42&action=add
#first-section
URI↓
URL
scheme
authorizatio
n
host
port
path
query
fragment idhttp://username:[email protected]:8080/folder/index.html?
id=42&action=add#first-section
Same-origin policy
• Share buttons
• Visitors analytics
• Advertisments
• Maps
• Payment systems
• REST API
• Shared services
Use cases
Requests with XHTTPRequest 2Plain JavaScript
CODE
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", transferSuccessful, false);
xhr.open(method, url, async, user, password);
xhr.send(data);
//for compatibility with XHTTPRequest v1xhr.onreadystatechange = function (req) {
if (req.readyState != 4) return; if (req.status == 200 || req.status == 304) { promise.success([req]); } else { promise.fail([req]); }};
12345678910111213141516171819
Requests with XHTTPRequest 2 - EventsPlain JavaScript
CODE
var xhr = new XMLHttpRequest();
xhr.addEventListener("progress" , updateProgress , false);xhr.addEventListener("error" , transferFailed , false);xhr.addEventListener("abort" , transferCanceled , false);xhr.addEventListener("load" , transferSuccessful , false);xhr.addEventListener("loadstart", transferStart , false);xhr.addEventListener("loadend" , transferEnd , false);xhr.addEventListener("timeout" , transferTimeout , false);
xhr.withCredentials = true;
xhr.open(method, url, async, user, password);
xhr.send(data);
123456789101112131415
Requests with XHTTPRequest 2jQuery
CODE
$.ajax(url, {xhrFields: { withCredentials: true } }) .done(callback);
//Persistent: $.ajaxPrefilter( function( options, originalOptions, jqXHR ) {
options.xhrFields = { withCredentials: true }; });
1234567891011121314
Requests with XHTTPRequest 2AngularJS
CODE
myApp.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.withCredentials = true;
$httpProvider.defaults.useXDomain = true;
delete $httpP~.defaults.headers.common['X-Requested-With'];
}]);
123456789
Hacking time!
What’s all about?
● Same-origin policy ● Cross domain requests use-cases ● Making requests with XHTTPRequest● CSRF attacks● Simple and not-so-simple requests● Cross-domain limitations & Access Control ● Back-end implementation examples● Limitation in Internet Explorer 8, 9● Workarounds (proxy, JSONP)● Content Security Policy
• Only GET, HEAD or
POST
• No custom headers
• Content-Type onlyapplication/x-www-form-urlencoded,
multipart/form-data, or text/plain
• All other will have
preflighted request
Not-so-simple andsimple requestshttp OPTIONS (Origin:
http://example.com:81)
200 Access-Control-Allow- ...
direct GET/POST/PUT/DELETE request
as allowed by access headers
pre
flig
hte
d
app
lica
tio
n
• Request always contains
an Origin
• Allow-Origin can be * for
read requests
• For modify requests it
should be set manually
• Allow-Origin can’t be *
with Allow-Credentials:
true
Access-Controlheaders
Origin: origin
Access-Control-Request-Method: put
Access-Control-Request-Headers: …
Access-Control-Allow-Origin: origin |
*
Access-Control-Max-Age: 300
Access-Control-Allow-Credentials:
bool
Access-Control-Allow-Methods: put,
get
Access-Control-Allow-Headers: …
Access-Control-Expose-Headers: …
pre
flig
hte
d
req
ues
tre
spo
nse
http://www.html5rocks.com/en/tutorials/cors/
• Have white list of
origins
• If not possible use X-
CSRF-Token
Prevent attacks
set header X-CSRF-Token
pre
vio
us
re
qu
est
nex
t re
qu
est
return X-CSRF-Token
serv
er
vali
dat
ion
server response with new X-CSRF-Token
http://mircozeiss.com/using-csrf-with-express-and-angular/
What’s all about?
● Same-origin policy ● Cross domain requests use-cases ● Making requests with XHTTPRequest● CSRF attacks● Simple and not-so-simple requests● Cross-domain limitations & Access Control ● Back-end implementation examples● Limitation in Internet Explorer 8, 9● Workarounds (proxy, JSONP)● Content Security Policy
Back-end implementation.Net
CODE
// library Thinktecture
public static void Register(HttpConfiguration config){var corsConfig = new WebApiCorsConfiguration();
corsConfig.RegisterGlobal(config);corsConfig.ForAll().AllowAll();
}
//more details: //http://brockallen.com/2012/06/28/cors-support-in-webapi-mvc-and-iis-with-thinktecture-identitymodel/
1234567891011121314
Back-end implementationRuby
CODE
module YourProjectName class Application < Rails::Application
...... config.action_dispatch.default_headers = { "Access-Control-Allow-Origin" => "*", "Access-Control-Allow-Methods" => "PUT, GET, POST, DELETE,
OPTION",
"Access-Control-Allow-Headers" => "Origin, X-Requested-With, X-File-Name, Content-Type, Cache-Control, X-CSRF-Token, Accept", "Access-Control-Allow-Credentials" => "true", "Access-Control-Max-Age" => "1728000" }
...... endend
123456789
10111213141516171819
• Most probably you will
never need it, but in
case flowchart is under
link below
Manual implementation
http://www.html5rocks.com/en/tutorials/cors/
What’s all about?
● Same-origin policy ● Cross domain requests use-cases ● Making requests with XHTTPRequest● CSRF attacks● Simple and not-so-simple requests● Cross-domain limitations & Access Control ● Back-end implementation examples● Limitation in Internet Explorer 8, 9● Workarounds (proxy, JSONP)● Content Security Policy
• IE ≤ 7 is not a browser
• IE10+ is already a
browser
• IE8-9 can be handled
with XDomainRequest
Most loved browser
Limitation in Internet Explorer 8, 9Feature detection
CODE
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
//"withCredentials" only exists on XMLHTTPRequest2 objects xhr.open(method, url, async, user, password);
} else if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest(); xhr.open(method, url);
} else {
//Otherwise, CORS is not supported by the browser xhr = null;
}
123456789101112131415161718
1. The target URL must be accessed using only the methods GET
and POST
2. No custom headers may be added to the request
3. Only text/plain is supported for the request's Content-Type
header
4. No authentication or cookies will be sent with the request
5. Requests must be targeted to the same scheme as the hosting
page
6. The target URL must be accessed using the HTTP or HTTPS
protocols
7. Requests targeted to Intranet URLs may only be made from the
Intranet Zone
Limitation in Internet Explorer 8, 9Things to remember
http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
Third party services
Proxy
Client
Workarounds
WorkaroundsJSONP Concept
CODE
<script src="http://3rd-party.com/api/v1/users/27"></script>
#responce from http://3rd-party.com/api/v1/users/27:
callbackFn({"id":1,"name":"Jack","email":"[email protected]","startDate":"2010-01-01T12:00:00","endDate":null,"vacationRate":1.67,"admin":true,"defaultRecipient":true,"userRequestCount":0,"requestToUserCount":0});
123456789101112131415161718
WorkaroundsJSONP with jQuery
CODE
<script src="http://3rd-party.com/api/v1/users/27"></script>
$.ajax("http://3rd-party.com/api/v1/users/27", { "crossDomain": true, "dataType" : "jsonp" });
#request URL will be:http://3rd-party.com/api/v1/users/27?callback=jQuery111008519500948023051_1398177525599&_=1398177525600
#responce from http://3rd-party.com/api/v1/users/27:jQuery111008519500948023051_1398177525599({
"id":1,"name":"Jack","email":"[email protected]",...
});
123456789101112131415161718
WorkaroundsJSONP Limitations
● JavaScript Object Notation is for read, not eval.
● Can’t add custom headers.
● Require ability to modify backend.
● Only GET method.
Workarounds... kind ofDocument messaging
CODE
window.addEventListener("message", function(event){
if (event.origin !== "http://example.org"){ return;}
}, false);
window.parent.postMessage("Hi there!", "http://example.org");
12345678910
https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage
What’s all about?
● Same-origin policy ● Cross domain requests use-cases ● Making requests with XHTTPRequest● CSRF attacks● Simple and not-so-simple requests● Cross-domain limitations & Access Control ● Back-end implementation examples● Limitation in Internet Explorer 8, 9● Workarounds (proxy, JSONP)● Content Security Policy
• Only latest browsers
• With prefix 'X-' in IE10-
11
• Inline script won’t work
• eval() too
• Report and Report-
Only
https://www.youtube.com/watch?v=C2x1jEekf3ghttp://www.html5rocks.com/en/tutorials/security/content-security-policy/http://en.wikipedia.org/wiki/Content_Security_Policy
Content Security Policy
Content-Security-Policy:
default-src 'unsafe-eval' 'unsafe-inline';
connect-src 'none';
font-src https://themes.googleusercontent.com;
frame-src 'self';
img-src http://cdn.example.com/;
media-src http://cdn.example.com/;
object-src http://cdn.example.com/;
style-src http://cdn.example.com/;
script-src 'self';
report-uri /csp_report_parser;