Check out a free preview of the full AWS for Front-End Engineers (ft. S3, Cloudfront & Route 53) course:
The "Adding Security Headers" Lesson is part of the full, AWS for Front-End Engineers (ft. S3, Cloudfront & Route 53) course featured in this preview video. Here's what you'd learn in this lesson:

Steve audits the security of our new application, and it fails, so he writes a Viewer Response function to address the holes in the application.

Get Unlimited Access Now

Transcript from the "Adding Security Headers" Lesson

[00:00:01]
>> Steve: So in addition to the policies that we added earlier, you see that now there's a content-security-policy, so on and so forth. You can see that it's currently being served by my brand new server side framework, Erlang on Eels. I look forward to a future workshop on that as soon as I invent it.

[00:00:25] But right now, any unsuspecting user will think that this site is being served by Erlang on Eels. Which in a lot of ways it is. My site isn't perfect yet, though. I know you looked at it and if this isn't perfection, I don't really know what is, right?

[00:00:45] But if we go to Mozilla's Observatory, which is basically a way to audit the security of your site, there is some superimportantwebsite.com. There is a little bit to be desired.
>> Steve: So for security, my site currently gets an F, not even an F plus. Luckily it is a bunch of the same problem, right?

[00:01:26] Which is I'm missing security headers, right? So in my response object. So it looks like what I need to do is, now you're all like, I don't have a server. So where is this gonna happen? We know the answer to that question, right? We can program our CDN.

[00:01:41] We can solve this. So this is gonna be one that we do on the viewer response. So as it leaves CloudFront, we know that it needs these headers on it in order to work. Now, this is something that I do have in the kind of set up guide.

[00:01:56] I have a lot of the code to this, cuz a lot of these headers are incredibly tedious to type, so I'm not gonna force that on you. But we are gonna go through the process, and then we're also gonna go ahead and just, for funsies after that, make one other change to the headers, right?

[00:02:12] So the two things we're gonna do is, I'm gonna add the security headers, and then one thing you might notice here is the server is Amazon S3. Now if you don't want people to know that you're serving your thing from S3, you can change that, right? Cuz if we can add security headers then we can likely also replace any other headers that we want.

[00:02:32] So I'm gonna go ahead and add some of the security headers which will lay some of the ground work. And we'll go back to an exercise where you can change the server header to anything you want, to mask the fact that it's coming from S3 if you want, right?

[00:02:47] With S3, you don't have a lot of security issues but that is definitely a thing that is been used in the past where it'll be like, served with Express version 1.3, right? And then all of a sudden there's a known security vulnerability, Express 1.3 and you're a target, right?

[00:03:03] Or a given version of Rails, so whatever. So it's usually a practice, get rid of that. Or the x powered by is another way that you'll see that. Mostly we want to get some practice modifying headers. So I'm gonna look real quick at what I have in the getting started guide here.

[00:03:24] And these are effectively some sensible defaults for the security headers. And we kind of talk through this code and then we'll put it in place. Before we had a request object, now we have the response object, cuz we are doing this on viewer response. This is leaving CloudFront, we've either had the cache miss or hit, and we're going back to the user.

[00:03:46] And effectively, we can basically find these headers, right? In JavaScript, if this doesn't exist, it'll set it for the first time, if it's there, it will update it.
>> Steve: And then these are basically the same. CloudFront will actually normalize the casing as well. So we'll go ahead, and we'll update all of these with the values that they need, all right?

[00:04:09] Again, watching someone type this, probably not super fun. So grab this. Now this is gonna be a little bit different than the last one. We're not gonna do in the viewer requests cuz we're not ready to handle responses just yet. We want to actually change the response coming out of CloudFront to include these headers.

[00:04:32]
>> Steve: So we'll go back, we'll find our way back to lambda, go to Functions. We'll create a new function, right, cuz this is a different place in the request response cycle that we're trying to drop into. So here we'll go to Create Function, and I want to just little bit too, to show you what it's like after the first one.

[00:04:50] We created a role last time, now we have one. So we'll call this one Add, we'll call it ModifyResponseHeaders.
>> Steve: We choose an existing role. And we'll choose that EdgeLambda one that we made earlier.
>> Steve: Great, so now we have a new lambda function. We can go ahead and replace this with what we had.

[00:05:23]
>> Steve: We'll hit Save.
>> Steve: And remember, we have to publish a new version.
>> Steve: So now we're on Version 1. Which will allow us to add CloudFront. You get those arrows, why they don't scroll you down, I don't know. They just show you arrows that they don't show you a second time, they do, they didn't before.

[00:05:52] We'll go ahead and now we want to make this one on the viewer response and we'll enable it and have it replicate. There's a lot of buttons that you have to hit, right? A problem you will run into at one point is you'll like yeah, yeah, yeah, I want to enable it.

[00:06:07] And then you will have saved it and you'll wonder what happened. And 20 minutes later you will see that you just didn't save it. So hopefully, by having this talk together right now it becomes a little, it helps you remember. So we'll head back over to the Observatory.

[00:06:27] We're gonna initiate a rescan and my hope is that,
>> Steve: It probably hasn't propagated just yet, so.
>> Steve: We'll also invalidate everything because we might have previously cached them.
>> Steve: But I do have to wait several minutes for that to happen. So we'll run the tests together in a second.

[00:07:03] What I want you to do is find a header that you wanna change. If you're feeling not particularly imaginative or you just wanna go down the happy path, server one's a great one to change, right? So you can see in this case it will be just lower case server.

[00:07:20] If you looked at the response headers before, it was the capital S on server there. And we can change the value to anything. You can change it all yes, totally served from Ruby on Rails, right, or whatever you want. Let's just add an additional header in there so that we can kind of just get a chance to play with a viewer response.

[00:07:38] So in addition to the policies that we added earlier, you can see that now there is a content-security-policy, so on and so forth. You can see that it's currently being served by my brand new service side framework, Erlang on Eels. I look forward to a future workshop on that, as soon as I invent it.

[00:08:02] But right now, any unsuspecting user will think that this site is being served by Erlang on Eels. Which, in a lot of ways, it is.