WAF

Grammarly fixed XSS vulnerability that bypasses AWS WAF

Grammarly is the unicorn company that announced its open bug bounty program last September. Since that time, many security researchers posted their submissions and got paid well. Some of Grammarly's issues are also useful for others. Like the recent XSS, that also bypasses an AWS WAF.

The recent XSS report is a bit different among others. First of all, it was submitted by Frans Rosen, one of the top HackerOne hackers. He is the 6th for the all-time rank.

Secondly, the report was paid for $3000 unlike tons of $50-100 XSSes on a platform.

The report title is: "Config override using non-validated query parameter allows at least reflected XSS by injecting configuration into state" https://hackerone.com/reports/1082847

This security issue is an excellent example of in-depth JavaScript research that Frans did.

Moreover, for some reason, an XSS payload that Frans used to validate this Grammarly vulnerability bypasses AWS WAF.

Let's understand why.

The payload look like a very usual XSS for the first glance:

https://app.grammarly.com/docs/new?config={%22account%22:{%22subscription%22:%22javascript:alert(document.domain)//%22},%22api%22:{%22redirect%22:%22javascript:alert(document.domain)//%22}}

It consists of a JSON-encoded config parameter that vulnerable application parse. JSON attributes subscription and redirect contains an ordinary XSS sample of alert() function call. And if we will send this request to check how does the mod_security WAF detects it, we will get the following:

2021/03/03 01:10:44 [error] 41#41: *1 [client 172.17.0.1] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `28' ) [file "/etc/modsecurity.d/owasp-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "80"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 28)"] [data ""] [severity "2"] [ver "OWASP_CRS/3.2.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "172.17.0.1"] [uri "/docs/new"] [unique_id "161473384455.381362"] [ref ""], client: 172.17.0.1, server: localhost, request: "GET /docs/new?config={%22account%22:{%22subscription%22:%22javascript:alert(document.domain)//%22},%22api%22:{%22redirect%22:%22javascript:alert(document.domain)//%22}} HTTP/1.1", host: "localhost:8080"

At the same time, AWS WAF will pass this payload with no blocking:

But, if we will remove the JSON object and use the same payload in a plain text way, AWS WAF will block it:

An attentive reader may notice that we modified the payload by adding onerror attribute to make this payload work in HTML attribute injection way. That's true, but now we can add the JSON prefix back and see what happens:

It passed! We basically found that adding JSON prefixes before payloads makes them invisible for AWS WAF. Let's understand what happened and why.

We initially decided that the reason for this bypass is behind the JSON parser. As we already discussed recently in a post WAF JSON decoding capability required to protect against API threats like CVE-2020-13942 Apache Unomi RCE

But it was not even close since AWS WAF has no JSON parsing capabilities at all.

After minifying Grammarly payload, we will get that the following request will be blocked by AWS WAF:

But adding just one additional double quote into there bypass the WAF:

The reason is not in JSON-like prefix, but the double-quote itself. We can easily remove the bracer charter and get the same bypass result with the payload ""onerror=javascript:alert('I-LOVE-AWS-WAF!').

It seems irrational but adding any numbers of double quotes before an XSS payloads bypass AWS WAF. We tested on 1500 rules enabled

Please leave a comment if you have an idea why. Thanks for reading!

Recent Posts

The CISO’s Dilemma: How To Scale AI Securely

Your board wants AI. Your developers are building with it. Your budget committee is asking…

1 week ago

Agent-to-Agent Attacks Are Coming: What API Security Teaches Us About Securing AI Systems

AI systems are no longer just isolated models responding to human prompts.  In modern production…

1 week ago

Everyone Knows About Broken Authorization – So Why Does It Still Work for Attackers?

Broken authorization is one of the most widely known API vulnerabilities.  It features in the…

3 weeks ago

From Shadow APIs to Shadow AI: How the API Threat Model Is Expanding Faster Than Most Defenses

The shadow technology problem is getting worse.  Over the past few years, organizations have scaled…

1 month ago

Inside Modern API Attacks: What We Learn from the 2026 API ThreatStats Report

API security has been a growing concern for years. However, while it was always seen…

1 month ago

CISO Spotlight: Craig Riddell on Curiosity, Translation, and Why API Security is the New Business Imperative

It’s an unusually cold winter morning in Houston, and Craig Riddell is settling into his…

1 month ago