Server Side Request Forgery
A successful Server Side Request Forgery attack means an attacker can successfully read internal server files or execute external files by abusing website’s functionality.
There are many reasons why a web application would need to fetch data from the external website. With the growing number of public APIs ( Application Programming Interfaces ), there are no reasons to implement the whole logic and dataset again in a production environment when an application can just fetch the data from a third party website.
Consider a scenario of an ecommerce guiding web application. When you enter a product name, the webpage automatically finds the webpage from multiple ecommerce vendors and lists the price so you can compare and make an educated decision on where to purchase.
In addition to searching products from the default vendor list, you can also specify from which specific website you want the application to try and find the product.
In a typical implementation of this application, once you enter the product name and the custom url, request should look like following
http://search-cheapest-product.com/product_name=laptop&website=www.bestbuy.com
So, once this GET request is made, inside the default webpage, the application will open the bestbuy.com page for the product. So, if you instead specify www.google.com as the website, it will be loaded. This shows improper implementation of loading external websites, which amounts to potential server side request forgery attacks.
If there were any admin page which can only be accessed by authenticated admins, and everyone else will get “Unauthorized” error, an attacker can leverage the Server Side Request Forgery vulnerability to get the webpage.
Here, in the custom url field, we will set the page to be loaded to http://127.0.0.1/admin
Exploit for that would be:
http://search-cheapest-product.com/product_name=laptop&website=http://127.0.0.1/admin
When this malicious request gets to the server, backend picks up the malicious url and tries to fetch the data from the url
We will try this ssrf scenario in portswigger web security academy’s SSRF lab
Select a product and view details
Now turn the burp interceptor on and click on “check stock” to inspect the request generated by the web application
As you can see, the request is made to the endpoint /product/stock and it is a POST request which contains the stockApi parameter. Current value of the stockApi parameter is a url encoded webpage, to better view the url, we can copy the encoded url and paste it to the burp decoder
This is the url where the web application is trying to find the current stock amount. To manipulate the request, send it to the burp repeater. Either right click and select “send to repeater” or press ctrl + R.
As the objective of the lab is to access the admin page at http://127.0.0.1/admin, we can replace the application generated url with http://127.0.0.1/admin as the value of stockApi parameter and hit send
Now, the webpage of the admin portal we get has several endpoints, one of them being /admin/delete which facilitates an admin to delete any user account. We need to delete the user “carlos”, so we can send the request to http://127.0.0.1/admin/delete?username=carlos which will exploit the SSRF to delete the user account of user carlos
Now if we refresh the main page, we can see the banner confirming that we have deleted the user carlos and solved the lab
In most cases we can do more damage than just browsing restricted web pages. If the ssrf vulnerable application is hosted on AWS and running an AWS EC2 instance, we can craft the payload to access the aws metadata.
For example, if the vulnerable application from the lab was hosted on aws ec2 instance, we can change the stockApi parameter to http://169.254.169.254. If this returns an AWS metadata instance, attackers can take advantage of this vulnerability to access sensitive information of the EC2 instance such as credentials and keys as this api endpoint provides unauthenticated access. Attackers can also impersonate the role attached to the ec2 instance to deal more damage. SSRF to query AWS Ec2 is only possible if the underlying AWS metadata API is not of version 2.
So, a ssrf request to http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name would initiate a request to the ec2 instance hosting the vulnerable web application and return the security credential
Apart from reading restricted files, ssrf can also be exploited to get remote command execution on the vulnerable website.
There are certain cases where web applications load the php code from remote urls, this can also be exploited to make server side request forgery.
for example, http://www.examplepage.com?page=http://remoteapp.com/page.php
this url fetches the page.php from remoteapp.com, this can be replaced with the remote php url.
So, attacker can host the malicious php code on their malicious server and put the code as the ssrf parameter to get the vulnerable host to execute the malicious php code
Countermeasures
Server Side Request forgery is one of the hardest attacks to defend web applications from as it requires meticulously set up firewalls and restrictions. So, at first the developers need to decide if it is absolutely necessary to get the user input to form a domain name or the url to create the request. It should be impossible for the user to control which URL to send the request to.
If user input is absolutely necessary to craft the URL for the request, a whitelist based input checker should be implemented to make sure only trusted and genuine urls are requested.