Monthly ArchiveNovember 2018

Don’t rely on X-XSS-Protection to protect you from XSS

Brian Fore No Comments


The X-XSS-Protection header only helps protect against certain reflected XSS attacks. It does nothing for stored XSS attacks. Don’t rely on it to protect your site from XSS!

What it can do: Block reflected XSS attacks

Reflected XSS occurs when a malicious query parameter in a page’s URL is rendered unsanitized on the page.

The XSS protection against this is not implemented uniformly across browsers (and it’s not supported at all by Firefox). But the basic idea is that the browser searches through the html looking for a script tag that exactly matches the script tag in the URL. If it finds a match, then the page is prevented from loading.

As an example, suppose our page takes the ‘user’ query parameter from the URL and displays it in a welcome message:

We’ll turn off Chrome’s default XSS auditor by including the following header in our server responses (this is not something you should normally do):

X-XSS-Protection: 0

Now we’ll replace ‘Mario’ with a script tag and see what happens:

With the X-XSS-Protection turned off, the script runs and an alert box appears.

Now we’ll turn the X-XSS-Protection back on by including the following header in our server responses (this is the usual setting we recommend):

X-XSS-Protection: 1; mode=block

We’re blocked when we attempt to reload the page:

We see the following message in the Chrome dev console:

The XSS Auditor blocked access to ‘http://localhost:8080/todos?user=%3Cscript%3Ealert(1)%3C/script%3E’ because the source code of a script was found within the request. The server sent an ‘X-XSS-Protection’ header requesting this behavior.

Here we have an example of the X-XSS-Protection in action. It has signaled to the browser to block the loading of the page, because


appears both in the URL and within the page’s html.

We generally recommend setting X-XSS-Protection: 1; mode=block, which (as we saw above) prevents the loading of the page if a reflected script is detected. An alternative is to set X-XSS-Protection: 1, which signals the browser to sanitize the reflected script and then continue to load the page.

What it can’t do: Block stored XSS attacks

Stored XSS occurs when a user submits malicious input to the website, the website stores this input, and then redisplays it, unsanitized, on one or more pages on the site.

As an example, suppose the todos on our site are displayed unsanitized, and the user submits a new todo with an onmouseover action:

When the user clicks Submit, the todo is stored server-side and the page refreshes with the updated list of todos from the server. When we hover over the malicious todo we see the alert popup:

The X-XSS-Protection does nothing against this sort of attack.


Generally speaking you should include the X-XSS-Protection header in your server responses:

X-XSS-Protection: 1; mode=block

But realize this only helps protect against certain reflected XSS attacks, and it’s not implemented uniformly across browsers. It will not protect against stored XSS attacks.

So how can you protect your site from stored XSS attacks?

  • Have a strong Content-Security-Policy.
  • Sanitize (or reject) malicious user input before it is stored server-side.
  • Always sanitize user input before it is displayed client-side. (Modern frameworks will usually take care of this for you, assuming you follow their best practices.)
  • Don’t assume 3rd party libraries (markdown editors, chart creators, etc.) are properly sanitizing all possible user input.



JASP Check Deep Dive: S3

Matt Konda No Comments

It is very common to find Amazon S3 buckets misconfigured. 

We found one in a pen test this week.  We find them frequently.  The most common things we see with S3 buckets is that people leave them open to the world and don’t encrypt them.  The one we found this week also let us delete and write files.

