Security/CSP/Specification: Difference between revisions

Line 383: Line 383:


==Policy Refinements with Multiple Headers==
==Policy Refinements with Multiple Headers==
When multiple instances of the <tt>X-Content-Security-Policy</tt> HTTP header are present in an HTTP response, the intersection of the policies is enforced; essentially, the browser enforces a policy that is more strict than both the policies specified in the multiple headers, but only strict enough to correspond to rules in all policies.  Any web request that satisfied ''all'' policies alone will be accepted by the new policy, but any request rejected by ''any of'' of the two policies will be rejected.  The intersection is calculated on a directive-by-directive basis (i.e., the intersection of the <tt>allow</tt> directive is taken and enforced as the <tt>allow</tt> part of the effective policy). Explicitly, for two policies:
When multiple instances of the <tt>X-Content-Security-Policy</tt> HTTP header are present in an HTTP response, the User Agent MUST enforce the intersection of the policies; essentially, the User Agent SHOULD enforce a policy that is more strict than both the policies specified in the multiple headers, but only strict enough to correspond to rules in all policies.  Any web request that satisfied ''all'' policies alone MUST be accepted by the new policy, but any request rejected by ''any of'' of the two policies MUST be rejected by the new policy.   
 
User Agents MUST calculate the intersection on a directive-by-directive basis (i.e., the intersection of the <tt>allow</tt> directive is taken and enforced as the <tt>allow</tt> part of the effective policy). Explicitly, for two policies:


<blockquote>
<blockquote>
Line 396: Line 398:
</blockquote>
</blockquote>


If more than two instances of the <tt>X-Content-Security-Policy</tt> header are present in the response, the intersection is done digest-style: the first two policies are removed from the set of headers to digest, intersected, and the result is placed back in the set.  This continues until only one policy remains.  e.g.,
If more than two instances of the <tt>X-Content-Security-Policy</tt> header are present in the response, the User Agent MUST perform intersection digest-style: the first two policies are removed from the set of headers to digest, intersected, and the result is placed back in the set.  This continues until only one policy remains.  e.g.,
  intersect(A, B, C, D) = intersect(A, intersect(B, intersect(C,D)))
  intersect(A, B, C, D) = intersect(A, intersect(B, intersect(C,D)))


If two policy headers are present, one (P<sub>1</sub>) may allow scripts from domains A, B and C.  The policy in the other header (P<sub>2</sub>) may allow scripts from domains B, C and D.  The policy enforced (P<sub>enforced</sub>) by the browser will allow scripts from domains B and C only (P<sub>enforced</sub> = P<sub>1</sub> &cap; P<sub>2</sub>).
''Example: If two policy headers are present, one (P<sub>1</sub>) may allow scripts from domains A, B and C.  The policy in the other header (P<sub>2</sub>) may allow scripts from domains B, C and D.  The policy enforced (P<sub>enforced</sub>) by the browser will allow scripts from domains B and C only (P<sub>enforced</sub> = P<sub>1</sub> &cap; P<sub>2</sub>).''
 
===Why Intersect Policies?===
 
Because the <tt>X-Content-Security-Policy</tt> header may appear multiple times in the response, it is possible they're crafted by different entities and may conflict.  A decision must be made about which policy to use, or whether to combine them or not.  Assuming there are two different policies present, there are five obvious ways to address this conflict:
 
#<b>Ignore both.  Raise error in the console.  Enforce "allow none" (most secure).</b><br/>Simplest and safest way to lock down when the policies conflict.
#<b>Ignore both. Raise error in the console.  Enforce "allow *" (most relaxed).</b><br/>This is a fail-open policy and will keep the site from breaking if two policies conflict.
#<b>Use the first header's policy.</b>
#<b>Use the second header's policy.</b>
#<b>Enforce the intersection of the policies.</b><br/><i>This is the technique used by CSP</i>.  For each URI that is accepted by <i>both</i> policies, the new intersected policy will also accept the URI.  Any request that is not accepted by <i>both</i> policies will be rejected by the new policy. This provides the ability for interaction between multiple policy specifications, allowing infrastructure admins to add a global policy to all sites on their network that may additionally want more restrictions.  This technique allows the use of multiple headers to make a widely used policy more restrictive, but never more relaxed.
 
