SSRF는 서버 사이드 요청 위조라고 불리며, 외부에서 악의적인 사용자가 서버에게 의도하지 않은 요청을 하도록 속이는 공격입니다.
보통 서버는 외부 API나 내부 서비스로 요청을 보내는 기능을 갖고 있는데, 이 요청의 목적지 URL이 사용자로부터 입력될 수 있다면, 그 입력값을 조작해서 서버가 공격자가 원하는 위치로 요청을 보내게 만들 수 있습니다.
예시로 보는 SSRF
예를 들어 어떤 서비스가 사용자가 입력한 이미지 URL을 기반으로 이미지를 서버에서 다운로드해 보여준다고 할 때:
{
"imageUrl": "http://example.com/image.jpg"
}
그런데 공격자가 여기에 다음과 같은 URL을 넣는다면?
http://localhost:8000/admin
서버는 외부가 직접 접근할 수 없는 내부 서비스에 접속하게 되고, 민감한 정보를 공격자에게 노출시킬 수도 있습니다.
Next.js의 next/image 컴포넌트는 이미지 최적화를 위해 이미지를 서버에서 다운로드한 후 리사이징하여 클라이언트에 전달합니다. 이 과정에서 next.config.js 파일의 images.remotePatterns 또는 images.domains 옵션을 통해 허용된 외부 이미지 주소를 등록할 수 있죠.
문제의 원인
이 SSRF 취약점은 이미지 최적화 서버가 외부에서 입력된 URL을 충분히 검증하지 않고 직접 요청을 보냈기 때문에 발생했습니다.
공격자가 이미지 URL로 내부 주소(예: http://localhost, http://metadata.google.internal, http://127.0.0.1:5000) 등을 입력할 경우, Next.js 서버가 해당 URL로 요청을 보내면서 SSRF가 가능해졌던 것입니다.
정리하자면:
next/image는 성능을 위해 서버에서 이미지를 가져옴
이때 URL 검증이 충분하지 않으면 SSRF가 발생할 수 있음
공격자는 내부 네트워크로의 요청을 유도해 민감한 데이터에 접근할 수 있음
Next.js 팀은 다음과 같은 방식으로 취약점을 수정했습니다:
이미지 URL에 대해 호스트 검증 로직을 강화함
내부 IP 주소나 로컬 주소(localhost, 127.0.0.1 등)로의 요청을 차단함