[Security] XSS와 CSRF 공격 해결

서정범·2024년 1월 29일
0

보안

목록 보기
7/9

여기서는 XSS와 CSRF의 공격들을 해결하기 위해서 고려해볼 수 있는 기능들을 얘기할 것이고, 최종적으로 CSP(Content Security Policy)에 대해서 이야기해보겠습니다.

SOP와 CORS의 취약점

브라우저는 외부에서 리소스를 마구잡이로 받아오는 사태를 방지하기 위해서 SOP(Same Origin Policy) 정책을 세웠습니다.

해당 정책으로 리소스로부터 같은 출처를 가진 서버에게만 추가적인 리소스에 대한 응답을 받을 수 있게 되었습니다.

하지만, 인터넷의 경우 다른 서버와 통신을 하여서 리소스를 받아와야 되는 경우가 많았고 그렇기 때문에 SOP 정책을 완화시켜주기 위한 정책인 CORS(Cross-Origin Resource Sharing)이 등장했습니다.

CORS는 서버측에서 요청 허용 범위를 결정하는 방식으로 특정 출처에 대한 요청 허용을 설정해줄 수 있습니다.

여기까지 봤을 때, 해당 두 정책은 다음과 같은 문제점들을 해결했다고 볼 수 있을 것 같습니다.

  • 허락되지 않은 출처의 리소스에서 멋대로 다른 서버의 리소스를 담을 수 없게 되었습니다.
  • Preflight 기능과 같이 동작하여 불필요한 네트워크 트래픽 발생을 미연에 방지할 수 있습니다.

이 외에도 여러 가지 이점들이 있을 수 있겠지만, 여기까지 정리하도록 하겠습니다.

CORS의 등장으로 SOP 정책은 유연성을 보장할 수 있게 되었지만, 반대로 다른 문제도 생겼습니다.

많은 SOP의 설명 중에서 XSS(Cross Site Script)를 막아준다는 이야기가 있습니다.

하지만, CORS 정책을 같이 활성화 시킬 수 있게 되면서 SOP는 XSS를 완벽히 막을 수 없게 되었습니다.

XSS는 리소스에 특정 스크립트를 작성하여 다른 사용자들이 해당 리소스를 브라우저로 가져왔을 때 스크립트가 동작하도록 하여 원치 않은 동작을 수행하도록 하는 것입니다.

즉, 여기서 봐야되는 문제는 스크립트 실행요청에 대한 처리입니다.

SOP를 사용하더라도 스크립트 실행은 막을 수 없습니다. 하지만, 요청에 대한 응답이 돌아오는 것은 막을 수도 있습니다.

예를 들어서,

  • 공격자가 특정 웹사이트의 댓글로 스크립트를 삽입했다고 가정해봅시다.
  • 희생자의 브라우저에서 해당 특정 웹사이트의 리소스를 받아오면서 댓글에 적혀있는 스크립트가 동작하게 됩니다.
  • 해당 스크립트는 특정 사이트(공격자가 통제하는 사이트)로 요청을 보내어 악의적인 동작을 수행해서 응답을 보내는 동작을 수행합니다.
  • 스크립트가 동작하면서 응답을 받아오게 됩니다.

여기서, 만약 SOP만 사용을 한다면 응답은 브라우저 측에서 거부될 것입니다.

하지만, CORS 정책을 사용하여 공격자가 자신의 웹사이트의 CORS 설정에서 Access-Control-Allow-Origin의 설정을 와일드카드인 "*"로 설정해 놓는다면 해당 응답을 받을 것입니다.

이러한 보안적인 취약점이 발생할 수 있기 때문에 허용되지 않는 스크립트를 실행시키는 것은 최대한 피하는 것이 좋습니다.

아래 블로그에서 제가 생각했던 내용들을 너무 잘 정리해 주셨습니다. 참고해보시면 좋을 것 같습니다.

해당 블로그에서 정리된 것을 간단하게나마 정리를 하자면,

SOP와 CORS는 서버측에서 요청에 대한 접근 제한을 걸어서, 동작 수행 결과의 응답을 브라우저로 보내도 서버측에서 허용하지 않았다면 브라우저가 응답을 버려버리는 작업을 수행합니다. 만약, preflight를 사용한다면 본 요청조차 보내지 않을 것입니다.