The fifth option, enforcing the intersection of the policies, is the best balance between safety and flexibility so CSP implements this conflict resolution technique.  Furthermore, it is likely that those controlling the network are not always the same people who maintain or create the web application itself -- the ability to "refine" or further restrict enforced policies allows the web programmers to tighten the belt on a CSP-protected page without violating the policy set out by the network (possibly set by the sysadmins).


===Conflicting <tt>report-uri</tt> values===
===Conflicting <tt>report-uri</tt> values===
If multiple headers define policies with <tt>report-uri</tt> values, a single report is sent to each of the provided URIs.  If any <tt>report-uri</tt> values are the same, only one report for each violation is sent to that URI; essentially one report is sent to each distinct URI upon policy violation.
User Agents MUST send a single report to each URI when multiple headers define policies with different <tt>report-uri</tt> values


Report-duplication (or multiple reporting) is useful in the case where two different groups want to receive reports, but may not share access to the reports archive.  Take for instance a large web company that has a separate sysadmin staff (who are also in charge of security at some level) and project teams.  One project team may be interested in receiving reports about violations of their CSP, but are not interested in violations on other parts of the web site.  The sysadmin team wants to record all violations from all parts of the site into a massive archive.  The multiple reporting technique allows both entities to receive the reports they want without causing extra data-mining work on the part of the sysadmin team to isolate the reports that each project team may want.
''Example: Report-duplication (or multiple reporting) is useful in the case where two different groups want to receive reports, but may not share access to the reports archive.  Take for instance a large web company that has a separate sysadmin staff (who are also in charge of security at some level) and project teams.  One project team may be interested in receiving reports about violations of their CSP, but are not interested in violations on other parts of the web site.  The sysadmin team wants to record all violations from all parts of the site into a massive archive.  The multiple reporting technique allows both entities to receive the reports they want without causing extra data-mining work on the part of the sysadmin team to isolate the reports that each project team may want.''


====Data Leak Vectors====
====Data Leak Vectors====
Since HTTP headers and the entire request string are sent in the report, it is possible that, in case of compromise, a violation report could leak private information to an arbitrary URI.  To avoid any possible cross-domain cookie or authentication token transfer, <b>all reports must be sent to the same origin (scheme/host/port) that served the protected content</b>.
Since HTTP headers and the entire request string are sent in the report, it is possible that, in case of compromise, a violation report could leak private information to an arbitrary URI.   
 
To avoid any possible cross-domain cookie or authentication token transfer, User Agents MUST only transmit reports to ''the same origin (scheme, host, and port)'' that served the protected content.


===Policy Refinement Procedure===
===Policy Refinement Procedure===


Two headers present conflicting policies, they are resolved through a straightforward process: first the policies are made explicit (see below), then they are intersected, and the resulting policy is enforced.  Through this process, the enforced policy will <i>never be more lenient</i> than either of the conflicting policies.
User Agents MUST resolve two headers present conflicting policies through the following process:
# The policies are made explicit (see below)
# They are intersected
# The resulting policy is enforced.   


[[Image:CSP_Policy_Refinement_Overview.png|Policy Refinement Overview]]
[[Image:CSP_Policy_Refinement_Overview.png|Policy Refinement Overview]]


This refinement procedure is only followed if there are multiple instances of the <tt>X-Content-Security-Policy</tt> HTTP header present in the HTTP response.
User Agents MUST follow this refinement procedure when there are multiple instances of the <tt>X-Content-Security-Policy</tt> HTTP header present in the HTTP response, or multiple policies are present in the HTTP header (separated by commas).


====Making a Policy Explicit====
====Making a Policy Explicit====
Line 445: Line 440:


[[Image:CSP_Directive_Intersect.png|Intersecting two directives]]
[[Image:CSP_Directive_Intersect.png|Intersecting two directives]]


==Handling Parse Errors==
==Handling Parse Errors==
canmove, Confirmed users
1,537

edits