우아한 테크코스/테크코스

[보안] 설계/실행의 실수에 기인한 오작동/보안 문제를 막기 위한 대책

jamie. 2020. 2. 22. 12:10
반응형

뒤로 가기 버튼

오작동

 웹 브라우저에는 한 번 표시했던 페이지를 저장해놓는 캐시(Cache) 기능이 있음, 뒤로 가기 버튼을 눌러 바로 전 페이지를 표시할 때는 해당 캐시 기능을 이용하여 웹 서버에 다시 요청을 하지 않아 작동을 빠르게 할 수 있음

 단, 위의 경우 정적인 페이지에서는 문제가 되지 않지만, 세션을 이용해 상태를 관리하는 웹 애플리케이션에서는 문제가 될 수 있음(예 - 주문 후 뒤로가기 + 앞으로가기 = 재주문)

 뒤로 가기의 경우 웹 애플리케이션 측에서 감지를 할 수 없으므로(웹 서버에 다시 요청을 하지 않기 떄문에), 다양한 오작동의 원인이 됨

대책 1 - 브라우저 캐시 무효화

 일단, 위와 같은 경우엔 브라우저가 HTML을 캐시하지 않게 막는 것이 중요

 HTTP 응답의 헤더에 아래와 같은 정보를 추가하면 됨 (HTTP/1.1)

/* 캐시에 기록된 컨텐츠라도 현재 유효한지 아닌지 서버에 문의해 확인하지 않는 한 사용하지 않게 함 */
Cache-Control: no-store, no-cache, must-revalidate

 실행 환경이나 프레젠테이션 프레임워크에서 캐시 무효화 기능을 제공하는 경우도 많으니, 구현 전에 프레임워크의 기능을 먼저 알아보면 좋음

대책 2 - 자바스크립트 이용 : 뒤로 가기 버튼 무효화

 자바스크립트를 이용해 뒤로가기 버튼을 무효화

 단, 웹 브라우저의 설정에 따라 자바스크립트 자체가 무효화될 때는 의미가 없으므로 그다지 권하지 않음

 기업 내에서 사용하는 애플리케이션처럼 환경이 제한될 때만 대책이 될 수 있음

대책 3 - 일회용 토큰 이용  

 실행하기는 번거롭지만 가장 확실한 방지책

 Hidden 매개변수로 일회용 토큰을 심어놓고 해당 토큰을 사용하게되면, 캐시가 되더라도 재실행시 토큰이 만료되었으므로 실행되지 않게 됨

이중 폼 제출

오작동

 네트워크 지연등의 이슈로 화면 전환이 빠르게 되지 않았을 때, 사용자가 두 번 이상 버튼을 클릭 등을 통해 다음 동작을 중복 발생시켜 같은 동작이 반복되는 문제 발생

대책 1 - 자바스크립트를 이용한 대책

 자바 스크립트로 버튼을 눌렀는지 값을 관리하고, 그 값을 기준으로 폼 제출 여부를 관리하는 것

 자바스크립트가 비활성화 되어있다면 효과는 발휘하지 못함

대책 2 - 일회용 토큰을 이용한 대책 

 뒤로 가기 버튼과 마찬가지로 일회용 토큰을 사용시 중복 동작시 토큰이 만료되므로, 대책이 될 수 있음

 단 사용자 편의성은 위의 자바스크립트를 이용한 대책이 더 높으므로 가능하다면 두 방법을 모두 사용하는 것이 좋음

- 자바스크립트를 이용하면 웹 브라우저에서 불필요한 요청을 아예 보내지 않기 때문임

Hidden 매개변수 이용시 주의점

Hidden 태그

 임의의 정보를 폼에 저장함으로써 요청을 통해 정보를 전달할 수 있어 매우 편리

보안 문제

 웹 브라우저에서 HTML 소스를 표시하는 방법으로 쉽게 엿볼 수 있음

 예) 로그인 중인지 아닌지 같은 애플리케이션 상태를 hidden 매개변수에 직접 보존하게 하면 사용자가 이를 쉽게 수정할 수 있음 > 이런 애플리케이션상의 상태는 세션을 이용해 애플리케이션의 서버 측에서 관리해야 함

 CSRF같은 수법 이용시 제삼자가 hidden 매개변수의 내용을 변경해 웹 애플리케이션에 보낼 수 있기 때문에 보안 구멍이 되기 쉬움

