Bypass filter with JavaScript RegExp.prototype​.source

Welcome to my blog!

Today I write about a technique to bypass string filters in JavaScript to trigger XSS. Some times ago, I found it after solved a CTF.
To solve that CTF, I must bypass some filters to send a DOM-based XSS to the admin bot to get his cookies. One of them is a string filter which limits the max length of the payload and restricts the existing of some strings and characters like ', ", ;, location, cookie,... So, I couldn't access some DOM attributes or make a URL to forward the admin's cookies.

After trying many techniques, I found that I can use JavaScript regular expression (regex) to construct any string without using a quote or restricted string by splitting them among the regexes.
For example:
/Hello W/+/orld!/ == "/Hello W//orld!/"
As you see, the regexes can be concatenated by a plus operator like normal strings. However, the slashes are also added to the result so I must find something to remove them and it is RegExp.prototype.source.

With RegExp.prototype.source, I could concatenate regexes without adding the slashes to the result string.
For instance:
/Hello W/.source+/ordl!/.source == "Hello World!"
The source property returns the source text of the regex, which means exactly the string inside the slashes at first and last. Now, I could also make a URL like this:
/\/ == \/
Oh, look at the example above, you can see that the URL doesn't need the http(s) prefix. Yeah, the browser also accepts both // and \/ at the beginning of an URL. No need to use the http(s) prefix any more!

The technique of using the source property of regex objects in JavaScript can be used not only in CTF but also in the real world bug bounty programs. You can bypass some hardcore string filters to trigger your XSS payloads with RegExp.prototype.source.

If you found it valuable, please share it with other people.
If you have any questions, please don't hesitate to ask me on Twitter or leave a comment.
Thank you for reading!