Favorite Emojis
Prerender dynamic rendering leads to SSRF
Last updated
Prerender dynamic rendering leads to SSRF
Last updated
🎈
🏃
http://favorite-emojis.chal.acsc.asia:5000
The server uses something called dynamic rendering, which renders JavaScript on the server-side before serving web crawlers. This is meant to improve SEO.
If we look at the Nginx configuration, we can see that as long as we set our HTTP User-Agent
header to one of the web crawlers, e.g.googlebot
, the request is re-written and forwarded to the pre-renderer at http://renderer:3000
.
The goal is to get to http://api:8000/
.
If the API server was hosted on port 80 instead, there would be no need for any exploitation - the need for subsequent exploitation stems from the fact that $host
will strip the port number in the HTTP Host
header, preventing us from accessing the API server at port 8000 directly.
I came across this post which gave me the inspiration for the exploit. We know that the server uses Prerender to handle these requests. Since Prerender uses Chrome to render JavaScript, we can perform XSS within the renderer.
Set the host header so that the renderer visits our attacker-controlled site. From there, we can redirect the browser using the Location
header.
redirect.php
:
From the user's perspective, the Nginx server will return the 302 redirect, instead of the contents of the redirected site. However, the renderer's browser will still follow the redirect. It will then be redirected to our second exploit page:
exploit.html
:
Notice that the browser is currently on http://localhost:3000
, viewing the pre-rendered exploit.html
. Since both the current site and the iframe's source are http://localhost:3000
, this bypasses SOP and allows us to access the iframe's contents through the onload
handler.
This gives us the http://api:8000/
contents:
Which decodes to