백엔드 API 서비스 보호하기 3탄 – 요청 사이즈 제어 & 요청 본문 유효성 검증

애플리케이션 운영을 보다 빠르고, 스마트하며, 안전하게 운영할 수 있도록 지원하는 글로벌 No.1 브랜드 <F5 네트웍스 코리아> 공식 블로그를 방문해주신 여러분, 반갑습니다! 백엔드 API 서비스 보호하기 시리즈의 마지막 편, 요청 사이즈 제어 & 요청 본문 유효성 검증에 대해 소개해 드리려고 합니다. 실제로 활용할 수 있도록 예제를 들어 설명해 드리고 있으니, 실무자라면 꼭 필독해 주세요!

​​

HTTP API는 일반적으로 요청 본문을 사용해 백엔드 API 서비스가 처리할 명령과 데이터를 포함합니다. 이는 XML/SOAP API는 물론, JSON/REST API에도 적용되지요. 결과적으로 요청 본문은 백엔드 API 서비스에 대한 공격 경로를 제공할 수 있고, 이는 대용량 요청 본문을 처리할 때 버퍼 오버 플로우 공격에 취약할 수 있습니다. 기본적으로, NGINX Plus는 1 MB를 넘는 본문을 포함한 요청을 거부합니다. 이미지 처리와 같이 대용량 페이로드를 처리하는 API의 경우에는 이 값을 늘릴 수 있지만, 대부분의 API들은 낮은 값으로 설정하고 있습니다.

​라인 19의 client_max_body_size 지시문(directive)은 요청 본문의 사이즈를 제한합니다. 이 구성을 적용하면, 가격 책정 서비스에 대한 2개의 서로 다른 PATCH 요청을 수신하는 API 게이트웨이의 동작을 비교할 수 있습니다. 첫 번째 curl 명령은 작은 크기의 JSON 데이터를 전송하는 반면, 두 번째 명령은 대용량 컨텐츠 파일(/etc/services)을 전송하려고 시도합니다.

​​

요청 본문 유효성 검증

백엔드 API 서비스는 대용량 요청 본문을 포함한 버퍼 오버플로우 공격에 취약합니다. 뿐만 아니라 유효하지 않거나 예상하지 못한 데이터가 본문에 포함될 가능성도 높습니다. 요청 본문에 올바른 형식의 JSON을 요구하는 애플리케이션의 경우, NGINX JavaScript 모듈을 사용해 백엔드 API 서비스로 프록시하기 전에 JSON 데이터가 오류 없이 파싱되는지를 확인할 수 있습니다. JavaScript 모듈을 설치한 경우, js_include 지시문(directive)을 사용해 JSON 데이터의 유효성을 검증하는 함수를 위한 JavaScript 코드가 포함된 파일을 참조합니다.

​js_set 지시문(directive)은 새로운 변수 $validated를 정의하며 이는 json_validator 함수를 호출해 평가됩니다.

​​

json_validator 함수는 JSON.parse 메소드를 이용해 요청 본문을 파싱하려고 시도합니다. 성공하면, 이 요청을 위해 의도한 upstream 그룹의 이름이 반환됩니다(라인 6). 요청 본문을 파싱할 수 없는 경우(예외로 인해), 로컬 서버 주소가 반환됩니다(라인 9). return 지시문(directive)은 $validated 변수를 입력합니다. 따라서 이 변수를 이용해 요청을 어디로 보내야 하는지 결정할 수 있습니다.

​​

Warehouse API의 정책 섹션에서 라인 24의 proxy_pass 지시문(directive)을 수정합니다. 이는 이전과 같이 요청을 백엔드 API 서비스로 전달하지만, 이제 $validated 변수를 목적지 주소로서 사용합니다. 클라이언트 본문이 JSON으로 파싱되면, 평상시처럼 upstream 그룹을 프록시합니다. 하지만, 예외가 있는 경우, 127.0.0.1:10415의 반환된 값을 이용해 클라이언트에게 오류 응답을 전송합니다.

​요청이 이 가상 서버로 프록시되면, NGINX Plus는 클라이언트에게 415 (Unsupported Media Type) 응답을 전송합니다. 이러한 전체 구성을 적용하면, NGINX Plus는 올바른 형식의 JSON 본문을 포함한 경우에만 요청을 백엔드 API 서비스로 프록시합니다.

​​


알고가자! ‘$request_body 변수’에 대한 주의 사항

JavaScript 함수 json_validator는 $request_body 변수를 사용해 JSON 파싱을 실행하지만, NGINX Plus는 이 변수를 기본적으로 입력하지는 않습니다. 중간 사본도 만들지 않고 해당 요청을 바로 백엔드로 스트리밍하지요. Warehouse API 정책 섹션의 mirror 지시문(라인 19)을 이용해 클라이언트 요청의 사본을 작성하면, $request_body 변수가 입력됩니다.

라인 20 및 21의 지시문들은 NGINX Plus가 내부적으로 요청 본문을 처리하는 방법을 제어합니다. 요청 본문이 디스크에 기록되지 않도록 client_body_buffer_size를 client_max_body_size와 동일한 사이즈로 설정합니다. 이는 I/O 작업을 최소화해 전반적인 성능을 향상시키지만, 메모리 사용량은 증가시킵니다. 이는 작은 요청 본문을 이용하는 대부분의 API 게이트웨이 활용 사례의 경우에 적절한 절충안이 될 수 있습니다.

위에서 언급했듯이 mirror 지시문(directive)은 클라이언트 요청의 사본을 만듭니다. $request_body를 입력하는 것 이외에는 이 사본이 필요하지 않기 때문에 이를 최상위 API 게이트웨이 진입점에서 정의한 “dead end” 위치(/_NULL)로 보냅니다.

​​

이 위치는 204 (No Content) 응답을 전송하는 역할을 수행하는 데 불과합니다. 이 응답은 미러링 된 요청과 관련되어 있기 때문에 무시됩니다. 따라서 원래의 클라이언트 요청을 처리하는 데 발생하는 오버헤드는 무시할 수 있는 수준이라고 생각하시면 됩니다.


악의적인 클라이언트와 오작동하는 클라이언트로부터 운영환경의 백엔드 API서비스를 보호를 위해 중점을 둔 백엔드 서비스 보호하기 시리즈, 귀사에 도움이 되셨나요? NGINX Plus는 오늘날 가장 많은 트래픽이 발생하는 인터넷 사이트의 작동 및 보호에 사용되는 API 트래픽을 관리하는 데 동일한 기술을 적용한다는 점 잊지 마시길 바랍니다. 본 포스팅에 대해 궁금하신 점은 댓글 또는 Contact F5를 통해 문의해 주세요! “Code Connects Us All!” F5 네트웍스 코리아는 귀사의 애플리케이션이 보다 빠르고 스마트하며 안전하게 운영될 수 있도록 항상 최선을 다하겠습니다.

​출처: https://blog.naver.com/f5networks_korea/221870522121

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>