블로그

SPA 확보는 팀 스포츠입니다.

로리 맥비티 썸네일
로리 맥비티
2019년 8월 5일 게시

제가 몇 년 동안 알게 된 흥미롭고도 실망스러운 점 중 하나는 네트워크 엔지니어와 애플리케이션 개발자가 앱을 보는 방식의 차이입니다. 우리는 네트워크 다이어그램에 애플리케이션이 표현되는 방식에서 이를 확인했고, 반대로 애플리케이션 아키텍처 다이어그램에 네트워크가 표현되는 방식에서도 이를 확인했습니다. 

개발자 vs 넷 관점

말할 것도 없이, 각자는 다른 사람에 대해 매우 단순한 견해를 가지고 있습니다. 

이는 보안에도 해당되는데, 네트워크와 애플리케이션뿐만 아니라 비즈니스 자체를 보호하는 역할이 무엇보다 중요해졌습니다. 보안팀이 애플리케이션을 실제로 이해하기 위해서는 전형적인 아키텍처 다이어그램의 틀에서 벗어나는 것이 중요합니다. (성공적인) 공격의 상당 부분은 애플리케이션 계층에서 실행됩니다. 우리가 다양한 유형의 애플리케이션의 고유한 특성을 인식하지 못하는 시간이 길어질수록 해당 애플리케이션은 취약한 상태로 유지될 가능성이 커집니다. 

오늘은 SPA에 대해 논의해보겠습니다. 이 특정 TLA가 무엇을 의미하는지 궁금해하는 사람들을 위해 설명드리자면, 이것은 "단일 페이지 애플리케이션"입니다. 

SPA 소개 

단일 페이지 애플리케이션이란 모든 애플리케이션 관련 작업에 대한 프레임워크 역할을 하는 단일 웹 페이지를 말합니다. 이 아키텍처는 전체 페이지를 다시 로드하는 대신 개별 DOM(문서 개체 모델) 요소를 '새로 고침'하는 방법으로서 AJAX가 등장한 Web 2.0 시절로 거슬러 올라갑니다. 이 기술은 성능을 크게 향상시켰으며, 현대적이고 단일 페이지 애플리케이션의 선구자입니다.

이러한 앱은 모바일 앱의 동작에 더 가깝습니다. 즉, 클라이언트 UI는 처음 열릴 때 로드되고 서버와의 통신에는 데이터만 포함됩니다. 즉, 서버에 대한 모든 호출에는 데이터 외에는 아무것도 포함되지 않으며 UI에 대한 모든 변경 사항은 클라이언트에서 발생합니다. 이를 통해 주고받는 데이터 양이 획기적으로 줄어들고, 상상할 수 있듯이 성능도 향상됩니다. 이런 종류의 앱은 API를 사용하여 데이터를 교환합니다.

일반적으로 우리는 대부분의 API가 REST 원칙을 사용하여 구현된다는 가정 하에 운영해 왔습니다. 즉, 각 객체(일반적으로 단일 UI 요소에 연결된 것으로 간주됨)에는 CRUD(생성, 읽기, 업데이트, 삭제) 트랜잭션을 실행하기 위해 호출할 수 있는 고유한 API가 있습니다. 보안 관점에서 보면, 주어진 API(URI) 호출에 대해 특정 형식의 데이터를 기대할 수 있으므로 작업이 다소 수월해집니다. "/update/product/123"에 전송된 데이터는 일관되게 동일한 직렬화된 객체가 되지만, "/delete/order/4433"에 전송된 데이터는 다른 직렬화된 객체가 됩니다. 즉, 특정 URI에 특정 정책을 연결하는 기존 방식을 사용하여 해당 API를 보호할 수 있습니다. 

단일 URI 패턴 

SPA는 이 패턴을 따를 수도 있고, 따르지 않을 수도 있습니다. SPA를 중심으로 한 새로운 관행은 거래를 수행하기 위해 보다 전통적인 함수-URI 매핑과 마찬가지로 동일한 API를 사용할 수 있으며 실제로 그렇게 합니다. 단일 URI 패턴 SPA를 사용하면 URI는 변경되지 않지만 서버 간에 주고받는 직렬화된 객체는 변경됩니다.

