paragonie / csp-builder Goto Github PK
View Code? Open in Web Editor NEWBuild Content-Security-Policy headers from a JSON file (or build them programmatically)
Home Page: https://paragonie.com/projects
License: MIT License
Build Content-Security-Policy headers from a JSON file (or build them programmatically)
Home Page: https://paragonie.com/projects
License: MIT License
It would be nice if there was an option to generate the CSP headers in the .htaccess for Apache, removing the need to restart Apache after generating the script.
The frame-src directive is deprecated in CSP 2 and is replaced by child-src which is correctly supported by csp-builder. Unfortunately, this will result in WebKit based browsers which only support CSP 1 falling back to default-src for nested browsing contexts, which could cause unexpected behaviour.
https://github.com/paragonie/csp-builder/blob/master/src/CSPBuilder.php#L85
In order to support WebKit you should allow a user to specify the frame-src directive. If the user does not specify a frame-src directive, the value of the child-src directive could be duplicated in the frame-src directive. There isn't really a downside apart from some header bloat and it results in support for WebKit based browsers like Safari and Edge.
@troyhunt experienced the issue and I assisted in debugging it: http://www.troyhunt.com/2015/10/how-to-break-your-site-with-content.html
I had download the csp-builder version 1.2.0 and configure json as required. But whenever i want to set Blob to connect-src it wont be added to headers this leads to not allowed blob data. How can i add "blob":true value to connect-src file to overcome that issue.
The report-uri is encoded when the header is compiled, and then escaped, causing https://example.com
to be encoded as https%3A//example.com
The browser then interprets this as "https://www.mydomain.com/https%3A//example.com", which... maybe obviously, doesn't work very well.
Add the ability to save the generated headers to a JSON file.
(I understand additional awesomeness is very project specific)
To gain a greater device support for the CSP (namely older IE, Safari and some mobile browsers), I suggest to add:
X-Content-Security-Policy
and
X-WebKit-CSP
headers in addition to Content-Security-Policy.
I wouldn't mind using this in my production envrionment, would you mind if I PR'd an extension that implements the __invoke method for PSR-7 middleware?
Not sure if this is possible or not but is there a way to allow additional schemes? Either by an additional class method or via a json config.
Refused to load data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 because it does not appear in the img-src directive of the Content Security Policy.
The CSP builder has no method for retrieving the value that's currently set for directives. There's only a method to set the value for a directive. I have a scenario where I initialized the CSP builder from a large config array, and now I need to apply some selective additions to it, but need to get the value for some directives first.
Older versions of iOS Safari (iOS 9 and earlier) don't understand CSP nonces. So when using nonces, if you want those browsers to work you have to add unsafe-inline as well. Of course, this is less secure again.
Firefox and Edge ignore the "unsafe-inline" directive if nonces are also called, so this is fine in those browsers; but... I can't determine if Chrome or newer versions of iOS Safari (10+) do the same. Thus, I'm not positive that just adding unsafe-inline is the correct (safe) fix. Worth investigating though.
@paragonie-scott @paragonie-security
Please add support for https:
scheme. Thank you in advance !
Hi there,
First of all, thanks for this great component!
We just had an issue with some frame-src
directives that started to "mysteriously disappear". For example, we initialize a builder and we set some global directives,
$cspBuilder = new \ParagonIE\CSPBuilder\CSPBuilder();
$cspBuilder->addSource('frame-src', 'first-frame-src');
$cspBuilder->disableOldBrowserSupport();
And then in the code, we dynamically add some directives, depending on the requirements,
$cspBuilder->addSource('frame-src', 'second-frame-src`);
When the response is about to being sent, we generate the final header and we send it.
The problem is that calling disableOldBrowserSupport()
in between 2 different addSource()
for frame-src
will generate different directives - see
csp-builder/src/CSPBuilder.php
Line 175 in 34b2d80
And in that specific scenario, since we define frame-src
and child-src
first and then child-src
only, we end up with the second-frame-src
being only defined in the child-src
but the browser cannot resolve it since there is a frame-src
directive for the first-frame-src
As per Mozilla doc,
If this directive is absent, the user agent will look for the child-src directive (which falls back to the default-src directive).
Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-src
As a work around, we moved the disableOldBrowserSupport()
call just after creating the builder and it works but I think that it should be a constructor's option instead so you cannot just change the addSource()
behavior in the middle of the CSP builder usage, screwing up the following frame-src
directives.
Browser: Microsoft Edge
Add support for CSP 3 elements script-src-elem and script-src-attr
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src-elem
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src-attr
Is there any reason to prepend all (almost all) functions and classes with \
? For example:
\ParagonIE\ConstantTime\Base64
)\array_keys
)According to that this is no longer supported.
This repo provides very useful functionality, but directly messes with global state via the header
function.
Hereby I suggest one of either:
csp-builder/src/CSPBuilder.php
Lines 323 to 330 in 8d8b993
Awesome idea to make a library for this! 👍
One dimension the browser looses control even with a CSP is via third-party plugins, which may have little / no enforcement.
The good people at Google via the W3C project have a CSP for white-listing allowed plugins, so a website can use plugins, that might break CSP, but restrict them, so the possible attack space is known (for example we know we don't allow swf files, we are not vulnerable to flash exploits...)
Right now it's only reported as working by chrome 40.0+ and android chrome 40.0+ source MDN
w3c spec with examples.
http://www.w3.org/TR/CSP2/#directive-plugin-types
Hi,
Nice work.
Just a silly question ? what is the use of the 'type' policies ? when i look at the code i don't understand. I have see the plugin use some types, but it doesn't look the same as the 'types' referenced here :
https://github.com/paragonie/csp-builder/blob/master/src/CSPBuilder.php#L742
Can you explain me ? i have found nothing about this node in the json example you have provided.
Thank you.
What PSR object are you referring to?
I assume the Response Object, but I just want to be sure.
the json example in the readme has no self
in various params but the json file from the tests does have these set.
https://github.com/paragonie/csp-builder#example
https://github.com/paragonie/csp-builder/blob/e9a7560fd3f133a85f03c51de5fc051ac97630a7/test/vectors/basic-csp.json
for example i am guessing that using the example from the readme does not set self fore base-uri. but that might not be a good example then, right? the resulting csp will not work well.
unless i am misstaken please adjust the readme json example so it will have sensible defaults where self
might be needed. thanks.
Hi,
Recently report-uri
has been deprecated - however it's still recommended to provide a URL for this field for older browsers.
However browsers like Chrome are now only using the report-to
which defines a group within a new Report-To
response header.
Currently the code just runs $compiled []= 'report-to ' . $this->policies['report-uri'] . '; ';
This means the value is always the same for both.
Would it be possible to allow individual control for the report-to
directive? this way we can leave a URL for older browsers in the report-uri
section and then have a group name in the report-to
directive? e.g. something maybe like:
if (empty($this->policies['report-to'])) {
$compiled []= 'report-to ' . $this->policies['report-uri'] . '; ';
}
Then if the developer defines a report-to
it will allow it?
I would like to do this:
"img-src": {
"self": true,
"data": true,
"blob": true
},
However, the "blob":true has no effect. I can resolve this by adding it in the other way:
$csp->addSource('image-src', "blob:");
but that results in having to look at annoying error messages in the console:
As a solution I would also accept any way to remove the automatic addition of "http://blob" and "https://blob" to the source list.
Since version 2.8.0, the report-uri
is wrongly encoded when injecting the CSP header.
2.8.0
report-uri https%3A//
2.7.0
report-uri https://...
This leads to a 404 if a CSP violation happens, as the browser prefixes the request with the local URL.
It would be a nice touch if the script automatically adjusted for duplicate addSource() calls.
I have a template system that uses CSP-Builder, and any time I link an external JavaScript file (via class method), it automatically runs the appropriate addSource() for the domain. But if I include http://example.com/script1.js and http://example.com/script2.js , the domain is duplicated in the CSP script-src -- e.g. "script-src http://example.com http://example.com;"
Doesn't seem to harm anything; just trying to keep clean code. :-) Thanks for you work on this class; very handy!
In the current CSP builder the nonce consists of random bytes, while nonce
means number used once. According to MDN, depending on the specific directive you are visiting, it is confirmed that the nonce should be a number. Some other directives don't specify it.
Now I don't know if the usage of random_bytes
is intentionally chosen. I did not encounter any problems with it in the browser, so it seems fine. But maybe you could consider to change it, or reject it if you feel the current implementation is fine.
New Directive: worker-src
This used to be handled by the (now deprecated) child-src. Child-src was split into frame-src and worker-src. You should also mark child-src as deprecated in CSP-Builder.
HOWEVER, worker-src is a bit odd because it follows an unusual fallback pattern:
So without setting worker-src it looks to script-src. (The current workaround with CSP-builder is to set both frame-src and child-src; then child-src serves as a de facto worker-src.)
What it says in the header. Please add support for the manifest-src directive.
Wondering if you could future proof this plugin a bit by making a "plugin" mechanism that allows users to add directives and such without directly hacking your code? I realize this library doesn't get updated too often, but some sort of modularity would allow us to add new things without waiting for official updates.
Feature-Policy
is a new header that, in format, seems to look exactly like CSP. It uses a separate Feature-Policy
HTTP header and instead of script-src
, img-src
, and so on as directives, it uses directives such as geolocation
and vibrate
.
It would be neat if csp-builder supported these. I realize that it is not strictly the same as CSP. An alternative would be to create a new project, though it would likely duplicate most efforts as the structure - and likely code - would mostly be the same.
[1] https://wicg.github.io/feature-policy/
[2] https://developers.google.com/web/updates/2018/06/feature-policy
[3] https://caniuse.com/#search=feature-policy
How do I add a 'strict-dynamic' directive for styles/scripts? The directive is mentioned in the code, but not clear how to use it.
The csp-builder allows you to specify hosts such as "scotthelme.co.uk" which is a valid definition as per the specification.
https://github.com/paragonie/csp-builder/blob/master/src/CSPBuilder.php#L180
In this scenario the browser should allow the scheme that the policy was delivered over to be used for the 3rd party host. This doesn't work as expected in Safari and can cause unexpected blocking behaviour. Specifying "scotthelme.co.uk" as an allowed host in any policy directive would not allow that resource type to be loaded from "https://scotthelme.co.uk". You can view more details on the bug here: https://scotthelme.co.uk/safari-doesnt-like-csp/
If the user doesn't specify a scheme the csp-builder could default to, or have an option to, use the scheme of the current page obtained by parsing the $_SERVER['REQUEST_URI'] or $_SERVER['HTTPS'].
If the policy is served over HTTP then all hosts specified without a scheme would default to HTTP. In this scenario the browser will allow a scheme upgrade to HTTPS.
If the page is served over HTTPS then all hosts specified without a scheme would default to HTTPS. In this scenario the browser will not allow a scheme downgrade to HTTP.
Chrome 76 seems to not handle how csp-builder does report-to
; when a report URI is set, Chrome does not send any CSP reports with v2.3.1. Only when the report-to directive is removed does Chrome send reports correctly (presumably to report-uri).
It seems like you can't just pass a normal URL as a report-to
value. Did the CSP spec change between implementation and now?
Scott Helme did a nice piece on how SRI would have countered a recent slew of unwanted script injections.
Standard: Latest editor’s draft & W3C Recommendation.
I may be able to sneak in a PR tomorrow, but can’t make any promises.
It appears that in CSPv3 report-uri is deprecated and replaced with report-to. Report-to looks like a more complicated way to specify types and endpoints. I can see in the code mentioned, that report-to is adding report-uri annotation (for compatibility), but seem to not find a way to define the reporting string. Please either implement or document this feature.
Example:
Report-To: { "group": "csp-endpoint",
"max_age": 10886400,
"endpoints": [
{ "url": "https://example.com/csp-reports" }
] },
{ "group": "hpkp-endpoint",
"max_age": 10886400,
"endpoints": [
{ "url": "https://example.com/hpkp-reports" }
] }
Content-Security-Policy: …; report-to csp-endpoint
For the love of God people, could you please document this?
I've spent an hour trying to figure out how to set report-uri and simply nothing works. CSPBuilder.php on line 107 thinks "/csp_reporting.php" is an array. Or something. I don't know, because I have no $#%*)^% idea how it's intended to work. AddDirective()? AddSource()? SacrificeFirstBornAtMidnight()?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.