In last post about CORS i explained the cases where and how we can detect the presence of CORS misconfiguration, so this post will cover the one of specific case from them.
So last week while testing one of web application for CORS misconfiguration, i came across a scenario and this is how it looks like:
Request 1#
GET /settings HTTP/1.1 Host: www.site.com User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: */* Accept-Language: en-US,en;q=0.5 Referer: <Redacted> Origin: https://www.attacker.com Cookie: <Redacted> Connection: close
Response 1#
HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: User-Agent,Keep-Alive,Content-Type Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE, PUT, HEAD, PATCH Access-Control-Allow-Origin: https://www.site.com Cache-Control: no-cache, no-store, max-age=0, must-revalidate Content-Type: text/html; charset=utf-8 Date: Sat, 10 Jun 2017 00:27:22 GMT Expires: Fri, 01 Jan 1990 00:00:00 GMT .... [data]
Request 2#
GET /settings HTTP/1.1 Host: www.site.com User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: */* Accept-Language: en-US,en;q=0.5 Referer: <Redacted> Origin: http://www.site.com Cookie: <Redacted> Connection: close
Response 2#
HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: User-Agent,Keep-Alive,Content-Type Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE, PUT, HEAD, PATCH Access-Control-Allow-Origin: https://www.site.com Cache-Control: no-cache, no-store, max-age=0, must-revalidate Content-Type: text/html; charset=utf-8 Date: Sat, 10 Jun 2017 00:27:22 GMT Expires: Fri, 01 Jan 1990 00:00:00 GMT .... [data]
Request 3#
GET /settings HTTP/1.1 Host: www.site.com User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: */* Accept-Language: en-US,en;q=0.5 Referer: <Redacted> Origin: https://test.site.com Cookie: <Redacted> Connection: close
Response 3#
HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: User-Agent,Keep-Alive,Content-Type Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE, PUT, HEAD, PATCH Access-Control-Allow-Origin: https://www.site.com Cache-Control: no-cache, no-store, max-age=0, must-revalidate Content-Type: text/html; charset=utf-8 Date: Sat, 10 Jun 2017 00:27:22 GMT Expires: Fri, 01 Jan 1990 00:00:00 GMT .... [data]
Request 4#
GET /settings HTTP/1.1 Host: www.site.com User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0 Accept: */* Accept-Language: en-US,en;q=0.5 Referer: <Redacted> Origin: https://www.site.com.attacker.com Cookie: <Redacted> Connection: close
Response 4#
HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: User-Agent,Keep-Alive,Content-Type Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE, PUT, HEAD, PATCH Access-Control-Allow-Origin: https://www.site.com.attacker.com Cache-Control: no-cache, no-store, max-age=0, must-revalidate Content-Type: text/html; charset=utf-8 Date: Sat, 10 Jun 2017 00:27:22 GMT Expires: Fri, 01 Jan 1990 00:00:00 GMT .... [data]
so from request 1-3 we can see, the ACAO is properly set no matter from what Origin its requested, but in case 4 we can see the anything after domain name site.com is getting reflected back to ACAO header.
So i thought to exploit it, and after bit of confusion and quick tip from James cleared my doubts. so i enabled the wildcard entry for my domain geekboy.ninja.
And idea is of wildcard will work like this, now if i request anything in this manner: https://site.com.geekboy.ninja/exploit.html, it will valid request and exploit.html will be served from domain geekboy.ninja/exploit.html and other side, Origin will be set as: https://site.com.geekboy.ninja which is the requirement of this case.
And this is how a small misconfiguration allows attacker to bypass the SOP of website.
Takeaways for hackers: check for every variations of Origin header, for dev: use predefined ACAO dynamically.
do let me know if you have any question in comment section.