SSRF 공격 방지
URL을 검증하고 외부로 나가는 네트워크 요청을 제한하여 서버 측 요청 위조(SSRF) 취약점을 식별하고 완화하는 방법을 학습합니다.
SSRF 공격 방지은(는) CoddyKit의 무료 Secure Coding & OWASP Top 10 for Backend 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 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!
자주 묻는 질문
“SSRF 공격 방지” 강의는 무료인가요?
네 — “SSRF 공격 방지” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Secure Coding & OWASP Top 10 for Backend 강의 전체를 잠금 해제할 수 있습니다. Secure Coding & OWASP Top 10 for Backend 강의에는 총 4개의 강의가 포함되어 있습니다.
“SSRF 공격 방지”에서 뭘 배우나요?
URL을 검증하고 외부로 나가는 네트워크 요청을 제한하여 서버 측 요청 위조(SSRF) 취약점을 식별하고 완화하는 방법을 학습합니다. 브라우저에서 직접 실행하는 실습 코드로 Secure Coding & OWASP Top 10 for Backend을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Secure Coding & OWASP Top 10 for Backend을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Secure Coding & OWASP Top 10 for Backend은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“SSRF 공격 방지” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Secure Coding & OWASP Top 10 for Backend 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Secure Coding & OWASP Top 10 for Backend 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.