防止 SSRF 攻击
学习通过验证 URL 和限制传出的网络请求来识别并缓解服务器端请求伪造(SSRF)漏洞。
防止 SSRF 攻击 是 CoddyKit 上的免费 Secure Coding & OWASP Top 10 for Backend 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Secure Coding & OWASP Top 10 for Backend 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Secure Coding & OWASP Top 10 for Backend 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
Understanding SSRF Attacks
Server-Side Request Forgery (SSRF) is a critical web security vulnerability. It tricks a server into making requests to an unintended location, often internal resources or other external services.
Imagine your backend application acts as a proxy, fetching data or resources on behalf of a user. If an attacker can control the destination of these requests, you have an SSRF vulnerability.
How SSRF Works
Here's how SSRF typically works:
- Your application accepts a URL from a user.
- The server then makes a request to that URL to fetch data (e.g., an image, a file, a webpage).
- An attacker provides a malicious URL, pointing to an internal IP address or a sensitive service.
- The server, trusting the input, makes the request, potentially exposing internal data or services.
The Dangers of SSRF
The consequences of a successful SSRF attack can be severe:
- Access to internal systems: Attackers can scan internal networks, access databases, or administrative interfaces.
- Cloud metadata exposure: On cloud platforms (AWS, GCP, Azure), SSRF can expose sensitive instance metadata, including temporary credentials.
- Interaction with other services: The server might be forced to interact with other APIs or services it has access to, performing unauthorized actions.
- Port scanning: Attackers can use the server to scan ports on other internal or external machines.
Vulnerable Code in Action
Consider a simple backend service that fetches content from a user-provided URL. This Java example shows a common pattern that can lead to SSRF.
The fetchContent method directly uses a user-supplied URL to make an HTTP request without validation.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
public class Main {
public static void main(String[] args) {
// In a real app, this URL would come from user input (e.g., a web parameter)
String userSuppliedUrl = "http://example.com/data.txt";
// Malicious example: "http://169.254.169.254/latest/meta-data/"
try {
System.out.println("Fetching content from: " + userSuppliedUrl);
String content = fetchContent(userSuppliedUrl);
System.out.println("--- Fetched Content ---");
System.out.println(content.substring(0, Math.min(content.length(), 100)) + "...");
System.out.println("-----------------------");
} catch (Exception e) {
System.err.println("Error fetching content: " + e.getMessage());
}
}
public static String fetchContent(String urlString) throws Exception {
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder content = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
return content.toString();
}
}The Power of Whitelisting
The most robust defense against SSRF is whitelisting. Instead of trying to block bad inputs, you should only allow known, safe inputs.
For URLs, this means defining a strict list of permitted domains, hostnames, or IP addresses that your application is allowed to connect to. Any request to a destination not on this list should be blocked.
Code for URL Whitelisting
Let's update our previous example to include a whitelist check. We'll define allowed domains and check the input URL against them before making any network requests.
This makes sure the server only connects to trusted external services.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.List;
public class Main {
private static final List<String> ALLOWED_HOSTS = Arrays.asList(
"example.com", "mytrustedapi.com"
);
public static void main(String[] args) {
String safeUrl = "http://example.com/data.txt";
String maliciousUrl = "http://badsite.com/evil.php";
try {
System.out.println("\nAttempting to fetch from: " + safeUrl);
String content = fetchContentSafely(safeUrl);
System.out.println("Fetched (safe): " + content.substring(0, Math.min(content.length(), 50)) + "...");
} catch (Exception e) {
System.err.println("Error fetching (safe): " + e.getMessage());
}
try {
System.out.println("\nAttempting to fetch from: " + maliciousUrl);
String content = fetchContentSafely(maliciousUrl);
System.out.println("Fetched (malicious): " + content.substring(0, Math.min(content.length(), 50)) + "...");
} catch (Exception e) {
System.err.println("Error fetching (malicious): " + e.getMessage());
}
}
public static String fetchContentSafely(String urlString) throws Exception {
URL url = new URL(urlString);
String host = url.getHost();
if (!ALLOWED_HOSTS.contains(host)) {
throw new IllegalArgumentException("Host not allowed: " + host);
}
URLConnection connection = url.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder content = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
return content.toString();
}
}Blacklisting: A Risky Approach
You might think blacklisting known bad IPs or domains is easier. However, blacklisting is inherently weak against SSRF.
Attackers can use various tricks to bypass blacklists:
- IP address encoding: Using decimal, octal, or hexadecimal representations (e.g.,
http://0x7f000001for localhost). - DNS rebinding: Changing DNS records to point a 'safe' domain to an internal IP after the initial check.
- URL shorteners: Masking malicious URLs behind a seemingly benign short URL.
- Special protocols: Using
file://,gopher://, ordata://schemes if not explicitly blocked.
Always prefer whitelisting!
Layered Defense: Network Rules
Beyond application-level URL validation, you should also implement network-level controls:
- Firewall rules: Configure firewalls to block outgoing connections from your application server to internal IP ranges (e.g.,
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.1/8). - Network segmentation: Isolate the server making external requests into its own network segment, with minimal access to other internal resources.
- Least privilege: Ensure the application's runtime environment has only the necessary network access.
These measures provide a crucial second layer of defense.
Tricky URLs and Redirects
SSRF attacks can also exploit nuances in URL handling:
- Inconsistent URL parsers: Different libraries or systems might interpret a URL differently, potentially bypassing your validation. Always use a consistent, robust parser.
- HTTP Redirects: An attacker might provide a whitelisted URL that then redirects to a blacklisted internal IP. Your application must follow redirects carefully and re-validate the final destination URL.
Always validate the resolved URL after any redirects and before making the final request.
Preventing SSRF Attacks
Which of the following is the most effective strategy to prevent Server-Side Request Forgery (SSRF) vulnerabilities?
Recap: Secure Against SSRF
You've learned how to identify and prevent SSRF attacks!
- SSRF allows a server to make unauthorized requests to internal or external systems.
- The most effective defense is URL whitelisting, allowing connections only to trusted destinations.
- Avoid blacklisting, as it's prone to bypasses.
- Supplement application-level defenses with network firewalls and segmentation.
- Be cautious of URL parsing inconsistencies and always re-validate URLs after redirects.
Keep your backend secure by strictly controlling outgoing connections!
用 AI 导师学习 Secure Coding & OWASP Top 10 for Backend — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 12
- 课程
- 48
常见问题解答
「防止 SSRF 攻击」课时是免费的吗?
是的 — 「防止 SSRF 攻击」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Secure Coding & OWASP Top 10 for Backend 课程的其余内容,请升级到 CoddyKit PRO。 Secure Coding & OWASP Top 10 for Backend 课程共包含 4 节课。
「防止 SSRF 攻击」这节课中我会学到什么?
学习通过验证 URL 和限制传出的网络请求来识别并缓解服务器端请求伪造(SSRF)漏洞。 你通过在浏览器中直接运行的动手代码来练习 Secure Coding & OWASP Top 10 for Backend,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Secure Coding & OWASP Top 10 for Backend 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Secure Coding & OWASP Top 10 for Backend 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「防止 SSRF 攻击」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Secure Coding & OWASP Top 10 for Backend 课中编写并运行代码吗?
能。每节 Secure Coding & OWASP Top 10 for Backend 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 设计安全的 RESTful API
- GraphQL API 安全
- 防止 SSRF 攻击
- 接口限流与节流