5 ms·
I have been trying to explain the importance of HTTP headers to some younger/junior devs I am working with. I have noticed that headers are often considered to
by LeonM 7y ago
I have been trying to explain the importance of HTTP headers to some younger/junior devs I am working with. I have noticed that headers are often considered to be 'too technical' or even 'old tech'.
I'm going to recommend them to read this, but I do think I need to explain a couple of things that the article is not clear about:
- Be sure that you understand the concept of HSTS! Simply copy/pasting the example from this article will completely break subdomains that are not HTTPS enabled and preloading will break it permanently. I wish the authors made that more clear. Don't use includesubdomains and preload unless you know what you are doing. Scott Helme also did a great article about this [0].
- CSP can be really hard to set up. For instance: if you include google analytics, you need to set a script-src and a img-src. The article does a good job of explaining you should use CSP monitoring (I recommend sentry), but it doesn't explain how deceptive it can be. You'll get tons of reports of CSP exceptions caused by browsers plugins that attempt to inject CSS or JS. You must learn to distinguish which errors you can fix, and which are out of your control.
- Modern popular frontend frameworks will be broken by CSP as they rely heavily on injecting CSS (a concept known as JSS or 'styled components'). As these techniques are often adopted by less experienced devs, you'll see many 'solutions' on StackOverflow and Github that you should set unsafe-inline in your CSP. This is bad advise as it will bascially disable CSP! I have attempted to raise awareness in the past but I always got the 'you're holding it wrong' reply (even on HN). The real solution is that your build system should separate the CSS from JS during build time. Not many popular build systems (such as create-react-app) support this.
- Cache control can be really hard too. If you don't have time to fiddle with these settings, I recommend using a host like Netlify, they seem to do a proper job at caching in my experience.
[0] https://scotthelme.co.uk/tag/hsts-preload/ https://scotthelme.co.uk/tag/hsts-preload/
edit: typos
- quickthrower2 7y agoIt could be that headers seem scary, and I think that is because you can get a lot done without them, so they might be unfamiliar to junior devs. To make them less scary maybe it is sufficient to say they are just key/value pairs, like an additional JSON object in the response. It's there for you to see in Chrome dev tools, and it's fun seeing how different sites might send different headers. As a motivator I always say look at the network tab and think about how you can make stuff faster. It was this mindset where I first saw these additional requests and thought 'WTF!' I better find out why it is happening, turned out to be preflight requests.
- geezerjay 7y ago> I think that is because you can get a lot done without them Reinventing the wheel is also a good way to fool yourself into assuming we're being clever and productive. I mean, it's as if everyone who preceded me in a field was incapable of looking into a problem I've managed to find a hacky solution in 5 minutes. Meanwhile let's not pretend that there are currently about half dozen standards and specifications for HATEOAS, all involving ugly hacks around response documents and funny media types, when all it takes to achieve the same goal is passing link relations through Link headers.
- barbecue_sauce 7y agoHow can you even get a job as a junior dev without knowing about headers?
- ljm 7y agoEasy, you just think you have to add a content type.
- quickthrower2 7y agoNever been asked about headers in a job interview, junior or otherwise. Usually interviews are a 'can you code' test. I've never been interviewed by FAANG etc. though.
- jve 7y ago> Be sure that you understand the concept of HSTS! Simply copy/pasting the example from this article will completely break subdomains that are not HTTPS enabled and preloading will break it permanently +1. I'm kind of worried that the default copy-pasteable snippet there can lead to serious consequences. Well, less today when you can get certs for free, but you may have some unpleasent downtime.
- 3jckd 7y agoOne tip from personal experience: I usually introduce CORS (and Access-Control-Allow-Origin header in particular) first. Most people unfamiliar with HTTP headers have no problem understanding the usefulness of that one and it opens the door to other stuff.
- fabian2k 7y agoI was also disappointed that some aspects of modern JS frameworks make adding strict CSPs incredibly hard. Especially with CSS there don't seem to be many resources on how to make something like React styled components work with CSPs, disabling the CSS CSP seems to be the only reasonable way to do this.
- amelius 7y ago> Be sure that you understand the concept of HSTS! Instead of using HSTS, you can also simply redirect any HTTP request to HTTPS. That way, you are certain that HTTPS is used, even if a browser does not understand HSTS.
- hywel 7y agoThis will leave your users vulnerable to man-in-the-middle attacks. If I control the router between their computer and the Internet, I can serve back a HTTP page which doesn't redirect, and trick them to enter their password (for example). HSTS is designed to prevent this.
- amelius 7y agoHow can HSTS prevent a man in the middle attack if the server has not even been contacted yet?
- LeonM 7y agoIt can't, that is what preloading is for. Your browsers comes preloaded with a list of all sites that have requested HSTS preload, so your browser will use HTTPS even on the first visit. This is why preloading on all subdomains is potentially dangerous to use, it could break your site if you don't have HTTPS everywhere. But even without preloading HSTS will improve security. Yes, the first visit will be susceptible to MITM, but every visit after that is not. This makes it a lot more difficult for an attacker as they must intercept the very first visit for the attack to work.
- heinrich5991 7y agoIt can only do that if you add it to the preload lists of browsers (which is mentioned in the article). But even if it is not, it's still helpful for people connecting to your site again.
- tialaramex 7y agoAnd because the preload list is hierarchical whole swathes of the Web can be covered with a single entry. .dev is the biggest example, but they can protect all the stack exchanges, all the default blogspot blogs, that sort of thing.
- nolok 7y ago> - Be sure that you understand the concept of HSTS! Simply copy/pasting the example from this article will completely break subdomains that are not HTTPS enabled and preloading will break it permanently. I wish the authors made that more clear. Don't use includesubdomains and preload unless you know what you are doing. Scott Helme also did a great article about this. Great point that is even more important than people might realize at first when reading your comment, because it doesn't cover only your web properties; it covers all subdomains even those you forget you use and don't associate with your web presence. You have a nas at nas.exemple.com, a webmail at mail.exemple.com, a third party cdn/similar routing at cdn.exemple.com, a printer interface at printer.office.exemple.com and other internals things at internally routed path, like that custom old dashboard written 15 years ago ? Include subdomain covers it, and preloading means you can't disable it once you realize you shouldn't have done it. Seen a few small non-IT companies hit by that, and then asking for urgent consultancy to fix it.
- LeonM 7y ago> and then asking for urgent consultancy to fix it. If it is preloaded (as the article suggest you should do), there is nothing you can do to 'fix' it, except migrating all other subdomains to HTTPS. Which is not always possible.
- nolok 7y agoOh yes exactly, especially since they don't have much planned budget for it (small firms) it ends either with a lot of dirty proxying to have an HTTPS middle point, just because someone screwed up without paying attention to what they were actually doing, or with a secondary domain for the office.
- eridius 7y agoMy subdomains for things like that all go through a reverse-proxy (Caddy) where I terminate HTTPS, which makes things simple, though I still don't use includesubdomains because it just seems too risky.
- baddox 7y ago> Modern popular frontend frameworks will be broken by CSP as they rely heavily on injecting CSS (a concept known as JSS or 'styled components')... Not sure what you mean by this paragraph. JSS and styled components are both specific JS libraries that provide a way to write styles in JS and compile them to normal CSS. They both support normal server-side rendering of CSS that could be included in the HTML like any traditional web page. The general term for this concept is “CSS-in-JS.” The libraries do not rely on inline styles, even though the general term may suggest that. I’m not very familiar with JSS, but styled components absolutely supports building CSS in create-react-app.
- LeonM 7y agoI confused styled components with JSS. JSS is a library used by popular UX libraries, most notably Material-UI. The problem is that JSS injects the CSS dynamically at runtime. There seems to be no real solution to extract the CSS into a .css file at compile time. The only solution that the JSS developers suggest [0] is using server-side rendering to inject a nonce into the HTML script tag to bypass CSP. But I think that requiring server-side rendering for a client-side rendered framework is totally backwards. The whole reason why I use single page client side rendered applications is so I can deploy on a CDN. [0] https://github.com/cssinjs/jss/blob/master/docs/csp.md https://github.com/cssinjs/jss/blob/master/docs/csp.md
- theandrewbailey 7y agoI'm surprised that SRI (sub resource integrity) isn't mentioned, though it does require HTML changes. It makes you embed SHA-2 hashes into your CSS and/or JS tags, and if the given hash doesn't match the received resource's hash, the resource isn't applied to the page. It protects you (for example) from your CDN changing your data. Also, no mention of E-tags. They help with caching.
- gambler 7y ago> The real solution is that your build system should separate the CSS from JS during build time. Not many popular build systems (such as create-react-app) support this. The real solution is to fix the actual protocol issues, instead of imposing arbitrary limitations on what scripts can do with the page. If you pause and think about what these security measures are aiming to mitigate, they themselves are at best amateurish.
- dcbadacd 7y agoThey aren't strictly "protocol issues" though, they're just dangerous features that are good to be limited in most cases.
- DGAP 7y agoUnfortunately, using Google Tag Manager basically requires setting 'unsafe-inline', neutering your CSP.
- rocketraman 7y agoAnother gotcha with HSTS + includesubdomains is if you have a naked domain e.g. https://example.com https://example.com redirecting to a www prefix e.g. https://www.example.com https://www.example.com, but the server is configured to send the HSTS header for the naked domain. It's not always obvious because your gut reaction is "oh my web site is on www.", but that misconfigured naked domain redirect might indeed break "randomservice.example.com".
- caprese 7y ago> I have noticed that headers are often considered to be 'too technical' or even 'old tech'. Are you or they able to elaborate on that? Headers are an active area of research/implementation for web security, are they working on any replacement to the entire concept?
- JMTQp8lwXL 7y agoAre you implying that CSS-in-JS is an anti-pattern, due to its incompatibility with CSP? (I have no opinion one way or the other regarding CSS-in-JS).