Server-Side Request Forgery (SSRF) is a security vulnerability in which an attacker, through a flaw in the application, can make requests from the server hosting the applications. An SSRF flaw could be used to gain access to internal resources, exfiltrate data from the host that was not publicly accessible, and so on.
SSRF is an application security vulnerability and in order to mitigate SSRF, an application needs to be hardened, not the underlying host. However, one can put preemptive security controls in place on the host server, here an AWS EC2 instance, to contain the blast radius in case an SSRF attack does happen.
Preemptive Security Measures for EC2 instances against SSRF
As mentioned before, SSRF is an application security issue so the security measures we will talk about do not prevent SSRF but harden EC2 instances against SSRF attacks to limit the damage in such an event.
Enable IMDS v2
Instance Metadata Service, or IMDS, is a utility provided to the users to obtain information about the instance and various launch configuration parameters associated with it. IMDSv1 is an active service that can still be used. It stores credentials in the metadata endpoint which can be exfiltrated and abused to make calls to the AWS API with AWS CLI in the event of a successful SSRF attack. In IMDSv2, a session token is included which is required to make calls to AWS API. However, this token information is not stored as part of the metadata endpoint, making it more difficult to abuse the credentials attached to the instance or other resources.
Enable IMDSv2 for a new instance via Console
When launching an instance, under the “Configure Instance Details” page, navigate to the “Advanced Details” section and: * Select “Enabled” for the “Metadata accessible” option * Select “V2 (token required)” for the “Metadata version” option Metadata version ![EC2 Advanced Details](https://imgs.kloudle.com/academy/security-measures-against-ssrf-attacks-for-aws-ec2-instances/1673703540-ec2-advanced-details.png)
Enable IMDSv2 for new instance with AWS CLI
To enable IMDSv2 while launching an instance with AWS CLI, use the following flag in the command: ```bash aws ec2 run-instances --image-id <IMAGE_ID> \ <other required options for your instance> \ --metadata-options "HttpEndpoint=enabled,HttpTokens=required" ```
Enable IMDSv2 for existing instances with AWS CLI
Run the following AWS CLI command to modify the instance and enable IMDSv2: ```bash aws ec2 modify-instance-metadata-options \ --instance-id <INSTANCE_ID> \ --http-tokens required \ --http-endpoint enabled ```
Restrict outbound traffic from the server
Security Groups attached to an EC2 instance are typically used to restrict access to the server. It is a firewall that prevents unintended entities from reaching the server over a network, be it private or public. These security groups, however, can also be used to restrict traffic from the instance. The outbound rules in the security group can stop an attacker from making requests from the server to other resources and hinder their ability to cause more damage than they already have.
Since restricting outbound traffic is dependent on the context of what the EC2 instance is supposed to connect to, there is no one-size-fits-all solution or example that can be shared. Restricting outbound traffic for the instance would require deliberation on what the VM would need to initiate connections to and then explicitly add those specific IP addresses along with the protocol in the security group attached to the EC2 instance.
AWS has comprehensive documentation on how to create outbound rules for security groups. The only point to note is that in step 4 of the documentation, choose the “Edit outbound rules” option.
Use the lowest privilege system user
When launching instances on AWS, and virtually all other cloud providers, we are given a user with root (or Administrator) privileges. This could come in various forms, such as direct root access or a user which can act as root (for example, by using sudo with the commands). These privileged system users can be exploited in case of an SSRF attack to run privileged commands on the system as these default root (or root-like) users do not require additional authentication information such as a password.
It is a good security practice to create a non-privileged user on the instance once launched and use this lower-privilege user to run the application or code on the VM. Such a security control can stop the attacker from lurking in the server,stealing data and causing further damage. For example, an attacker that has successfully performed SSRF on a server that had MySQL installed with a database and the application was running on the default privileged user, the attacker could take a dump of the database and exfiltrate it over the network.
The steps for creating this low-privilege user for all operating systems are fairly similar and trivial to perform. As an example, here’s how you can create a low privilege user, say “app”, on an EC2 instance with Ubuntu 18.04 installed with a home directory and bash as the default shell:
- sudo useradd -m app -s /bin/bash
Server-Side Request Forgery (SSRF) is a security vulnerability where an attacker can craft requests and execute them from the underlying server. Though SSRF is an application security issue, we saw that we can take preemptive security measures to limit the blast radius and contain the damage the attacker can cause in the case of a successful SSRF attack by hardening our instances.
We looked at how we can enable IMDSv2 to subdue the exfiltration of credentials and we also looked at how we can use security groups to explicitly restrict outbound traffic from the instance preventing the attacker from making requests. Lastly, we also looked at how we should use low-privilege system users to ensure that the attacker can not run privileged commands in the case of an SSRF incident. An additional note on using lower-privilege users is that this measure can be employed on servers present on any cloud provider, like Google Cloud Platform, Azure, etc.
Since SSRF is not a cloud or infrastructure security issue, we can not prevent SSRF by hardening our cloud resources. To prevent SSRF, application security testing needs to be performed on the application. However, applying the security measures listed in this article will help in reducing the damage that an SSRF attack can cause without preemptive security measures in-place.