Something cool about using a tool like JASP ( is that it will not only detect the kinds of settings we’re about to go deeper on, but it will also check them every day and alert you if something changes.  Finally, you should be able to go look at reports to determine when the bucket first showed up with that config (though ideally you could get that from CloudTrail too).

Why encrypt S3 drives?

Since we’re in a shared file system in AWS, even though we expect AWS to prevent anyone from ever being able to read raw disk attached to any system we run in our account, because there could be shared host systems or infrastructure, we need to take extra precautions to make sure the data we write isn’t mistakenly available to another tenant.  This is also why we advise encrypting any other data storage as well.  Fundamentally, if a rogue user were able to identify a problem and break out of their guest instance to read raw disk, I don’t want them to know what I have.  If I encrypt the disk, they shouldn’t be able to.

Thinking about permissions for S3 drives

Sometimes S3 drives are used to host files like images, videos or web content.  In that case, you need the files to be readable to be able to use the service the way you want.  In that event, we would recommend double checking that the directory is not listable.  In general, we don’t want directories to be listable.  We would also recommend using different buckets if you intend to have some files be readable and others not be.  Finally, and this sounds obvious when we say it like this, but if the intent is for people to be able to read the files, don’t let them write or delete them!

Other times we have S3 buckets that are more like file sharing drives.  We want a limited group of people to be able to read those buckets.  Of course, we also want a limited number of people to be able to write or delete in those buckets as well.


A couple of things related to S3 and logging.  First, your cloudtrail logs that get stored in S3 should not be publicly readable.  Second, access to any non web files should probably have access logging going to cloudtrail.  That will come in handy if you ever need to know who did read that file.


These are just some examples of things that JASP ( can identify for you related to S3 buckets.  However you choose to manage your environment, you may want to implement some sort of automatic check.

JASP Meta: November 2018 Edition

Matt Konda No Comments

Building JASP has been a really interesting experience for all of us at Jemurai (  This post captures some of what I think we’re seeing and learning right now.

We bootstrapped.  Lots of people think raising venture capital for an idea is the best way to build and grow.  We still bootstrapped.  That means we paid for all of the development of the tool by also working our tails off on client projects.  Some of those client projects were cloud security audits, and that’s where the whole idea came from.  Keeping close to clients needs has actually helped us.  Bootstrapping also means we’ve stayed very lean.  Which I hope means the team feels an organic sense of ownership and learning as we go.  We’re hungry.  Not scared.  But hungry.

As consultants and engineers, we are sure there is a lot of value in the JASP tool.  It makes it easy to find and fix AWS security issues.  It provides ongoing visibility and notifications when something isn’t right.  We have learned a lot from the awesome tools listed below in the references and you can run a lot of those by hand to get some of the results JASP gives.  But you have to figure out how to run those tools and digest the results.  We tried to build a tool around a lot of those same ideas that would take away a lot of the complexity of running the tool and exchange that for clearer information and resources for the user.  We believe there is a significant need for easier to use tools that don’t take a dev team or DevOps process and pull them out of the things they know.

I believe someone can get started in JASP in < 10 minutes and get the benefit of daily checking and alerting around AWS security items, for a price that is a small fraction of having someone do it by hand.  – MK

What I am personally learning is that having a tool with value isn’t enough.  I can show people the results, help them fix real security issues and while they are happy to have fixed them – they don’t necessarily feel a clear and present need to buy the tool.  It is still a “nice to have”.  Even most people who might want to try it for free can’t make the time.  People that do try it for free, rarely opt in to purchase unless they need the deeper support we can provide at the higher tiers.  It could be discouraging but I understand, there is so much noise and everyone is so busy, we need to make it easier and find the best ways to communicate about it.

Of course, one big goal was to be able to provide this value in a leveraged way, with a software platform.  We didn’t want to be constrained by what our team could do by hand.  (And of course, we wanted to be a SaaS business with a great hockey stick J curve)  So we’ve been trying to find ways to get the message out about our product.

As we’ve engaged with firms to help us with marketing and growing the idea beyond our technical ideation, we’ve learned more.  We digested their suggestions and it is clear that almost any framing of the tool comes off as a gross oversimplification.  Very common advice is to scare people or drive people to the tool with Compliance.  There’s a place for fear and compliance, but I told myself a long time ago I didn’t want to be one of those security firms.  I hate the idea of using people’s fear and ignorance to get them to buy my tool.  From the beginning, I have wanted to find developers and put tools in their hands that made their lives remarkably better.  I wanted to approach security as a constructive partner, helping people to do the right thing with a positive spin.  I believe by approaching the space this way, we can earn long term trust from partners.

But of course, like I said we also want to grow beyond what we can do directly with word of mouth.  So, following marketing advisors input, we have run ads on various platforms.  We have tried several messaging approaches.  All suggest that what we’re doing isn’t resonating for people in a major way yet.  We have done a couple of feature releases we think might help (better prioritization, user management, dashboards, reporting) but ultimately, we’re at that place where we’re not chasing users by adding more features – we’re trying to find the right messaging, framing, pricing, etc. to make the tool relevant and useful to people.

When I started my career, I hated having to build new features that sales people had already promised to customers.  Now, I’m laughing at my old self and thinking about how hard I would work for each new customer.  That’s not to say I am willing to lose my identity chasing them, but I definitely underestimated the complexity of building and running a software business – in particular the ability to engage with customers and have lots of great learning conversations.  I assumed that with a free tier in the tool we’d be having lots of those conversations.

There is a lot more to do here in terms of building a platform for automation.  The vision has always been to be able to do Azure, GCP and even integrate Glue for source code analysis.  We want to make these kinds of analysis really easy so that they just show up where developers need them.  We want to be an API first backbone for security automation that makes it possible to quickly apply new tools, rules, etc.  Yes, we can build some of these things into one off Jenkins jobs or run them as scripts, but there is a lot more value when the results are aggregated, stored over time, compared to industry standards, and get escalated with support to fix.

It will be very interesting to continue to learn what the industry has an appetite for.  The good news is that it’s all been fun along the way and its the journey not only the destination that matters.