메뉴 건너뛰기

app

내부망 침투의 교두보: CWE-918 SSRF 방지 전략

suritam92026.01.17 19:13조회 수 0댓글 0

    • 글자 크기

1. SSRF(Server-Side Request Forgery)의 위험성

SSRF는 공격자가 서버를 속여, 서버가 접근할 수 있는 내부 자원이나 외부 시스템에 악의적인 요청을 보내게 만드는 취약점입니다. 공격자는 서버가 가진 권한을 이용해 외부에서는 접근이 불가능한 내부 관리자 페이지, DB 서버, 또는 클라우드 메타데이터 서비스(예: AWS의 169.254.169.254)에 접근하여 민감한 정보를 탈취하거나 내부 시스템을 장악할 수 있습니다. 서버 자체가 공격자의 '프록시(Proxy)'가 되는 셈입니다.

2. 흔히 발생하는 취약한 패턴

주로 이미지 업로드(URL 입력 방식), 웹 후크(Webhook), 외부 RSS 피드 읽기 기능 등에서 발생합니다. 사용자가 입력한 URL을 서버가 검증 없이 HttpURLConnection이나 RestTemplate 등으로 호출할 때 보안 구멍이 생깁니다. 공격자는 http://localhost:8080/admin이나 http://192.168.0.1/과 같은 주소를 주입하여 내부 서비스의 반응을 살피고 공격 지점을 찾아냅니다.

3. 실무적 대응: 화이트리스트 기반의 목적지 통제

단순한 입력값 필터링만으로는 SSRF를 완벽히 막기 어렵습니다. 다음과 같은 다중 방어막이 필요합니다.

화이트리스트(Allowlist) 적용: 서버가 통신해야 할 외부 도메인이나 IP 리스트를 미리 정의하고, 그 외의 요청은 모두 차단합니다.

내부 IP 대역 차단: 입력받은 주소가 루프백(127.0.0.1), 사설망(10.0.0.0/8, 192.168.0.0/16 등), 클라우드 메타데이터 주소인지 확인하여 차단합니다.

URL 스키마 제한: http나 https 외에 file://, gopher://, dict:// 등 위험한 프로토콜 사용을 금지합니다.

입력값 정규화 및 DNS 검증: 호스트 이름을 IP로 변환한 후, 그 IP가 안전한 대역인지 다시 한번 검사합니다(DNS Rebinding 공격 방지).

4. CWE-918 대응 및 안전한 URL 호출 자바 코드 예시

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
 
public class RemoteResourceManager {
    private static final Logger logger = LoggerFactory.getLogger(RemoteResourceManager.class);
    
    // 허용된 외부 도메인 리스트 (Allowlist)
    private static final List<String> ALLOWED_DOMAINS = Arrays.asList("trusted-api.com", "partner-site.org");
 
    public void fetchRemoteData(String urlString) {
        try {
            URL url = new URL(urlString);
            String host = url.getHost();
 
            // [CWE-918 조치] 1. 프로토콜 제한 (http, https만 허용)
            if (!"http".equalsIgnoreCase(url.getProtocol()) && !"https".equalsIgnoreCase(url.getProtocol())) {
                logger.debug("Security Violation: Disallowed protocol -> {}", url.getProtocol());
                return;
            }
 
            // [CWE-918 조치] 2. 화이트리스트 도메인 검증
            if (!ALLOWED_DOMAINS.contains(host)) {
                logger.debug("Security Violation: Attempt to access unauthorized host -> {}", host);
                return;
            }
 
            // [CWE-918 조치] 3. 내부망/루프백 주소 차단 (추가적인 IP 검증 로직 필요)
            // if (isInternalIp(url)) { ... }
 
            logger.debug("Safe request to remote resource: {}", host);
            
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.connect();
            // 데이터 처리 로직...
 
        } catch (Exception e) {
            // [CWE-754, CWE-390] 예외 상황 로깅
            logger.debug("Error fetching remote resource: {}", e.getMessage());
        }
    }
}

코멘트: SSRF 방어의 핵심은 "서버의 발을 묶는 것"입니다. 서버가 외부의 요청에 따라 아무 곳이나 돌아다니지 못하도록 허용된 구역(화이트리스트)을 명확히 설정하십시오. logger.debug()를 통해 비정상적인 내부망 접근 시도를 기록하되, 우리 서버가 내부 자원을 탈취하는 공격자의 앞잡이가 되지 않도록 철저한 검증 루틴을 구축하는 것이 시큐어 코딩의 핵심입니다.

 
    • 글자 크기
헤더에 숨어든 공격자: CWE-113 HTTP 응답 분할 방지 전략 (by suritam9) 사용자의 권한을 훔치는 실선 없는 공격: CWE-352 CSRF (by suritam9)

댓글 달기

첨부 (0)
위로