따라서, 서버가 일반적인 서버라면 클라이언트 출처의 허용 범위를 정상적으로 설정해놓았을 것이고 이것을 이용해서 본 요청처리 하는 것을 막아줄 수 있습니다.

하지만, 문제는 서버가 정상적인 서버가 아닌 공격자가 통제하는 서버일 경우 문제가 발생합니다.

서버 차체가 공격자가 관리하고 있기 때문에 공격에 사용되는 서버로 사용하기 위해서 Access-Control-Allow-Origin을 와일드 카드 "*"를 사용할 것이고, 이것으로 인해서 오염된 서버로부터 오는 응답까지 받아버릴 것입니다.

결국, 오염된 서버로 요청을 보내는 작업을 최대한 피하기 위해서 우리는 다른 방식을 고려해봐야 합니다.

해당 문제를 고려하기 위해 먼저 고려할 수 있는 방법은 Cookie를 보호하는 것입니다.

해당 방식은 요청, 응답 처리 자체를 막을 수는 없지만 탈취될 경우 위험한 데이터를 보호하자는 목적으로 사용될 수 있습니다.

쿠키의 경우, 토큰 혹은 필요한 정보들을 저장하는데 사용되고 필요에 따라 세션 데이터도 저장되어 있을 수 있습니다.

따라서, 외부에서 쿠키에 접근하는 것을 최대한 막아야 하는데 그럴 때 사용할 수 있는 속성중 하나는 HTTP Only 설정입니다.

HTTP Only 설정을 쿠키에 걸어둘 경우 쿠키는 통신 과정에서만 자동으로 전송되고, 스크립트를 통해서 접근할 수 없습니다. 따라서, 외부에서 스크립트를 통해 쿠키의 탈취가 불가능해 진 것입니다.

외에도, 통신 과정에서 패킷 탈취가 발생하지 않기 위해서 secure 속성을 고려해볼 수 있습니다. 해당 속성을 사용할 경우 암호화된 통신 프로토콜인HTTPS를 통해서만 쿠키를 전송할 수 있게 제한합니다.

마지막으로 same-site 옵션을 고려할 수 있습니다.
과거에는 same-site 옵션이 None으로 설정되어 있어서, 서드 파티의 경우에도 쿠키를 전송하기 때문에 보안적으로 문제가 발생할 수 있었습니다.

하지만, 정책 변경으로 Lax 모드로 바뀌면서 특별한 경우가 아니라면 퍼스트 파티의 통신에 한해서만 쿠키를 전송하기 때문에 이전보다 더 안전해 졌습니다.

Cookie를 통해 정보가 탈취될 수 있는 상황은 어느정도 피했지만, 여전히 의도치 않은 요청과 응답을 처리할 수 있는 상황이 남아있습니다.

CSRF Token의 취약점

CSRF Token의 사용 목적은 사용자의 행동을 한번 더 검증하면서 보안을 강화하기 위해서 사용한다고 했습니다.

CSRF Toekn을 활용하는 방법은 실제 사용자의 사용성에 영향을 주지 않는다는 장점을 가지고 있지만 다소 간단하게 우회할 수 있는 단점을 가지고 있습니다. CSRF Token을 클라이언트에게 전송하는 방법은 회원 정보 수정 페이지 등에서 보이지 않는 input을 만들어 랜덤함 문자열을 CSRF Token으로 출력합니다.

이후, 수정 기능을 처리하는 페이지에서 출력한 CSRF Token과 전송된 CSRF Token 값을 비교하여 해당 요청이 이전 페이지에서 전송되었는지 확인할 수 있습니다.

하지만 이 방법 또한 요청 전 페이지의 응답 값을 가져와서 CSRF Token 추출 후 데이터 전송 시 CSRF Token 값과 함께 전송하면 우회할 수 있으므로 CSRF Token 취약점에 대한 완전한 방어는 불가능합니다.

[Google CAPTCHA 이미지 예제]
Google CAPTCHA 이미지 예제

이러한 문제를 해결하기 위해 실제 사람인지 컴퓨터 프로그램을 통해 전송되는 요청인지 확인하는 기술인 CAPTCHA(Completely Automated Public Turing test to tell Computers and Humans Apart)를 이용하여 대부분의 CSRF 취약점을 차단할 수 있습니다. CAPTCHA는 행위, 오디오, 이미지등을 통해 기계와 사람을 구별할 수 있도록 하는 기술입니다.

