0 ratings0% found this document useful (0 votes) 207 views12 pagesServer Side Request Forgery Prevention Cheatsheet
Server Side Request Forgery Prevention Cheatsheet
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content,
claim it here.
Available Formats
Download as PDF or read online on Scribd
9725122, 6353 AM Server Side Request Forgery Prevertion - OWASP Cheat Sheet Series,
Server-Side Request Forgery Prevention Cheat
Sheet
Introduction
The objective of the cheat sheet is to provide advices regarding the protection against Server Side
Request Forgery (SSRF) attack.
This cheat sheet will focus on the defensive point cf view and will not explain how to perform this,
attack. This talk from the security researcher Orange Tsai as well as this document provide
techniques on how to perform this kind of attack.
Context
SSRF is an attack vector that abuses an application to interact with the intemal/external network or
the machine itself. One of the enablers for this vector is the mishanding cf URLs, as shaweased in
the following examples:
«+ Image on an extemal server (eg. user enters image URL of their avatar for the application to
download and use).
+ Custom WebHook (users have to specify Wethook handlers or Callback URLs).
‘+ Intemal requests to interact with another service to serve a specific functionality. Most of the
‘times, user data is sent along to be processed, and if poorly handled, can perform specific.
injection attacks.
Overview of a SSRF common flow
Intps:icheatshectseries.owasp.rgicheatshects'Server_Side_Request Forgery_Prevention_Cheat_Shecthiml ane9123/22, 8:53. AM ‘Server Side Request Forgery Prevention - OWASP Cheat Sheet Series
Attacker VulnerableApplication «Targeted Application
Crafted HTTP request
Request (HTTP, FTP..
Response
Response
Notes:
+ SSRF isnot limited to the HTTP protocol. Generally the first request is HTTP, but in cases
where the application itself performs the second request, it could use different protocols (eg.
FIR SMB, SMTP, etc.) and schemes(eg. file://, phar://, gopher://, data://, dict://,
etc).
«If the application is vuherable to XML eXternal Entity (XXE) injection then it can be exploited to
perform a SSRF attack, take a look at the XXE cheat sheet to leam haw to prevent the exposure
tO XXE,
Cases
Depending on the application’ functionality and requirements, there ate two basic cases in which
SRF can happen:
+ Application can send request only toidentified and trusted applications: Case when allow
listing approach is available.
Intps:icheatshectseries.owasp.rgicheatshects'Server_Side_Request Forgery_Prevention_Cheat_Shecthiml ane9725122, 6353 AM Server Side Request Forgery Prevertion - OWASP Cheat Sheet Series,
‘+ Application can send requests to ANY external IP address or domain name: Case when allow
listing approach is unavailable.
Because these two cases are very different, this cheat sheet will describe defences against them
separately.
Case 1 - Application can send request only to identified and trusted applications
Sometimes, an application needs to perform a request to another application, often located on
another network, to perform a specific task. Depending on the business case, user input is required
for the functionality to work.
Example
Take the example of a web application that receives and uses personal information from a user,
such as their first name, last name, birth date etc. to create a profile in an internal HR system. By
design, that web application will have to communicate using a protocol that the HR system
understands to process that data. Basically, the user cannot reach the HR system directly, but, if
the web application in charge of receiving user information is vulnerable to SSRF, the user can
leverage it to access the HR system. The user leverages the web application as a proxy to the
HR system,
‘The allow list approach is a viable option since the internal application called by the
VulnerableApplication is clearly identified in the technical/business flow. It can be stated that the
required calls will only be targeted between those identified and trusted applications.
Available protections
Several protective measures are possible at the Application and Network layers. To apply the
defense in depth principle, both layers will be hardened against such attacks.
APPLICATION LAYER
The first level of protection that comes to mind is Input validation,
Based on that point, the following question comes to mind: How to perform this input validation?
{As Orange Tsai shows inhis talk, depending on the programming language used, parsers can be
abused. One possible countermeasure is to apply the allow list approach when input validation is
Used because, most of the time, the formet of the information expected from the user is globally
known.
‘The request sent tothe intemal application will be based on the following information:
Intps:icheatshectseries.owasp.rgicheatshects'Server_Side_Request Forgery_Prevention_Cheat_Shecthiml az9725122, 6353 AM Server Side Request Forgery Prevertion - OWASP Cheat Sheet Series,
«String containing business data.
+ [P address (V4orV6).
+ Domainname
© URL
Note: Disable the support for the following of the redirection in your web client in order to prevent
the bypass of the input validation described in the section Exploitation tricks > Bypassing
restrictions > Input validation > Unsafe redirect of this document,
‘String
Inthe context of SSRF, validations can be added to ensure that the input string respects the
business/technical format expected.
‘A regex can be used to ensure that data receivedis valid from a security point of view if the input
data have a simple format (€.9. token, zip code, etc.). Otherwise, validation should be conducted
using the libraries available from the string object because regex for complex formats are
difficult to maintain and are highly error-prone,
User input is assumed to be non-network related and consists of the user's personal information.
Example:
/fRegex validation for a data having a sinple format
if(Pattern.matches( "[a-zA-Z8-9\\s\\-]{1,58)", userInput)){
//Continue the processing because the input data is valid
Jelset
//Stop the processing and reject the request
}
IP address
In the context of SSRF, there are 2 possible validations to perform
1. Ensure that the data provided is a valid IP V4 or V6 address,
2. Ensure that the IP address provided belongs to one of the IP addresses of the identified and
trusted applications,
‘The first layer of validation can be applied using libraries that ensure the security of the IP address
format, based on the technology used (library option is proposed here to delegate the managing of
the IP address format and leverage battle-tested validation function):
Verification of the proposed libraries has been performed regarding the exposure to bypasses
(Hex, Octal, Dword, URL and Mixed encoding) described in this article.
Intps:icheatshectseries.owasp.rgicheatshects'Server_Side_Request Forgery_Prevention_Cheat_Shecthiml ana9725122, 6353 AM Server Side Request Forgery Prevertion - OWASP Cheat Sheet Series,
JAVA: Method netAddressValidator.isValid from the Apache Commons Validator libtary.
+ tis NOT exposed to bypass using Hex. Octal, Dword, URL and Mixed encoding.
-NET: Method IPAddress.TryParse from the SDK.
«+ tis exposedto bypass using Hex, Octal, Dword and Mixed encoding but NOT the URL.
encoding.
‘+ As allow listing is used here, any bypass tentative will be blocked during the comparison
against the allowed list of IP addresses.
JavaScript Library ip-adidress.
« Its NOT exposedto bypass using Hex, Octal, Dword, URL and Mixed encoding.
Ruby: Class |PAddr from the SDK.
+ Itis NOT exposed to bypass using Hex, Octal, Dword, URL and Mixed encoding.
|| Use the output value of the method/library as the IP address to compare against the allow list.
‘After ensuring the validity of the incoming IP address, the second layer of validation is applied. An
allow list is created after determining all the IP addresses (v4 and v6 to avoid bypasses) of the
identified and trusted applications. The valid IP is cross-checked with that list to ensure its
‘communication with the internal application (string strict comparison with case sensitive).
Domainname
In the attempt of validate domain names, itis apparent to do a DNS resolution to verify the
existence of the domain. In general, itis not a bad idea, yet it opens up the application to attacks
depending on the configuration used regarding the DNS servers used for the domain name
resolution’
+ It can disclose information to external DNS resolvers.
+ Itcan be used by an attacker to bind a legit domain name to an internal IP address. See the
section Exeloitation tricks > Bypassing res:
ictions > Input validation > DNS
pinning ofthis document.
+ Anattacker can useit to deliver a malicious payload to the intemal DNSresolvers and the APL
(SDK or third-party) used by the application to handle the DNS communication and then,
potentially, trigger a vuherability in one of these components.
In the context cf SSRF, there are two validations to perform:
1. Ensure that the data providedis a valid domain name.
Intps:icheatshectseries.owasp.rgicheatshects'Server_Side_Request Forgery_Prevention_Cheat_Shecthiml siz9725122, 6353 AM Server Side Request Forgery Prevertion - OWASP Cheat Sheet Series,
2. Ensure that the domain name provided belongs to one of the domain names of the
‘and trusted applications (the allow listing comes to action here).
ntified
Simiarto the IP address validation, the frst layer of validation can be applied using Kbraries that
ensure the security of the domain name format, based on the technology used (library option is
Proposed here in order to delegate the managing cf the domain name format and leverage battle
tested validation function):
Verification cf the proposed libraries has been performed to ensure that the proposed functions
donct perform any DNSresolution query.
¢ JAVA: Method DomainValidator.isValid from the Apache Commons Validator library.
«.NET: Method Uri.checkHostNvame from the SDK.
+ JavaScript Library is-valid-domain,
+ Python: Module validators. domain,
+ Ruby: No valid dedicated gem has been found.
‘+ domainator, public_suffix and addressable has been tested but unfortunately they all
consider .owasp.org asa valid domain name.
This regex. taken from here, can be used: *(((?!~)) (xn-~ |_{1,1})?[a-28-9- 148, 61}[2-
20-9] {1,1)\.)*(xn--)?([a-20-9] [a-28-9\- ](@, 68} |[a-20-9-] (1, 30)\..[a-2]{2,})$
Example of execution of the proposed regex for Ruby:
donain_names = [“onasp.org”, “owasp-test.org”, "doc
test.owasp.org", “doc.owasp.ora",
“", “.owasp.org”]
donain.nanes.each { |donain-nane|
af ( domainname = /*(((?!=)) (xn-=1_{1,1})?[a-28-9- ]{@, 61} La-28-9] (1, 1)\.)*
(xn-=)2( [2-2-9] a-26-9\-]{8, 68} | [e-28-9-] (1, 38}\ . [a-21{2,))8/ )
puts "[4] #{domainnane} is VALID"
puts "[!] #{domain_nane} is INVALID"
end
$ ruby test.rb
[4] owasp.org 4s VALID
[4] owasp-test.org is VALID
[4] doc-test.owasp.org is VALID
[4] doc.owasp.org is VALID
[1] is INVALID
[1] .owasp.org is INVALID
Intps:icheatshectseries.owasp.rgicheatshects'Server_Side_Request Forgery_Prevention_Cheat_Shecthiml ez9725122, 6353 AM Server Side Request Forgery Prevertion - OWASP Cheat Sheet Series,
‘After ensuring the validity of the incoming domain name, the second layer of validation is applied:
1. Build an allow list with all the domain names of every identified and trusted applications.
2. Verify that the domain name received is part of this allow list (string strict comparison with
case sensitive).
Unfortunately here, the application is stil vulnerable to the ONS pinning bypassmentioned in this
document. Indeed, a DNS resolution will be made when the business code will be executed. To
‘address that issue, the following action must be taken in addition of the validation on the domain
name
1. Ensure that the domains that are part of your organization are resolved by your internal DNS
server frst in the chains of DNS resolvers.
2. Monitor the domains allow list in order to detect when any of them resolves to a/an’
3. Local IP address (V4 + V6).
4, Internal IP of your organization (expected to be in private IP ranges) for the domain that are not
part of your organization.
The following Python3 script can be used, as a starting point, for the monitoring mentioned above
# Dependencies: pip install ipaddress dnspython
import ipaddress
import dns.resolver
# Configure the allow list to check
DOMAINS_ALLOWLIST = ["owasp.org", “lebslinux"]
# Configure the DNS resolver to use for all DNS queries
DNS_RESOLVER = dns.resolver .Resolver()
DNS_RESOLVER.nameservers = ["1.1.1.1"]
def verify_dns_records(domain, records, type):
Verify if one of the DNS records resolve to a non public IP address.
Retum a boolean indicating if any error has been detected.
error_detected = Felse
if records is not None:
for record in records:
velue = record.to_text().strip()
try:
ip = ipaddress-ip_address(value)
# See
https: //docs .python..org/3/Library/ipaddress.html#tipaddress. IPv4Address.is_global
if not ip-is_global:
print("[!] DNS record type ‘%s' for domain name '%s' resolve
to
Intps:icheatshectseries.owasp.rgicheatshects'Server_Side_Request Forgery_Prevention_Cheat_Shecthiml m29123/22, 8:53. AM ‘Server Side Request Forgery Prevention - OWASP Cheat Sheet Series
a non public IP address ‘%s'!" % (type, domain, value))
error_detected = True
except Valuefrror:
error_detected = True
print("[!] ‘%s' is not valid IP address!" % value)
return error_detected
def check():
Perform the check of the allow list of domains.
Retum a boolean indicating if any error has been detected.
error_detected = False
for domain in DOMAINS_ALLOWLIST:
# Get the IPs of the current domain
# See https ://en.wikipedia.org/wiki /List_of_DNS_record types
th
# A = IPvd address record
Sp_v4_records = ONS_RESOLVER.query(domain, A’
except Exception as
ip_v4_records = None
print("[i] Cannot get A record for domain '%s': %s\n" % (domain, e))
# MAMA = IPv6 address record
Sp_v6_records = ONS_RESOLVER.query(domain, "AAAA”)
except Exception as e:
ip_v6_records = None
print("[i] Cannot get AAAA record for domain ‘Ss’: %s\n" %
(donain,e))
# Verify the TPs obtained
Af verify_dns_records(domain, ip_v_records, “A")
or verify_dns_records(domain, ip_v6_records, “AAA”
error_detected = True
return error_detected
af —_nane..
if check():
exit(1)
else:
exit(@)
URL
Do not accept complete URLs from the user because URL are dfficult to validate and the parser
can be abused depending on the technology used as showcased by the following talk of Orange
Tsai,
If network related information is really needed then only accept a valid IP address or domain name,
NETWORK LAYER
Intps:icheatshectseries.owasp.rgicheatshects'Server_Side_Request Forgery_Prevention_Cheat_Shecthiml ana9725122, 6353 AM Server Side Request Forgery Prevertion - OWASP Cheat Sheet Series,
‘The objective of the Network layer security is to prevent the VunerabieAppiication from performing
calls to abitrary applications. Only allowed routes will be evailable for this application in order to
limit ts network access to only those that it should communicate with,
The Firevall component, as.a specific device or using the one provided within the operating
system. will be used here to define the legitimate flows.
Inthe scheme below, a Firewall component s leveraged to mit the application's access, and in
tum, limt theimpact of an application vulnerable to SRF:
(om)
\VulnerableApplication
[ea
Attacker Application 1 (legit call)
Application 2 illegitimate call)
Network segregation (see this set of implementation advice can also be leveraged and is highly
recommended in order to block illegitimate calls directly at network level itself.
Case 2 - Application can send requests to ANY extemal IP address or domain
name
This case happens when a user can control a URL toan External resource and the application
makes a request to this URL (eg. in case of WebHooks). Allew lists cannct be used here because
the list cf IPs/domains is often unknownpfront ands dynamically changing.
Inthis scenario, Externalrefers to any IP that doesn't belong to the internal network, and shouldbe
reached by going over the public intemet.
Thus, the call from the Vulnerable Application:
+ Is NOT targeting one of the IP/domain located inside the company’s global network.
+ Uses convention defnedbetween the VulnerableApplication and the expected IP/domain in
order to prove that the call has been lesitimetely initiated,
Challenges in blocking URLs at application layer
Intps:icheatshectseries.owasp.rgicheatshects'Server_Side_Request Forgery_Prevention_Cheat_Shecthiml enn9725122, 6353 AM Server Side Request Forgery Prevertion - OWASP Cheat Sheet Series,
Based on the business requitements cf the above mentioned applications, the allow list approach
is nota valid solution. Despite knowing that the block-ist approach is net an impenetrable wall it is
the best solution inthis scenario. It is informing the application what it should net do.
Hereis why filtering URLs ishard at the Application layer
« Itimplies that the application must be able to detect, at the code level, that the provided IP (V4
+V6) is not part of the official private networks ranges including also localhost and IPv4/v6
Link-Local addresses. Not every SDK provides a builtin feature for this kind of verification, and
leaves the handling up to the developer to understand all of its pitfalls and possible values,
which makes it a demanding task.
+ Same remark for domain name: The company must maintain a list of all internal domain
names and provide a centralized service to allow an application to verify if a provided domain,
‘name is an internal one. For this verification, an internal DNS resolver can be queried by the
application but this internal DNS resolver must not resolve external domain names.
Available protections
“Taking into consideration the same assumption in the following example for the following
sections.
APPLICATIONLAYER
Like for the case n“1,itis assumed thet the IP Address OF domain nome iStequited to create the
Tequest that will be sent to the Targetapplication.
“The first validation on the input data presertted in the case n°1 on the 3 types of deta willbe the
same for this case BUT the second validation will differ. Indeed, here we must use the blodk-ist
approach.
Regarding the proof of legitimacy of the request: The TargetedAppiication that will receive the
request must generate a random token (ex: alphanumeric of 20 characters) that is expected to
be passed by the caller (in body via a parameter for which the nameis also defined by the
application itsetf and only allow characters set [a-21{1,18}) toperform a valid request. The
receiving endpoint must only accert HTTP POST requests.
‘Validation flow (if one the validation steps fail then the request is rejected):
1. The application will receive the IP address or domainname of the Targetedpplication and it
will apply the first validation on the input data using the libraries/regex mentioned in this
section,
2. The second validation will be applied against the IP address or domainname of the
TargetedAppiicatian using the following block-list approact:
Intps:icheatshectseries.owasp.rgicheatshects'Server_Side_Request Forgery_Prevention_Cheat_Shecthiml sone9725122, 6353 AM Server Side Request Forgery Prevertion - OWASP Cheat Sheet Series,
3. For IP address:
‘+ The application will verify that itis @ public one (see the hint provided in the next
Paragraph with the python code sample).
44, For domain name: 1. The application will verify that its a pubic oneby trying to resolve the
domain name against the DNSresoher that will only resolve intemal domainname. Here, it
must retum a response indicating that it do nct know the provided domain because the
expected value received must be a public domain. 2. To prevent the ONS pinning attack
described in this document, the application will retrieve all the IP addresses behind the domain
name provided (taking records A + AAAA for IPv4 + IPv6) and it will apply the same verification
described in the previous point about IP addresses.
5. The application willreceive the protocolto use for the request via a dedicated input parameter
for which it will verify the value against an allowed list of protocols (TTP or HTTPS).
6. The application will ceive the parameter name for the token to pass to the
TargetedAppiication via a dedicated input parameter for which it will only allow the characters
‘Set [a-z]{1, 19}.
7. The application will receive the token itself via a dedicated input parameter for which it will
only allow the characters set [2-24-78-9] {20}.
8, The application will receive and validate (from a security point of view) any business data
needed to perform a valid call.
9. The application willbuild the HTTP POST request using only validated information and will
send it (dont farget to disable the support for redirection in the web client usec).
NETWORK LAYER
Simiarto the following section.
IMDSv2 in AWS
In cloud environments SSRF is cften used to aocess and steal credentials and access tokens from,
metadata services (e.g. AWS Instance Metadata Service, Azure Instance Metadata Service, GCP
metadata server).
IMDSv2 is an additional defence-in-depth mechanism for AWS that mtigates some of the
instances of SSRF.
To leverage this protection migrate to IMDSv2 and disable old IMDSv1. Check out AWS
documentation for more details.
Intps:icheatshectseries.owasp.rgicheatshects'Server_Side_Request Forgery_Prevention_Cheat_Shecthiml sine9725122, 6353 AM Server Side Request Forgery Prevertion - OWASP Cheat Sheet Series,
Semgrep Rules
Semarep is a command-ine tool for offine static analysis. Use pre-buift or custom rules to enforce
code and security standards in your codebase. Checkout the Sematep rule for SSRF to
identify/investigete for SSRF vulnerabilities in Java
https://semgrep.dev/salecharohitowasp_java_ssrf
References
Online version of the SSRF bible (PDF version is used in this cheat sheet).
Article about Bypassing SSRF Protection,
Articles about SSRF attacks: Part 1, part 2 and part 3.
Article about IMDsv2
Tools and code used for schemas
¢ Mermaid Online Editor and Mermaid documentation.
Draw.io Online Editor,
Meimaid code for SSRF common flaw (printscreen are used to capture PNG image inserted into
this cheat sheet):
sequenceDiagran
participant Attacker
participant Vulnerableapplication
participant TargetedApplication
Attacker->>Vulnerableapplication: Crafted HITP request
Vulnerablespplication->>TargetedApplication: Request (HTTP, FTP...)
Note left of TargetedApplication: Use payload includedcbr>into the request
to
Vulnerablespplication
‘TargetedApplication->>Vulnerableapplication: Response
Vulnerablespplication->>attacker: Response
Note left of Vulnerablessplication: Include response
from
thecbr>TargetedApplication
Drawio schema XML code for the "case 1 for network layer protection about flows that we want to
prevent" schema (printscreen are used to capture PNG image inserted into this cheat sheet).
Intps:icheatshectseries.owasp.rgicheatshects'Server_Side_Request Forgery_Prevention_Cheat_Shecthiml sane