대책 - hidden 매개변수를 통해 전송된 정보를 처리할 때는 그 요청이 사용자가 의도한 것인지 확인

 이러한 확인이 필요한 상황 : 결제 처리 / 개인 정보의 갱신 처리 / 게시판 등의 글쓰기 처리

 확인 방법 : CSRF 대책인 일회용 토큰을 이용하는 방법이 효과적

 일회용 토큰은 갱신 화면이나 결제 화면을 표시할 때 서버측에서 발행하므로 일회용 토큰을 모르면 날조한 hidden 매개변수를 직접 POST해 애플리케이션에서 처리하기가 곤란해짐

 일회용이며 추측하기가 어려운 문자열이라는 특성상 공격자가 일회용 토큰을 훔치더라도 연속해서 공격에 이용할 수 없으며, 위조하기도 사실상 어려움

디버그 정보는 출력하지 않을 것

 실행 환경에 따라 애플리케이션 실행 중 발생한 에러를 웹 브라우저에 표시해주기도 함 : 문제의 원인을 조사하는 데 도움이 되기 때문에 웹 어플리케이션을 개발할 때 매우 유용

보안 문제

 시스템을 운용할 때 에러 내용을 화면에 출력하면 공격자에게 시스템의 내부 구조를 알리는 결과로 이어질 수 있음

 출력되는 정보에는 때때로 DB에 발행되는 SQL 등이 포함되고는 하는데, 이런 정보가 SQL 인젝션의 계기가 될 수 있음

대책 - 정해진 장소에 출력

 에러 정보를 그대로 브라우저에 출력하지 않고 로그 파일 등 정해진 장소에 출력하는 등 처리 방침을 확실히 정해놓고 적절히 처리

전역 변수에 정보를 담지 말 것

문제

 웹 브라우저에 출력하는 정보는 특정한 형태로 내용이 보존되는데, 그런 정보를 저장하는 곳에도 주의가 필요함

 가장 주의해야 하는 것 : 전역 변수(프로그램 전체에서 참조할 수 있는 변수)나 클래스 변수(클래스가 보유한 변수) 등 어디서나 접근이 가능한 변수에 저장하지 않는 일

 최악의 경우 동시에 이용하고 있는 다른 사용자의 정보가 웹 브라우저의 화면에 표시되어 시스템이나 기업의 신뢰를 크게 실추시키는 문제로 발전할 수 있음

문제 예) - 서블릿의 인스턴스가 동일하기 때문에 발생

  애플리케이션 서버는 쓰레드(Thread)라는 구조에 따라 여러 클라이언트로부터 동시에 요청을 받아도 그러한 요청을 동시에 실행되는 것 처럼 보이도록 밀리초 같은 매우 짧은 단위로 각 쓰레드의 처리를 전환하면서 조금씩 실행하도록 되어있음

 문제 : 서블릿이 요청을 동시에 여러개 처리할 때의 구조

 서블릿의 인스턴스 - 요청별로 생성되는 것이 아닌 애플리케이션에 딱 하나만 생성됨 > 표시에 사용하는 정보 등을 인스턴스 변수에 저장하면 동시에 접속하고 있는 다른 사용자의 정보가 잘못 표시될 수 있음

 반드시 발생하는 것은 아니며, 여러 명의 사용자가 접속하는 시점에 따라 발생하지 않을 때도 있기 때문에 테스트 단계에서 발견하기가 비교적 어려움

대책 - 화면에 표시하기 위한 정보는 세션 스코프나 요청 스코프에 저장

 화면에 표시하기 위한 정보는 세션 스코프나 요청 스코프에 저장할 것

 이 문제의 함정은 평소에는 이용해도 그다지 문제가 없었던 인스턴스 변수라는 변수에 정보를 저장했는데 정보 유출 문제가 발생했다는 점

 서블릿이 작동하는 구조를 제대로 파악하지 못하면 생각지도 못한 곳에서 보안 문제가 발생할 수도 있음

 

반응형