Skip to content

06. 서버사이드 인젝션: Command·SSRF·XXE

서버가 대신 실행하거나 대신 요청하거나 대신 파싱하는 기능은 편리하지만, 입력 경계가 무너지면 서버 권한으로 위험한 동작이 일어난다.

학습 목표

  1. OS 명령 주입, SSRF, XXE가 공통적으로 어떤 구조에서 발생하는지 설명할 수 있다.
  2. 쉘 호출을 우회하는 안전한 서버 API 사용 원칙을 이해한다.
  3. 외부 URL 요청과 XML 파서에서 무엇을 제한해야 하는지 설명할 수 있다.
  4. 오래된 실습 중심 설명 대신 현재 기준의 방어 설계를 이해한다.

1. 세 취약점의 공통점

셋 다 본질은 같다.

  • 입력값이 단순 데이터가 아니라
  • 서버가 가진 실행 권한, 네트워크 권한, 파일 접근 권한으로
  • 추가 해석을 하게 만드는 문제다

즉, "사용자 입력을 어디까지 해석하게 둘 것인가"가 핵심이다.


2. OS 명령 주입은 가능한 한 구조 자체를 없앤다

원문은 시스템 명령을 직접 실행하는 예시를 중심으로 설명하지만, 현재 기준에서는 명령어 실행을 하지 않는 구조가 1순위다.

좋은 방향

  • 네트워크 진단이 필요하면 언어 라이브러리 사용
  • 파일 압축이 필요하면 표준 라이브러리 사용
  • 이미지 처리가 필요하면 안전한 전용 라이브러리 사용

피해야 할 방향

  • 사용자 입력을 붙여 쉘 명령 문자열 구성
  • sh -c, cmd /c 같은 쉘 경유 실행
  • 디버그 편의상 관리 도구를 웹에서 직접 노출

정말 외부 프로세스를 호출해야 한다면 원칙은 다음과 같다.

  • 쉘을 거치지 않는 API 사용
  • 인자를 배열 단위로 분리
  • 실행 가능한 프로그램과 인자 집합을 Allow-list로 제한
  • 타임아웃과 자원 제한 적용

3. SSRF는 "서버가 대신 요청한다"는 점이 문제다

SSRF(Server-Side Request Forgery)는 서버가 사용자 대신 다른 주소로 요청을 보내는 기능에서 자주 생긴다.

예를 들어 이런 기능이 위험하다.

  • URL 미리보기
  • 이미지 프록시
  • 웹훅 테스트
  • 외부 파일 가져오기
  • PDF 렌더링용 원격 자원 로드

왜 위험할까?

  • 외부 사용자는 접근할 수 없는 내부망에 서버는 접근할 수 있다
  • 클라우드 메타데이터 엔드포인트 같은 민감 자원에 닿을 수 있다
  • 서버가 인증된 네트워크 위치에서 요청하기 때문에 신뢰를 악용할 수 있다

4. SSRF 방어 원칙

4.1 목적지 Allow-list

호출 가능한 도메인이나 서비스 목록을 고정하는 편이 가장 강력하다.

4.2 URL 파싱과 DNS 재검증

  • 문자열로 startsWith 비교하지 않는다
  • 표준 URL 파서로 스킴, 호스트, 포트를 분리한다
  • 리다이렉트 이후 목적지도 다시 검증한다
  • DNS 재바인딩 같은 우회를 고려해 최종 IP도 확인한다

4.3 내부 주소 차단

사설 IP, 루프백, 링크 로컬, 메타데이터 주소 대역은 원칙적으로 차단한다.

  • IPv4뿐 아니라 IPv6 루프백, 링크 로컬, ULA 대역도 함께 본다
  • 클라우드 환경에서는 메타데이터 엔드포인트 차단 정책을 별도로 둔다
  • AWS를 쓰면 IMDSv2 강제를 함께 검토한다

4.4 요청 제한

  • GET만 허용할지
  • 응답 크기를 얼마나 받을지
  • 타임아웃을 얼마나 둘지
  • 어떤 헤더를 제거할지

이 정책도 같이 필요하다.


5. XXE는 현대 파서 기본값을 이해하는 것이 중요하다

원문에는 XXE를 XML 외부 엔티티 취약점으로 설명한다. 핵심 개념은 맞다.
다만 현재는 언어와 파서 버전에 따라 기본값이 더 안전해졌다는 점을 같이 알아야 한다.

실무 원칙

  • XML이 꼭 필요한지 먼저 확인
  • 가능하면 JSON 같은 단순 포맷 사용
  • XML이 필요하면 외부 엔티티와 DTD 처리를 비활성화
  • 안전한 파서 옵션을 명시적으로 켠다

특히 오래된 자료에서 자주 보이는 libxml_disable_entity_loader(true) 같은 예시는 현재 기준에서 역사적 맥락이 강하다.
현대 스택에서는 현재 사용 중인 파서의 기본값과 권장 옵션을 확인하는 쪽이 더 중요하다.


6. XXE에서 확인할 것

확인 포인트이유
외부 엔티티 허용 여부파일/네트워크 참조 위험
DTD 허용 여부엔티티 선언과 확장 위험
파서 옵션 명시 여부런타임 업그레이드 시 동작 차이 방지
업로드 XML 크기 제한파서 자원 고갈 완화

XML 파서 보안은 "기본값이 안전하겠지"라고 넘기지 말고 현재 라이브러리 문서를 한 번 더 확인하는 습관이 필요하다.


7. 원문을 현재 기준으로 다시 해석하면

원문 초점현재식 정리
명령 실행 실습웹에서 쉘 호출을 제거하는 구조 설계가 우선
XXE 실습용 외부 엔티티 예시현대 파서 기본 안전 설정과 명시적 비활성화가 우선
내부망 2차 침투 강조개발자 문서에서는 외부 URL, 메타데이터, 내부 API 접근 차단 원칙으로 정리

즉, 공격 절차를 자세히 따라가는 대신 어떤 기능이 위험한 해석을 일으키는가를 보는 편이 학습 가치가 높다.


8. PR 리뷰 체크리스트

  • 쉘 명령 호출을 대체할 표준 라이브러리가 없는가
  • 외부 프로세스를 호출해야 한다면 쉘을 거치지 않는가
  • 서버가 호출할 수 있는 URL 대상이 Allow-list로 제한되는가
  • 사설망, 루프백, 메타데이터 대역 차단이 있는가
  • XML 파서 옵션이 현재 권장값으로 명시되어 있는가
  • 외부 응답 크기, 타임아웃, 리다이렉트 정책이 제한되는가

핵심 정리

  • Command Injection, SSRF, XXE는 모두 서버가 입력을 과하게 해석할 때 생긴다
  • 가장 좋은 방어는 위험한 해석 구조 자체를 줄이는 것이다
  • 서버가 대신 요청하거나 실행하거나 파싱하는 기능은 항상 Allow-list와 제한 정책이 필요하다
  • 오래된 실습용 예제를 따라가기보다 현재 사용 중인 런타임과 라이브러리의 안전 기본값을 확인해야 한다