WebSocket에 대한 동일 출처 정책이없는 이유는 무엇입니까? ws : // localhost에 연결할 수있는 이유는 무엇입니까?


84

내 응용 프로그램의 프로세스 간 통신에 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에 연결하는 것은 확실히 작동합니다.


2
websocket.org는 나쁘지 않아야합니다. 웹 소켓은 될 수 있습니다;)
kuldeep.kamboj

답변:


51

"왜?" 부분, 브라우저가 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 취약점이 얼마나 잘 이해되지 않았는지 보여줍니다.


6
이것은 실제로 질문에 대한 답변이므로 +1. 그러나 기록을 위해 나는 이러한 추론에 강력히 동의하지 않습니다. 이 디자인 결정의 결과로 WebSockets를 사용하는 상당수의 사이트가 Origin헤더 유효성 검사에 실패 하고 결과적으로 개인 사용자 데이터가 타사 사이트로 유출 될 것으로 예상 합니다. Access-Control-Allow-Origin웹의 다른 교차 출처 HTTP 요청에 대한 응답에 대한 JS 액세스를 허용하기 전에 수행하는 것처럼 헤더를 확인하는 클라이언트 는 이러한 전체 공격 클래스 (Cross-Site WebSocket Hijacking)를 방지하는 간단한 방법이었을 것입니다. 지금은 너무 늦었어요.
Ajedi32

3
동의하는 경향이 있습니다. 디자인 변경은 본질적으로 화이트리스트 기반 접근 방식에서 블랙리스트 접근 방식으로 옮겨 가고 있습니다. 이는 위험합니다. 공정한 포인트.
staafl

42

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 ();
        반환;
    }

    // ...
}

[1] https://github.com/TooTallNate/Java-WebSocket 사용


OWASP는 CSRF 치트 시트 에서 Origin (그리고 잠재적으로 Referer) 헤더를 확인하는 것을 첫 번째이자 가장 중요한 단계 라고 언급 하지만, 한 단계 더 나아가 CSRF 특정 방어를 구현할 것을 권장합니다. WebSocket의 경우 XSRF 위조 방지 토큰을 쿼리 매개 변수로 WS URI에 추가하고 원본 확인 후 서버 측에서 유효성을 검사 할 수 있습니다.
Kevin Secrist

18

WebSocket은 도메인 간 통신이 가능하며 SOP (Same Origin Policy)에 의해 제한되지 않습니다.

설명한 것과 동일한 보안 문제가 WebSockets없이 발생할 수 있습니다.

사악한 JS는 다음을 수행 할 수 있습니다.

  • evil.tld에 대한 URL이있는 스크립트 / 이미지 태그를 만들고 쿼리 문자열에 데이터를 넣습니다.
  • 양식 태그를 작성하고 필드에 데이터를 입력 한 후 양식의 "제출"조치를 호출하여 교차 도메인 일 수있는 HTTP POST를 수행하십시오. AJAX는 SOP에 의해 제한되지만 일반적인 HTTP POST는 그렇지 않습니다. XSRF 웹 보안 문제를 확인하십시오.

페이지에 자바 스크립트가 삽입되거나 악성 자바 스크립트가 발생하면 보안이 이미 손상된 것입니다.


1
나는 사악한 JS에 대해 걱정하지 않습니다. 나는 이것이 항상 가능하다는 것을 알고 있습니다. 제가 정말로 걱정하는 것은 브라우저 브레이크 아웃입니다. 이제 모든 웹 사이트가 로컬로 바인딩 된 WS 소켓과 통신하고 거기에서 데이터를 훔칠 수 있습니다.
binwiederhier

53
SOP / CORS는 WebSocket에 적용되지 않지만 브라우저는 originWebSocket 연결을 연 JS로 HTML을 제공 한 서버의 호스트 이름이 포함 된 헤더를 보냅니다 . WebSocket 서버는 origin.
oberstet 2014 년

이것은 질문에 대한 답이 아닙니다. 문제는 다른 도메인웹 페이지 가 로컬 WebSocket에 액세스 할 수있는 이유였습니다 . OP 시나리오에는 "페이지에 자바 스크립트를 삽입"하는 것이 없습니다. 이는 다른 시나리오입니다. WebSocket이 없으면 원격 웹 페이지가 localhost의 리소스를 읽을 수 없습니다. 이것이 바로 SOP가 방지하는 것이기 때문입니다.
sleske
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.