해당 방식은 사용자의 경험을 저해시킬 수 있지만, 보안적으로 우수한 성능을 가지고 있었기에 과거에 자주 활용되었던 방식입니다.

하지만, AI의 발전으로 전통적인 CAPTCHA는 기계 학습 알고리즘등을 통해 해결할 수 있게 되었습니다. 더욱 복잡하고 정교한 CAPTCHA를 사용한 시스템을 사용할 수 있지만 이것은 사용자 경험을 더욱 저해시키게 됩니다.

CSP

CSP(Content-Security-Policy)는 웹 보안의 중요한 표준 중 하나로, 웹사이트 관리자가 어떤 리소스가 웹 페이지에서 로드되거나 실행될 수 있는지를 알려주는 방법입니다. CSP의 주요 목적은 XSS(Cross-Site-Script)와 같은 공격을 방지하여 웹사이트의 보안을 강화하는 것입니다.

작동 방식

CSP의 작동 방식은 다음과 같습니다.

  1. HTTP 헤더를 통한 구현: CSP는 주로 HTTP 응답 헤더(Content-Security-Policy)에 정책을 포함시켜 구현합니다. 웹 서버는 이 헤더를 설정하여 브라우저에 정책을 전달합니다.
  2. 리소스 출처 제한: CSP를 통해 웹사이트 관리자는 스크립트, 이미지, CSS, 플러그인 등이 로드될 수 있는 출처를 지정할 수 있습니다. 이를 통해 외부 출처로부터의 잠재적으로 위험한 리소스의 로드를 제한합니다.
  3. 스크립트 실행 제한: CSP를 사용하여 인라인 스크립트나 eval()과 같은 특정 JavaScript 기법의 사용을 제한할 수 있습니다.

장점

  • XSS 공격 방지: CSP는 악의적인 스크립트가 웹 페이지에 삽입되는 것을 방지함으로써 XSS 공격에 대한 보호를 제공합니다.
  • 데이터 탈취 방지: 외부 출처로부터의 스크립트 실행을 차단하여, 사용자 데이터의 탈취를 방지합니다.
  • 보안 정책의 유연성: 다양한 지시어를 통해 세부적이고 유연한 보안 정책을 설정할 수 있습니다.

지시어

  • default-src: 기본적으로 모든 리소스에 대한 로딩 출처를 지정합니다.
  • script-src: 스크립트가 로드될 수 있는 출처를 지정합니다.
  • style-scr: 스타일시트가 로드될 수 있는 출처를 지정합니다.
  • img-src: 이미지가 로드될 수 있는 출처를 지정합니다.

최종 결론

이제까지 배운것들을 적용해가며 정리를 해봅시다.

먼저, XSS는 여러 경우의 수로 발생할 수 있으며 모두 고려할 필요가 있고 CSRF 공격도 예방을 해야 한다고 언급 했습니다.

공격자가 사용자의 쿠키를 악이용하는 것을 예방하기 위해서 우선적으로 고려할 수 있은 것은 중요한 쿠키의 경우 HTTP Only 설정을 걸어두고, same-site 설정을 적절하게 하면서 예방할 수 있습니다.

서버에서 관리하는 리소스를 무분별하게 여러 사이트에서 사용되는 것을 방지하기 위해서 서버측에서 설정할 수 있는 SOP 정책이 있었고, 여러 출처들이 어느 정도 리소스를 공유할 수 있도록 해주는 CORS 정책을 확인했습니다.

공격자가 통제하는 사이트의 리소스를 브라우저에서 실행하게 되면서 발생할 수 있는 CSRF 공격CSRF Token을 사용하면서 회피할 수 있으며, 좀 더 보안성을 높이는 전통적인 방법으로 CAPTCHA를 활용할 수 있는 것을 확인했습니다.

공격자가 스크립트를 삽입하여 공격하는 방식인 XSS를 회피하기 위해서는 위에서 언급한 CAPTCHA를 고려해 볼 수 있지만, 스크립트 실행 자체를 막을 수 있는 CSP 방식이 있다는 것을 확인했습니다.

이렇게 여러 보안 방법이 있는 것을 확인했고, 실제로는 이보다 더 복잡한 형태로 사용할 것임을 짐작할 수 있을 것 같습니다.

참고한 자료

profile
개발정리블로그

0개의 댓글