
Secure Headers for PHP - aidantwoods
https://www.aidanwoods.com/blog/secure-headers-for-php
======
niftich
Though I am not familiar with this particular project and can't comment on its
quality, a C-S-P directive engine is always welcome.

In my opinion [1][2][3], it's fairly clear that C-S-P isn't a fire-and-forget
header (unlike some other Security Headers) and that its generation needs to
take into account rules that can be set up ahead of time and the context of
the resource in question. The OWASP wiki page itself recommends this, but as
far as I know, no web framework implements this.

If you know otherwise, let me know. This may be the first.

[1]
[https://news.ycombinator.com/item?id=12584356#12584733](https://news.ycombinator.com/item?id=12584356#12584733)
[2]
[https://news.ycombinator.com/item?id=12408328#12408680](https://news.ycombinator.com/item?id=12408328#12408680)
[3]
[https://news.ycombinator.com/item?id=13055470#13057260](https://news.ycombinator.com/item?id=13055470#13057260)

~~~
dandandan
If you generate them on-demand based on the resources included in the page how
can you ensure that XSS attacks on the page aren't going to result in hostile
sources being included in the CSP headers? I'm curious as to what the rules
would look like that define a fluid list of sources that can be expanded based
on page content but not vulnerable to inline XSS attacks.

~~~
aidantwoods
Generally with these things, avoiding user input is one of the best ways at
making sure they can't inject things into the header value.

I'd recommend manually writing the list of sources for the page type. There
isn't really a safe way to just scan the page for (safe) resources
unfortunately (how could you tell which resources were meant to be there?)

Point of the (CSP) part of this class is to let you break down your CSP into
distinct components and then combine them together.

E.g. You need to embed a tweet – that twitter embed code will require you to
add script, style, and image sources to your CSP. You could file them all
quite nicely in the CSP array format, and call that variable `$twitterCSP`.

If twitter changes things in the future RE the required sources, you now know
what to amend. If you decide you no longer want tweets on your page, you can
get rid of unnecessary sources by deleting just `$twitterCSP` from your code –
instead of leaving in sources you don't need, or having to trudge through the
entire CSP string trying to figure out which sources you added to make twitter
work.

Goal is source management, not auto generating the list.

------
onion2k
Do CSP headers change dynamically between page loads very often? I can't think
of a situation where that would happen. Consequently rebuilding them with PHP
seems unnecessary. Writing them using a build tool (eg gulp), and saving them
to a static includable file (or even a server config include) would get you
the same benefits without adding load to the page on every request.

Take said, this is still far better than not having a CSP or having a static
one, so it's an admirable project regardless.

~~~
aidantwoods
CSP headers are more often than not: static (bar nonces). Having them be
dynamic is really just a bonus to the management aspect you gain here. (You
can make sure every page truly only has access to load the sources it needs
though).

As far as using the class to do it goes, there are other benefits other than
just CSP management: auto cookie upgrades and error messages about poor
configuration to name a few.

------
seanwilson
Could you not simplify your large CSP header by using wildcards and moving
some of your dependencies to a central place (e.g. host Font Awesome
yourself)?

~~~
aidantwoods
It can be simplified, but it would reduce its usefulness to include wild
cards.

By specifying paths more explicitly, I whitelist less of the domain (and
consequently reduce the chances that I'll whitelist something this is user
controllable in the domain). I'll usually try to allow down to specific files
in CSP if I can.

Hosting font awesome myself costs me money, pointing to cloudflare is free

Edit: check out my site vs. a few others using Google's CSP evaluator – you'll
probably find a lot with known CSP bypasses due to their whitelisting.

------
jdpedrie
Unfortunate that it isn't published on Packagist, or installable via Composer.

~~~
aidantwoods
Hey. Just to let you know that the project is now installable from Packagist!

[https://packagist.org/packages/aidantwoods/secureheaders](https://packagist.org/packages/aidantwoods/secureheaders)

------
andreapaiola
I think that in LAMP environments (common shared hostings) it's in general
more convenient to set it in .htacess but... OK if you need it for some reason
in php, you can have it.

------
debaserab2
I kinda find this hard to believe:
[https://w3techs.com/technologies/overview/programming_langua...](https://w3techs.com/technologies/overview/programming_language/all)

I wouldn't be surprised if PHP is first, but Ruby, Python, and Javascript BOTH
under 1.0%? Seems highly doubtful.

That leads me to believe that this report must be generated off of websites
that actually self report language. I know PHP does by default in most distros
with an X-Powered-By header, but it's not clear to me what if any other
languages do that by default.

------
ChristianBundy
If you're setting your headers with PHP you've already lost. Headers should be
handled at the webserver level (e.g. Apache/Nginx), not in your server-side
code.

~~~
aidantwoods
IMHO, I don't think a broad statement about where headers should be handled
can really be made. For the one liners, sure. You can set up HSTS once and
forget about it.

For something like CSP, it becomes very difficult to maintain a list of
sources very quickly. Also, for parts of CSP like nonces too – from a
usability perspective, it's a lot easier to pass a nonce around in the
application layer, as opposed to generating it at the Apache/Nginx level, and
then trying to insert it into the HTML as the page goes out.

Goal here is to make things like CSP easier to use. Integrating security
headers into a language devs are already familiar with achieves that.

Disclaimer: I wrote the post and the PHP class.

