In a Server-Side Request Forgery (SSRF) attack, the attacker can abuse functionality on the server to read or update internal resources. The attacker can supply or modify a URL which the code running on the server will read or submit data to, and by carefully selecting the URLs, the attacker may be able to read server configuration such as AWS metadata, connect to internal services like http enabled databases or perform post requests towards internal services which are not intended to be exposed.
Server-Side Request Forgery occurs when an attacker can influence a network connection made by the application server. The network connection will originate from the application server's internal IP and an attacker can use this connection to bypass network controls and scan or attack internal resources that are not otherwise exposed.
Example: In the following example, an attacker can control the URL to which the server is connecting.
string url = Request.Form["url"];
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(url);
The attacker's ability to hijack the network connection depends on the specific part of the URI that can be controlled, and on the libraries used to establish the connection. For example, controlling the URI scheme lets the attacker use protocols different from http or https like:
- up://
- ldap://
- jar://
- gopher://
- mailto://
- ssh2://
- telnet://
- expect://
An attacker can leverage this hijacked network connection to perform the following attacks:
- Port Scanning of intranet resources.
- Bypass firewalls.
- Attack vulnerable programs running on the application server or on the intranet.
- Attack internal/external web applications using Injection attacks or CSRF.
- Access local files using file:// scheme.
- On Windows systems, file:// scheme and UNC paths can allow an attacker to scan and access internal shares.
- Perform a DNS cache poisoning attack.
Recommendations:
Do not establish network connections based on user-controlled data and ensure that the request is being sent to the expected destination. If user data is necessary to build the destination URI, use a level of indirection: create a list of legitimate resource names that a user is allowed to specify, and only allow the user to select from the list. With this approach the input provided by the user is never used directly to specify the resource name.
In some situations this approach is impractical because the set of legitimate resource names is too large or too hard to maintain. Programmers often resort to implementing a deny list in these situations. A deny list is used to selectively reject or escape potentially dangerous characters before using the input. However, any such list of unsafe characters is likely to be incomplete and will almost certainly become out of date. A better approach is to create a list of characters that are permitted to appear in the resource name and accept input composed exclusively of characters in the approved set.
Also, if required, make sure that the user input is only used to specify a resource on the target system but that the URI scheme, host, and port is controlled by the application. This way the damage that an attacker is able to do will be significantly reduced.
0 comments:
Post a Comment