내 응용 프로그램의 프로세스 간 통신에 WebSocket을 사용하고 싶습니다 (Daemon <-> WebGUI 및 Daemon <-> FatClient 등). 테스트 중에 websocket.org ( http://www.websocket.org/echo.html ) 의 JavaScript WebSocket 클라이언트를 통해 로컬에서 실행중인 웹 소켓 서버 (ws : // localhost : 1234)에 연결을 시도했습니다 .
내 질문은 다음과 같습니다.
왜 이것이 가능합니까? 브라우저에 구현 된 출처 간 정책이 없습니까 (여기 : Linux의 FF29)?
websocket.org가 악한 경우 로컬 WS 서버와 통신하고 localhost에서 수신하는 모든 메시지를 다른 서버로 리디렉션 할 수 있기 때문에 묻습니다.
로컬 WebSocket 서버 브라우저 이블 웹 서버 ws : // localhost : 1234 (http : //evil.tld) | | | | | ------ [GET /] ---------> | | | <----- [HTML + EvilJS] ---- | | <------ [ws : // .. 연결] ---- | | | <---- [일부 커뮤니케이션]-> | | | | ---- [사악한 포워드] ----> | | | |
전체 사용 사례를 테스트하지는 않았지만 websocket.org에서 제공하는 JS에서 ws : // localhost에 연결하는 것은 확실히 작동합니다.
답변
“왜?” 부분, 브라우저가 AJAX 호출과는 반대로 WebSockets에 대해 동일한 출처 정책 (CORS는 완화)을 시행하지 않는 이유는 교차 출처 요청의 값이 설정된 후에 WebSocket이 도입 되었기 때문입니다. 처음부터 SOP의 대상이 아니므로 CORS 클라이언트 측 검사에 대한 역사적 이유가 적용되지 않습니다.
AJAX의 경우 포괄적 인 단일 출처 정책 시대에 서버는 인증 된 브라우저가 다른 도메인 1 에서 요청을 보낼 것으로 예상 하지 않았으므로 요청이 신뢰할 수있는 위치 에서 오는지 확인할 필요가 없었습니다 2 . 세션 쿠키. 나중에 CORS와 같은 완화에서는 이 가정을 위반 하여 기존 애플리케이션이 남용 되는 것을 방지하기 위해 클라이언트 측 검사가 필요했습니다 (효과적으로 CSRF 공격 수행 ).
웹이 오늘 발명되고 지금 우리가 알고있는 것을 알고 있다면 AJAX에 SOP 나 CORS가 필요하지 않으며 모든 유효성 검사가 서버에 맡길 수 있습니다.
최신 기술인 WebSocket은 처음부터 도메인 간 시나리오를 지원하도록 설계되었습니다. 서버 로직을 작성하는 사람은 누구나 CORS와 같이 과도한 브라우저 측 예방 조치없이 교차 출처 요청의 가능성을 인식하고 필요한 유효성 검사를 수행해야합니다.
1 이것은 단순화입니다. 리소스 (<img>, <link> 및 <script> 태그 포함)에 대한 교차 출처 GET 요청 및 양식 제출 POST 요청은 항상 웹의 기본 기능으로 허용되었습니다. 요즘에는 요청이 동일한 속성을 갖는 교차 출처 AJAX 호출도 허용되며 단순 출처 간 요청이라고합니다 . 그러나 서버의 CORS 헤더에서 명시 적으로 허용하지 않는 한 코드에서 이러한 요청에서 반환 된 데이터에 액세스하는 것은 허용되지 않습니다. 또한 이러한 “간단한”POST 요청이 서버가 악성 웹 사이트로부터 자신을 보호하기 위해 안티 -CSRF 토큰이 필요한 주된 이유입니다.
2 사실, 요청 소스를 확인하는 안전한 방법은 Referer
헤더가 스푸핑 될 수 있기 때문에 ( 예 : 개방형 리디렉션 취약점 사용) 사용할 수 없었습니다 . 이것은 또한 당시 CSRF 취약점이 얼마나 잘 이해되지 않았는지 보여줍니다.
답변
oberstet이 질문에 대답했습니다 . 감사합니다! 안타깝게도 댓글이기 때문에 “올바른”것으로 표시 할 수 없습니다. 브라우저는 응용 프로그램에서 확인할 수있는 “원본”헤더를 보냅니다.
Java [1] :
@우세하다 public void onOpen (WebSocket clientSocket, ClientHandshake handshake) { 문자열 clientOrigin = handshake.getFieldValue ( "origin"); if (clientOrigin == null ||! clientOrigin.equals (WEBSOCKET_ALLOWED_ORIGIN_HEADER)) { logger.log (Level.WARNING, "클라이언트가 올바른 원본 헤더를 보내지 않았습니다 :"+ clientOrigin); clientSocket.close (); 반환; } // ... }
답변
WebSocket은 도메인 간 통신이 가능하며 SOP (Same Origin Policy)에 의해 제한되지 않습니다.
설명한 것과 동일한 보안 문제가 WebSockets없이 발생할 수 있습니다.
사악한 JS는 다음을 수행 할 수 있습니다.
- evil.tld에 대한 URL이있는 스크립트 / 이미지 태그를 만들고 쿼리 문자열에 데이터를 넣습니다.
- 양식 태그를 작성하고 필드에 데이터를 입력 한 후 양식의 “제출”조치를 호출하여 교차 도메인 일 수있는 HTTP POST를 수행하십시오. AJAX는 SOP에 의해 제한되지만 일반적인 HTTP POST는 그렇지 않습니다. XSRF 웹 보안 문제를 확인하십시오.
페이지에 자바 스크립트가 삽입되거나 악성 자바 스크립트가 발생하면 보안이 이미 손상된 것입니다.