HTML5
Last updated
Last updated
SOP prevents interactions between resources of different origins.
CSS, images and scripts are loaded without consulting SOP.
SOP is consulted when cross-site HTTP requests are initiated by client-side scripts. (e.g. AJAX requests)
If crossdomain.xml allows, an SWF animation on the origin a.com
can access via Actionscript resources (e.g. images, audio files) on a different origin b.com
.
Enable client side cross-origin requests for:
AJAX requests (via XMLHttpRequest API)
Web fonts (@font-face within CSS)
WebGL textures
Images are drawn using the drawImage
API
Control Access Headers
crossOriginXHRGet
Simple Requests
GET / HEAD / POST
For POST, the Content-Type
should be either:
application/x-www-form-urlencoded
multipart/form-data
text/plain
No custom headers
Preflight request
Not a simple request
PUT / POST with Content-Type
set to application/xml
/ GET with custom headers
Preflight request needs to send 2 HTTP requests
First = HTTP OPTION (determine if the actual request is consider safe by the web server)
Browser and web server use the HTTP Origin Header
to negotiate permission
Web server respond Access-Control-Max-Age
and the browser will cache the request
By default, in cross origin AJAX requests, browsers do not send credentials (HTTP Cookies / HTTP authentication)
If a developer decides to include credential, he must set the flag withCredentials
during XHR invocation
Access-Control-Allow-Origin: <allowedOrigin>
Set by the target origin to allow access from a specific requester origin. The <allowedOrigin>
can be a wildcard.
Typical security issue is when the origin has sensitive documents, while this header allows them to be accessed by all origins. If so, the attacker can just use a crafted link and leads the victim to visit.
By default the requester origin (browser) does not send credentials to the target origin. If it needs to, it needs to set withCredential
flag. The the origin allows it, it responds Access-Control-Allow-Credentials: true
.
For security reason, a target origin cannot specify that a resource is both accessible by any other origin and that is accepts credentials. i.e. You will never see a response header with both:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
HTTP response header sent by the target origin to the requester during preflight requests. It indicates which non-standard HTTP headers can be sent in the actual request. Syntax:
Access-Control-Allow-Headers: [<fieldname>][, <field-name>][*]
Sent by the target origin to the requester during preflight requests, which indicates how long the results of a preflight request can be cached.
Access-Control-Max-Age: <delta_seconds>
The response:
Access-Control-Expose-Headers: 7200
Sent by the target origin to the requester which indicates which headers can be accessed by the browser.
Access-Control-Expose-Header: [<MyHeader1>] [<MyHeader2>] [*]
A cross-origin request includes an extra HTTP header named Origin. This header always sent and contains the origin (protocol, domain name and port) of the request.
HTTP request header sent by the requestor origin during preflight requests. It is sent within the OPTIONS
requests and specifies what method the requester is going to use during the actual request.
Request:
Access-Control-Request-Method: <field_name>
Response:
Access-Control-Request-Method: <method>
HTML5 allows iframes, frames, pop-ups, and the current window to communicate one with each other, regardless of the SOP.
Relationships between the two windows:
A main windows including an iframe
A main windows including some HTML code that generates a popup
Use postMessage
API call to send message to another window.
A handler, related to the message event should be installed.
When the receiver window does not check the origin of the sender when receiving a message.
Good practice: Always filter the senders by checking their origin
If Message Content Filtering fails, it allows cross origin XSS!
HTML5 allows websites to store data locally in the browser via JS:
localStorage
(5-10 MB; only known to browser; simple interface array data model)
sessionStorage
Pages from the same origin use the same local storage object. The storage is persistent and will be deleted if either of the following:
The webapp deletes the storage via localStorage
API calls
The user deletes the storage using the browser cleaning feature (e.g. clear recent history)
APIs:
Add item: localStorage.setItem('k', 'v');
Get item: localStorage.getItem('k');
Remove item: localStorage.removeItem('k');
Clear all: localStorage.clear();
Session storage is bound to the browser window where a website is open - 10 tabs on the same URL, 10 sessionStorage
distinct objects.
Session storage is deleted if either:
The webapp deletes the storage via sessionStorage
API calls
The user deletes storage via the browser cleaning feature
The user close the browser window (session storage limited to the window lifetime) (Refreshing the page will not delete the storage)
APIs: Same as the ones in localStorage
Storage objects can be stolen by XSS (since they are managed by JS).