Policies¶
Same-Origin Policy¶
- Problem:
- Without separation, scripts could leak information from frames
- e.g., malicious site includes Gmail-iframe, logged-in due to cookies, malicious site read iframe content (e.g., mails)
- Idea:
- Restrict interaction between documents/scripts from two different origins (e.g., usually scripts and CSS)
- SOP is Access Control Policy
- Origins must match to get access
- Origin: Protocol, Hostname, Port
- IE: No explicit port => Match for all ports
- Important:
- ~~Only applies to scripts/CSS~~
- Resources like images, css files, dynamically loaded scripts, video, audio can be requested via the HTML tags
- Cross-origin writes are allowed (links, redirects, forms)
- Access:
- Cross-origin write (outgoing) allowed (e.g., form submissions, redirect to another page)
- Cross-origin embedding allowed (e.g., images, styles, scripts, video, …)
- Cross-origin read (incoming) disallowed (often leaked through embedding)

Use Cases¶
- Control (script) access to other documents in browser (frames, iframes, popups)
- Exception:
window.nameis always accessible (can be used for cross-site scripting)
- Exception:
- Control (script) access to local state (cookies/Web Storage)
- Control HTTP requests to other hosts (e.g., XMLHttpRequest)
Domain Relaxation¶
- Problem: SOP too restrictive (for big websites)
- Goal: Two domains should communicate under certain conditions
document.domain¶
document.domaincan be set- Set to super-domain (suffix containing parent domain)
- e.g.,
test.example.orgtoexample.org - Both domains have same
document.domainvalue - Both domains must explicitly set
document.domain(both must agree to communicate) - Exception: Setting to TLD is forbidden (e.g.,
.org)
Web Messaging¶
- HTML5 API
- Purpose:
- Communication channel between two sites
- Preserve authenticity/confidentiality of message
- Workflow:
- Sender script calls
windowobject of receiver withwindow.postMessage(msg, targetOrigin) - Receiver script must initialize an event listener
addEventListener("message", func)- Event:
{data, origin, source}originof sendersourceis window object of sender
- Sender script could initialize an event listener for bi-directional communication
- Sender script calls
- Security issue:
- Always provide
targetOriginand not the wildcard (otherwise, all scripts would receive the message) - Always check message origin at receiver site (otherwise, all sites could send messages)
- Always evaluate message content
- Avoid Regex checks or substring checks
- Always provide
- Real-world usage:
- CISPA, 2017
- ~50 % use postMessage with Wildcard target (2016)
Attacks¶
DNS Rebinding¶
- Attacker goal: Access to network behind firewall
- Idea:
- SOP relies on hostnames
- Change underlying IP address of hostname
- Abuse Time-to-live of DNS records
- Preliminaries
- Attacker controls DNS server
- Attacker controls Webserver (including malicious script)
- Real-world attacks:
- CUPS printing system (log files)
- Router access (configuration)
Workflow¶
- Victim asks for IP address for DNS
attacker.com - Attacker sends IP of Webserver with low TTL (e.g., TTL=1)
- Attacker sends website including malicious script to victim
- Victim’s browser executes script, script connects to
attacker.com - IP for DNS
attacker.comis expired, victim asks again for IP address - Attacker sends IP address of target (e.g., router
10.0.1.1) - Script connects to router (browser still communicates with the same origin, but different IPs)
History¶
- 1996 Princeton Attack
- 2002 Adam Megacz
- Using old domain relaxation rules
- 2006 Martin Johns
- IE/Firefox dropped pinned ID when connection failed
- Attack: Connect to closed port on attacker.org
- 2006 Kanatoko
- 2013 Johns et al.
- HTML5 AppCache
- 2016/2017
- Browser has finite DNS cache
- Idea: Flood DNS cache with for-loop
Approach HTML5 AppCache¶
- Johns et al., 2013
- HTML5 AppCache
- Cache manifest instructs browser to store certain files offline
- If offline content is loaded and the browser is online, browser checks for changes
- Idea:
att1.orghosts cache manifestatt2.orgcontains resources (gets rebound later)
- Workflow:
- Victim queries
att1.org - Attacker sends cache manifest to victim (manifest contains link to Flash file on
att2.org) - Victim queries Cache manifest
- Attacker sends malicious code to victim
- Victim’s browser caches the Flash file
- Attacker sends website (embedding the cached code)
- Code gets executed, asking for new IP
- Attacker sends IP of router
- Victim queries
Countermeasures¶
- IP address pinning (minimum TTL)
- Attacked web server checks
HostHTTP Request Header (mismatch after the rebinding) - Extended Same-Origin Policy
- Problem: Browser decides (with potentially bad information, e.g., IP addresses)
- Idea: Server sets its trust-boundary
- Server sends list of allowed origins
- Client checks if target origin is in the list of the server-provided origins
- Criterion does not hold for DNS Rebinding attacks
Cross-Origin Search Attack¶
- Attacker’s goal: Leak sensitive information from server (answer specific query)
- Side-channel attack
- Scenario:
- Victim is authenticated at target website
- Victim accesses attackers website
- Malicious script loads target website (but can’t access it due to SOP)
- Idea: Measure time of request
- Example query: Does user Alice have email from user Bob?
- Workflow:
- Attacker sends malicious script to user
- Script sends two requests:
- Challenge: One where an answer is expected
- Dummy: Other where no answer is expected
- Real answer is bigger and has higher latency
- If latency difference is significant, question can be answered with yes
- Use statistical significance test
Cross-Origin Resource Size Attack¶
- Goal: Identify users (attack anonymity/confidentiality)
- Side-channel attack
- Idea:
- Use sizes of dynamically generated resources to identify users
- e.g., identify Alice by measuring the resource size of her Twitter followers
- Let malicious script load Twitter followers of unknown user (compare resource sizes)
- Measuring size unknown resource
- Measure size of AppCache
- Instruct browser to cache the resource
- Measure size of AppCache again
- Result size is the different if the two measurements
- Attack workflow:
- Victim visits attacker’s website with malicious script
- Script measures current cache size (\( n \))
- Script loads an (approximately) unique site for a user into the cache
- Script determines resource size and tells attacker
- Later, anonymous visits attackers page and the process repeats
- The attacker can identify the unknown user by matching the resource sizes
- Defense:
- SameSite-Directive for Cookies (prevent sending of Cookies)
- Add padding for entires (do not measure exact resource size)

