2

The URL with the exercise is: https://portswigger.net/web-security/ssrf/lab-ssrf-with-whitelist-filter

The solution is:
http://localhost:80%2523@stock.weliketoshop.net/admin/delete?username=carlos

A little simplified (no port specified):
http://localhost%2523@stock.weliketoshop.net/admin/delete?username=carlos

We can concentrate simply on:
http://localhost%2523@stock.weliketoshop.net

Why is the credential component (everything before the @) processed as if everything after the @ is part of a URL fragment? Before double encoding the # character, the URL looks like this:
http://localhost#@stock.weliketoshop.net

Why is the @ even necessary, even after we double encode the #? Why does http://localhost%2523stock.weliketoshop.net (not no '@') not work? Does the url fragment statement take priority over the credential statement? Why is the @ ignored in favor of the #?

schroeder
  • 123,438
  • 55
  • 284
  • 319

2 Answers2

1

As per the RFC 3986:-

The userinfo subcomponent may consist of a user name and, optionally, scheme-specific information about how to gain authorization to access the resource. The user information, if present, is followed by a commercial at-sign ("@") that delimits it from the host.

RFC3986 section-3.2.1

Aayush
  • 557
  • 6
  • 17
0

I played with this recently. The SSRF filter is checking to see if the parameter value is an actual URL with a stock.weliketoshop.net hostname. It's not a simple string check. That's why if we use http://localhost%2523stock.weliketoshop.net it sees it as http://localhost#... and not working.

If you add '@' then the filter sees http://username@stock.weliketoshop.net which is the accepted hostname. Now if we use http://localhost%2523@stock.weliketoshop.net that passes the filter and the web server directs it to http://localhost#...

The mysterious part is why http://localhost%2523@stock.weliketoshop.net/admin works. It looks like there's another filter that strips everything from %25 until it sees / and concatenates, which leads tohttp://localhost/admin. The normal web server should ignore /admin at the end as it's after the # segment.

I enumerated all the characters and discovered that %252f and $253f also work which are / and ? respectively. I tried http://localhost%252fadmin%2523@stock.weliketoshop.net which still passes the filter and makes more sense but again the result was that everything after %25 was stripped so it goes to http://localhost only.

My conclusion is that Portswigger created a custom filter for the sake of the tutorial which doesn't exactly resemble a real-world SSRF filter.

1chk0v
  • 1