이는 단일 엔드포인트(URI)를 사용하여 여러 함수를 호출하는 SOA/XML 트랜잭션과 유사합니다. 대상 함수(엔드포인트)는 직렬화된 XML 데이터에 포함되거나 때로는 사용자 지정 HTTP 헤더에 삽입되었습니다. 이 모델에서는 요청을 수신하고 올바른 엔드포인트(서버)로 라우팅하기 전에 어떤 기능이 호출되는지 판단하는 역할을 하는 SOA/XML 게이트웨이가 필요하게 되었습니다. 

SPA를 사용하면 여러 개의 API 호출을 처리할 수도 있고, 몇 개만 처리할 수도 있습니다. 어떤 경우든 어떤 형식(아마 XML이겠지만, JSON일 가능성이 더 높음)으로 데이터를 보호해야 할 필요성을 다루고 있을 가능성이 큽니다. 즉, 콘텐츠에는 위험이 따른다는 사실을 알아야 한다는 의미입니다. 일부 데이터는 UI 요소를 동적으로 생성하는 데 사용될 수 있으므로(또는 클라이언트에서 DOM을 다시 조작하는 경우) 모든 제출에서 잠재적으로 악성인 코드를 찾아 파괴하는 것이 중요합니다. 

보안 단절 

불행히도, 다양한 기능에 대한 데이터를 교환하는 데 단일 URI가 사용되는 경우, URI에 정책을 첨부하는 기존 방식은 효과적이지 않습니다. 실제로 이러한 정책은 특정 페이로드 형식을 예상하도록 훈련되는 경우가 많기 때문에 보안이 손상될 수 있습니다. API 게이트웨이도 종종 정책(라우팅, 미터링, 액세스)을 특정 URI에 연결합니다. 즉, 다양한 데이터 형식으로 더 많은 기능을 처리하기 위해 몇 개의 URI(API 호출)만 사용하는 관행은 기존 보안을 깨뜨릴 수 있습니다.

이는 보안과 개발(DevOps가 아니라 개발자)이 코드의 첫 줄부터 배포 단계까지 더욱 긴밀하게 협력하는 것이 점점 더 중요해지고 있는 이유를 보여 주는 예입니다. 개발자가 보안 측면에서 적절한 보호 조치를 보다 쉽게 구축할 수 있도록 일찍부터 할 수 있는 작업이 있습니다. 여기에는 올바른 정책을 실행할 수 있는 지표가 포함된 HTTP 헤더를 삽입하는 것이 포함됩니다. "X-Code: 'order'"와 같이 간단한 것만으로도 보안 솔루션이 잠재적인 악용을 위해 데이터를 식별하고 이후 스캔할 수 있는 방식으로 요청을 강화할 수 있습니다.

구조적으로 보면, 적절한 보안 솔루션(WAF, API Gateway 등)으로 요청을 라우팅하기 전에 코드를 추출하고 URI를 다시 작성할 수 있는 스마트 L7 프록시가 필요할 수 있습니다. 이러한 접근 방식은 스마트 L7 프록시가 JSON과 같은 데이터 형식 언어를 말할 수 있고, 개발자가 모든 교환에 올바른 위치로 다시 작성하고 라우팅하는 데 사용할 수 있는 코드나 엔드포인트 이름을 포함하는 경우에도 작동합니다. 

안전한 스파 아키텍처

가장 좋은 방법은 애플리케이션 계층 보안을 앱 자체에 통합하는 것입니다. 그러면 성능과 보안 측면에서 최적의 균형을 이룰 수 있습니다. 하지만 항상 가능한 것은 아니며 때로는 보안 목표를 달성하기 위해 창의적인 아키텍처 솔루션이 필요합니다. 

보안은 팀 스포츠입니다

일반적으로, 개발자가 다양한 책임을 클라이언트와 서버에 분배하는 방식이 바뀌면 애플리케이션 서비스 인프라가 후속 요청 및 응답과 상호 작용하는 방식에 상당한 영향을 미칩니다. 보안, 개발자, 애플리케이션 서비스 인프라 팀이 전체 SDLC에 참여하는 것이 중요합니다. 아키텍처 솔루션도 구현하는 데 시간이 걸립니다. "끝날 때까지" 미룬다면 제품 출시에 며칠, 몇 주, 심지어 몇 달이 더 걸릴 수도 있습니다. 아니면 보안 서비스 없이 마케팅을 할 수도 있는데, 보안 서비스 없이 마케팅하는 데에는 고유한 위험(및 결과)이 있습니다.  

개발 첫날부터 협업하는 것은 앱이 프로덕션에 투입될 때 가용성, 속도 및 보안을 보장하는 가장 좋고 빠른 방법입니다.