Pixel Perfect Timing Attack¶
- Goal: Identify users (attack anonymity/confidentiality)
- Part of family of Canvas Fingerprinting
- Side-channel attack
- Each browser renders text/images differently fast (using CSS filter effects)
- Exploit timing behavior of browser (using
requestAnimationFrame()) - Can be used to generate fingerprints for users
- Paper: Paul Stone
Cross-Origin Resource Sharing (CORS)¶
- Problem:
- SOP too restrictive for cross-domain communication
- No really good solution exists
- Goal: Enable fine-grained access
- Server tells browser from which origins requests are allowed
Request From Client¶
- Send own origin via
Originheader (not complete URL) - Simple request:
- Standard methods: GET, HEAD, POST
- Standard headers (e.g.,
Accept,Content-Type,Content-Language, …) - Standard content-types (e.g.,
multipart/form-data,text/plain,application/x-www-form-urlencoded)
- Complex request:
- Requires Preflight request
- Non-standard methods (others than above)
- Non-standard headers (e.g., authentication, X-CSRF)
- Non-standard content-types (others than above)
- Preflight request
- Before sending the actual request, ask target server for policy
- HTTP-Method:
OPTIONS - Headers:
Access-Control-Request-Method: <method>Access-Control-Request-Headers: <headers>
Response From Server¶
- Sends policy with headers
- Headers
Access-Control-Allow-Origin- Possible values:
<origin>or* *can’t be used with credentials in request- Lists origin which can access
- Possible values:
Access-Control-Expose-Headers- Which headers my be accessed by (exposed to) JavaScript
- Always allowed:
Cache-ControlContent-LanguageContent-LengthContent-TypeExpiresLast-ModifiedPragma
Access-Control-Max-Age- Cache lifetime of preflight requests
- Value: Integer (seconds)
Access-Control-Allow-Credendials- Value:
true/false - Credentials: Cookies, authorization headers, certificates
- Value:
Access-Control-Allow-Methods- List, comma-separated
- Allowed HTTP methods
Access-Control-Allow-Headers- List, comma-separated
- Allowed HTTP headers (sent by client)
Vulnerability¶
If the server automatically adds the origin of every request to the allowed origins and sets credentials on true, the policy is useless.
Content Security Policy (CSP)¶
Basics¶
- Goal:
- Mitigation against XSS/data leakage
- Reduce attack surface
- Idea:
- Server sends policy of resource origins and script execution (e.g., designed by developer)
- Browser must enforce the policy
- Ensure, that attacker-controlled code can’t be executed directly
- Opportunities:
- Developer can explicitly whitelist trusted resources
- Developer can disallow inline scripts
- Developer can disallow dangerous JavaScript constructs (e.g., eval, event handlers)
- Realization:
- Policy set in HTTP
Content-Security-Policyheader - Policy in meta-tag (allows only a subset of directives)
- Policy set in HTTP
- Important:
- Can’t stop XSS, reduces impact
- Does not prevent HTML injection (e.g., Website defacement)
- Definition parser-inserted code:
- Use of
eval(code) - Use of
document.write(code) - Non-parser-inserted code:
document.appendChild/createElement
- Use of
- Problem: Libraries and Frameworks bypass CSP
- Libraries (e.g., Bootstrap) use annotations
- e.g.,
data-textattribute of button is inserted - Problem: With
script-dynamic, a script is trusted and the attacker could inject malicious script withdata-text="<script>...</script>"
- e.g.,
- jQuery uses
eval()to evaluate the content of an inline-script
- Libraries (e.g., Bootstrap) use annotations
- Statistics:
- 2016: 94 % of websites have a trivially bypassable CSP
Policy¶
- Sent by Server:
Content-Security-Policy: policy
- Policy is a string containing several directives
- Fetch directive
- Control location for certain resource types
- Document directive
- Control document properties
- Navigation directive
- Control locations a user can navigate to, e.g., form submission
- Reporting directive
- Control reporting process
- Fetch directive
Levels¶
Level 1¶
Fetch Directives¶
- Directives
default-src: Default fallback sourcescript-srcScript originstyle-srcStyle originimg-src: Image originfont-src: Font originobject-src: Object originconnect-src: Control valid XMLHttpRequest targetsframe-src: Control origin of frames
- Possible values:
<host-source>: Name, IP address or*'self': Refer to origin from which the document (Web page) is loaded'none': Refer to empty set, no URLs match'unsafe-inline': Allow usage of inline scripts, JS URLs, inline styles, inline event handlers'unsafe-eval': Allow usage ofeval()
Report Only Mode¶
- Problem:
- CSP tedious to write
- Restrictive policy might break functionality (e.g., third-party provider)
- Idea: Add feedback for developers (browser reports violations to server)
- Report Directive:
report-uri <URI>(later renamed) - Does not work in meta element
Level 2¶
- Fetch Directives:
- Added
child-src:- Control worker- and nested-browsing-source
- Deprecates
frame-src(later un-deprecated)
- Added
- Document Directives:
- Added
base-uri <source>:- Allowed values for
<base>-tag
- Allowed values for
- Added
sandbox(see Client-Side Security -> Sandbox)
- Added
- Navigation Directives:
- Added
frame-ancestors: Which sites may frame this site (does not fall back todefault-src) - Added
form-action: Control form targets (does not fall back todefault-src)
- Added
- Allow-listing of resources (new values):
- Using hashes:
- Add hash for script-tag to verify integrity
- Hash contained in CSP
CSP: script-src 'sha256-xxxx'<hash-algo>-<hash>(e.g.,sha256-xxxx)
- Using nonces:
- Nonce contained in CSP
- Nonce must be added to
scripttagCSP: script-src 'nonce-xxxx'<script nonce="xxxx">...</script>
- If a nonce is specified, modern browsers ignore the
unsafe-inlinedirective (i.e., if one nonce is used all inline scripts must use a nonce)
- Using hashes:
Level 3¶
- Fetch directives:
- Added
worker-src(control workers) - Added
manifest-src: control AppCache manifest source - Un-deprecated
frame-src
- Added
- Report directive:
report-to(replacereport-uri)
- New value
strict-dynamic:- Allow adding scripts dynamically
- Trust a root script (must be specified by a nonce or a hash)
- Browser ignores the host-based allow-listing
- Trust is propagated (scripts loaded by this script are trusted)
- Disallow parser-inserted code (i.e.,
eval,document.write) - e.g., script may use
appendChildbut notdocument.write
- Allow adding scripts dynamically
Example¶
Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">