여기서 다룰 내용은 다음과 같습니다.
웹 애플리케이션 보안이란 웹 애플리케이션을 보호하는 것으로, 이는 애플리케이션 자체와 데이터를 악의적인 공격으로부터 보호하기 위한 다양한 조치를 포함합니다.
웹 애플리케이션의 보안의 주요 목표는 무단 접근, 변경, 삭제, 도난으로부터 데이터를 보호하고, 애플리케이션의 기능 및 서비스가 계속 정상적으로 작동하도록 하는 것입니다.
주요 특징들은 다음과 같습니다.
이러한 문제들을 해결하기 위해선 여러 기능들이 고려되어야 하고 적용되어야 합니다.
소프트웨어 시스템에서 보안은 애플리케이션 수준에만 적용되는 것이 아닙니다. 애플리케이션 수준뿐만이 아니라 네트워킹도 고려해야 할 수 있고, 스토리지에도 적용되어야 합니다.
그리고 모든 서버는 운영 체체 즉, 서버 위에서 동작하므로 서버의 보안도 신경을 써야 합니다.
하지만, 이러한 모든 범위의 보안을 다루기에는 내용이 너무 복잡하기에 여기서는 애플리케이션을 개발하는 백엔드 개발자가 필수적으로 알아야 하는 개념들 위주로 다뤄보려고 노력할 것 입니다.
다만, 여기서 필수적이라는 단어에서의 기준은 필자의 기준임을 적어놓고 갑니다.
보안이 중요한 이유를 생각할 때 가장 좋은 방법은 사용자의 관점에서 보는 것입니다.
애플리케이션을 사용하는 사용자들은 자신들의 중요한 정보를 맡김으로써 애플리케이션을 사용하는 경우가 많습니다.
이러한 상황에서 보안이 취약하다면 사용자들의 중요한 개인 정보들이 탈취될 위험이 있습니다.
좀 더 다른 상황의 경우로 만약 사용자가 은행 관련 애플리케이션 혹은 이커머스 서비스를 사용하고 있다고 가정해봅시다.
사용자는 돈과 관련된 작업을 수행할 가능성이 높고, 만약 이 상황에서 사용자로부터 왔다고 생각한 요청이 사실은 공격자가 수행한 것이라면? 이로 인해서 사용자의 계좌에 잔액이 차감이 된다면?
이러한 상황들만으로도 볼 수 있듯이 애플리케이션이 정상적으로 운영되기 위해서 보안은 굉장히 중요한 요소로 자리잡고 있습니다.
보안의 취약점으로 인한 장애 발생은 곧, 사용자의 신뢰성을 떨굴 수 있고 이것은 운영에 큰 지장을 줄 것입니다.
취약점은 악의적 의도를 가지고 원치 않는 작업을 수행하는 데 이용할 수 있는 악점입니다.
일반적인 취약성의 목록은 다음과 같습니다.
여기서 예시로 들 것은 초기 계발 단계에서 놓치기 쉬울 법한 것들을 적어놓겠습니다.
먼저, 흔히 하는 실수가 에러 메시지에 대한 취약점 노출입니다.
개발을 접한지 얼마 안된 분들이 "착각"하기 쉬운 것 중 하나는 "메시지"는 최대한 자세하게 전달되어야 한다고 생각하는 것입니다.
"메시지"는 최대한 추상적인 것이 좋습니다. 메시지 자체만으로 애플리케이션의 동작 구현이 노출될 수 있기 때문에 이것은 보안 취약점으로 이어지기 쉽습니다.
예를 들어서, 잘못된 요청(예: 일부 정보 누락) 때문에 앱에서 NullPointerException
이 발생하는 경우 응답 본문에 예외가 나오지 않도록 해야합니다. 누락된 필드들이 무엇인지 메시지에 담아서 보내는 것은 보안 취약점이 될 수 있습니다.
다음 메시지에 문제의 소지가 있는 부분을 확인해 봅시다.
{
"상태": 500,
"오류": "내부 서버 오류",
"메시지": "IP 주소 10.2.5.8/8080에 대한 연결이 발견되지 않음",
"경로": "/product/add"
}
예외 메시지에 IP 주소가 공개된 것을 알 수 있습니다. 공격자는 이 주소를 보고 네트워크 구성을 파악하고 최종적으로 인프라의 VM을 통제하는 방법을 찾아낼 수 있습니다.
당연하지만, 응답에 예외 스택을 넣는 것도 좋지 않습니다. 이것으로 인해 애플리케이션의 내부 구조가 공개될 수 있습니다. 로그를 보고 종속성의 버전이 확인될 수 있고, 이것이 취약점으로 이어질 수 있습니다.
공격자는 극히 작은 세부 정보까지 활용합니다.
다음의 예를 봅시다.
응답 A:
{
"상태": 401,
"오류": "권한 없음",
"메시지": "사용자 이름이 올바르지 않음",
"경로": "/login"
}
응답 B:
{
"상태": 401,
"오류": "권한 없음",
"메시지": "암호가 올바르지 않음",
"경로": "/login"
}
이 예에서 응답 A와 B는 같은 인증 엔드포인트를 호출한 다른 결과를 보여줍니다.
컨택스트 정보를 공개하는 메시지에는 숨겨진 취약점이 있을 수 있습니다. 엔드포인트에 제공된 다양한 입력에 대해 다른 메시지를 제공하면 이 메시지를 이용해 실행 컨텍스트를 분석할 수 있습니다. 예를 들어 사용자 이름은 맞고 암호는 틀린 상황을 식별할 수 있으므로 시스템이 무차별 대입 공격에 더 취약해질 수 있습니다.
클라이언트로 반환되는 응답이 특정 입력이 무엇인지 추측하게 도와줘서는 안됩니다.
OAuth 2.0은 인터넷 사용자가 비밀번호를 제공하지 않고도 한 서비스(클라이언트 애플리케이션)가 다른 서비스(리소스 서버)에 대해 사용자를 대신하여 정보를 접근할 수 있도록 하는 표준입니다.
즉, 사용자(사람)이 브라우저(호스트)를 통해 애플리케이션에 접속을 하려고 OAuth 2.0 기능을 이용할 경우 다른 애플리케이션(OAuth 2.0 서비스 서버, 예를 들면 구글 로그인이나 깃허브 로그인 등)의 로그인 정보를 이용해서 우리 애플리케이션에 접속하여 사용할 수 있게 해주는 기능입니다.
OAuth 2.0의 주요 특징은 다음과 같습니다.
OAuth 2.0을 사용함으로써 가져갈 수 있는 이점은 해당 서비스를 이용하는 애플리케이션에서 사용자 인증 정보를 관리할 필요가 없음에 있습니다.
여러 보안들을 자체적으로 제공해주는 것 또한 장점이겠지만, Open ID Connect
를 이용하여 운영하고 있는 애플리케이션에서 인증 정보를 별도로 관리하지 않게 되면서 자체적인 서비스에 집중할 수 있도록 해줍니다.