브라우저에서 JavaScript를 해킹하는 것이 얼마나 쉬운가요?


37

내 질문은 JavaScript 보안과 관련이 있습니다.

Backbone 또는 AngularJS 와 같은 JavaScript 프레임 워크를 사용하고 보안 엔드 포인트가 필요한 인증 시스템을 상상해보십시오 . 서버에는 항상 마지막 단어가 있으며 원하는 작업을 수행 할 권한이 있는지 확인하므로 문제가되지 않습니다.

그러나 서버를 사용하지 않고 약간의 보안이 필요한 경우 어떻게해야합니까? 가능합니까?

예를 들어, 클라이언트 측 라우팅 시스템이 있고 로그인 한 사용자를 위해 구체적인 경로를 보호하려고한다고 가정하십시오. 따라서 서버를 핑 (Ping)하여 보호 된 경로를 방문 할 수 있는지 확인하고 계속 진행할 수 있습니다. 문제는 서버를 핑 할 때 응답을 변수에 저장하므로 다음에 개인 경로로 갈 때 이미 로그인했는지 (서버에 핑하지 않음) 확인하고 응답에 따라 갈 것입니다.

사용자가 변수를 수정하고 액세스하는 것이 얼마나 쉬운가요?

내 보안 (및 JavaScript) 지식은 좋지 않습니다. 그러나 변수가 전역 범위에 있지 않고 getter 만 있지만 setter가없는 모듈 패턴의 개인 부분에 있다면 그 경우에도 해킹 할 수 있습니까?


29
이 모든 긴 답변. 요컨대, "매우 해킹 가능"이라는 헤더에 답하십시오. "서버없이, 보안을 잃어 버렸습니다"&& "아니오". 3 번째 대답은 "매우 쉬워요"그리고 마지막으로 "예, 쉬워요"입니다. 당신은 간다. 모든 질문에 답변했습니다. : P
SpYk3HH 2016 년

가장 좋은 예는 웹 페이지에 jQuery를 추가하는 방법에 대한 내 블로그 게시물을 참조하십시오. spyk3lc.blogspot.com/2013/05/… 이제 젊은 padawan은 가서 시도해보십시오. jQuery가없는 사이트에 jQuery를 추가하는 것이 얼마나 쉬운 지 확인한 다음 jquery를 사용하여 긴 자바 스크립트없이 시력의 일부를 매우 쉽게 조작 할 수 있습니다. 팔!
SpYk3HH 2016 년

7
도메인 이름을 등록 할 때 전화 번호는 필수 필드이지만 서버 측이 아닌 Javascript에서만 적용되었습니다. 그래서 나는 기능을 재정 의하여 (Firebug를 사용하여) 비활성화했습니다. 내 전화 번호가 없습니다.
이즈 카타

8
manipulate any part of the sight without long lines 사이트 대 사이트
mplungjan

8
전문 웹 프로그래머는 그러한 일을 올바르게해야합니다. 부디. 그것은 문법 나치 일 :보다 더 당황 plus.google.com/u/0/+MonaNomura/posts/h9ywDhfEYxT
mplungjan

답변:


26

이 내용을 읽기 전에 요아킴의 답변 을 읽으십시오. 그는 클라이언트 측 취약점의 일반적인 원인을 다룹니다. 자,이 문제를 어떻게 해결할 수 있는지 제안하십시오 ...

모든 요청에서 서버와 수동으로 인증하지 않고도 클라이언트와 서버 간 통신을위한 보안 체계 :

당신이있어 여전히 서버가 마지막 말을시키는, 서버는 여전히 클라이언트가 말한다 모든 것을 검증하기 위해이 있지만 투명하게 발생합니다.

MITMA ( Man-in-the-Middle) 공격 을 방지하기 위해 HTTPS 프로토콜을 가정하십시오 .

  • 클라이언트는 처음으로 서버와 핸드 셰이크하고 서버 는 클라이언트 의 공개 키 생성 하고 비대칭 암호화 체계를 사용하여 개인 키 유지합니다. 클라이언트는 서버의 "공개"키를 로컬 저장소에 저장하고 어디에도 저장하지 않은 보안 암호로 암호화합니다.

  • 이제 클라이언트가 오프라인 상태입니다. 클라이언트가 신뢰할 수있는 작업을 수행하려고합니다. 클라이언트는 비밀번호를 입력하고 서버의 공개 키를 가져옵니다.

  • 클라이언트는 이제 해당 데이터에 대한 지식을 기반으로 조치를 수행 하고 클라이언트는 해당 클라이언트에 대한 서버의 공개 키로 수행하는 모든 조치를 암호화합니다 .

  • 클라이언트가 온라인 상태 인 경우 클라이언트는 클라이언트 ID를 보내고 클라이언트가 수행 한 모든 작업은 서버의 공개 키로 암호화 된 서버로 전송됩니다.

  • 서버는 조치를 해독하고 올바른 형식 인 경우 클라이언트에서 시작된 것으로 신뢰합니다.

노트 :

  • 클라이언트의 암호는 어디에도 저장할 수 없습니다. 그렇지 않으면 공격자가 키를 가져 와서 자신의 동작에 서명 할 수 있습니다. 이 체계의 보안은 서버가 클라이언트에 대해 생성 한 키의 무결성에만 의존합니다. 클라이언트는 해당 키를 요청할 때 여전히 서버로 인증해야합니다.

  • 실제로는 여전히 클라이언트가 아닌 보안 을 위해 서버 에 의존하고 있습니다. 클라이언트가 수행하는 모든 작업은 서버에서 확인 해야 합니다.

  • 웹 워커 에서 외부 스크립트를 실행할 수 있습니다 . 명심 모든 JSONP의 당신이 요청은 이제 훨씬 더 큰 보안 문제입니다. 모든 비용으로 키를 보호해야합니다. 일단 분실하면 공격자가 사용자를 가장 할 수 있습니다.

  • 이는 '서버에 핑 없음'이 수행되어야한다는 요구를 충족시킵니다. 공격자는 키를 모르는 경우 위조 된 데이터로 HTTP 요청을 단순히 모방 할 수 없습니다.

  • 요아킴의 대답은 여전히 옳습니다 . 실제로 서버에서 모든 인증 수행하고 있습니다. 여기에 저장 한 유일한 것은 매번 서버에서 비밀번호를 확인해야한다는 것입니다. 커밋하거나 업데이트 된 데이터를 가져 오려면 서버 만 관련하면됩니다. 여기서 우리가 한 일은 클라이언트 측에 신뢰할 수있는 키를 저장하고 클라이언트가이를 다시 확인하도록하는 것입니다.

  • 이는 단일 페이지 응용 프로그램 (예 : AngularJS)에 매우 일반적인 구성표입니다.

  • RSA 와 같은 체계에서 의미하는 바 때문에 서버의 공개 키를 "공개"라고 하지만 실제로는 체계에서 민감한 정보이므로 보호해야합니다.

  • 암호를 메모리의 어느 곳에도 보관하지 않습니다. 오프라인 코드 실행을 시작할 때마다 사용자가 '오프라인'비밀번호를 제출하게합니다.

  • 자체 암호화를 굴리지 마십시오 . 인증을 위해 Stanford와 같은 알려진 라이브러리를 사용하십시오.

  • 이 조언 을있는 그대로 사용하십시오 . 실제 업무상 중요한 응용 프로그램에서 이러한 종류의 인증을 수행하기 전에 보안 전문가에게 문의하십시오 . 이것은 고통스럽고 잘못되기 쉬운 심각한 문제입니다 .

그건 중요한 다른 스크립트가 페이지에 액세스 할 수 없다. 이것은 웹 워커와 함께 외부 스크립트 만 허용한다는 것을 의미합니다. 사용자가 비밀번호를 입력 할 때 인터셉트 할 수있는 다른 외부 스크립트는 신뢰할 수 없습니다.

용도 prompt하지 당신이 완전하게 확실하지 연기 실행을 할 경우 인라인 암호 필드를 (즉, 그것을해야 이벤트에 대한 액세스 권한 만 동기화 코드를 지점으로 살 수 없다). 그리고 실제로 암호를 변수에 저장하지 마십시오. 다시 말하지만 사용자 컴퓨터가 손상되지 않았다는 것을 신뢰하는 경우에만 작동합니다 (서버에 대한 유효성 검사에도 모두 해당됨).

우리는 여전히 클라이언트를 신뢰하지 않는다고 덧붙이고 싶습니다 . 당신 고객을 혼자 믿을 수 없으며 Joachim의 대답이 그것을 생각합니다. 작업을 시작하기 전에 서버를 핑하지 않아도되는 편리함 만 얻었습니다.

관련 자료 :


3
"자신의 암호 화폐를 굴리지 마십시오"는 기본 요소만큼 프로토콜에 적용됩니다. 일반적으로 사람들은 자신 만의 기본 요소를 만들 정도로 어리석지 않지만, 자신이 원하는 프로토콜을 만들 수 있다고 생각하기 때문입니다. . 또한 RSA가 왜 필요한지 모르겠습니다. HTTPS를 사용하고 있기 때문에 16-32 바이트 공유 암호를 생성하여 향후 요청과 함께 전송해야하는 이유는 무엇입니까? 물론, 이렇게하면 문자열에시 불변 등식 검사를 사용해야합니다.
Reid

2
+1 @Reid 예, 최근에이 문제에 대해 어느 정도 전문가와 논의했습니다. 필자는 여기에서 (Rabin IIRC에 의해) 배운 프로토콜을 기반으로 기본 체계를 대략적으로 기반으로했지만 적어도 세부 사항을 찾을 수있을 때까지 (예를 들어이 경우 비대칭 암호화가 필요한 이유를 정당화합니다). 보안 전문가에게 먼저 문의하지 않고이 답변에서 제안 된 체계를 사용하지 마십시오 . 이 접근 방식이 여러 곳에서 사용되는 것을 보았지만 실제로는 거의 아무 의미가 없습니다. 또한 그것을 향상시키기 위해 답변을 편집했습니다.
Benjamin Gruenbaum

프롬프트를 사용하면 보안이 거의 없습니다. 공격자는 암호 window.prompt구문을 가로 채기 위해 메서드를 재정의 하거나 고유 한 프롬프트 (iframe 내에서 가능)를 시작할 수 있습니다. 비밀번호 필드에는 추가 이점이 있습니다. 문자는 표시되지 않습니다.
Rob W

@RobW 물론, 페이지 전체가 손상되면이 전체 계획은 쓸모가 없습니다. 공격자가 페이지에서 JavaScript를 실행할 수있는 권한이 있다면 문제가됩니다. 프롬프트 뒤에 숨어있는 아이디어는 그것이 차단되고 있지만 당신이 옳다는 것입니다. 목록의 마지막 링크를 참조하십시오.
Benjamin Gruenbaum

1
가장 먼저. 멋진 대답, 나는 다른 것을 요청할 수 없다고 생각합니다. 반면에, 나는 나를 위해 애완 동물 프로젝트를하고 싶었습니다 (물론 누가 그것을 사용하고 싶어하는지). 나는 진지한 짓을하고 싶지 않다. 나는 당신이 설명했던 그런 종류의 지식, 지식 부족을 굴릴 수 없다는 것을 두려워한다. 간단한 401 검사를 수행하거나 요청이없는 경우 해당 경로에 액세스 할 때마다 서버를 핑합니다. 인증 토큰도 옵션입니다 (AFAIK에서 설명한 것과 가장 가까운 것). 감사합니다 :)
Jesus Rodriguez

89

간단합니다. 공격자가 클라이언트를 제어 할 때 클라이언트에게 지시 한 대로만 수행하는 보안 메커니즘은 손상 될 수 있습니다.

당신은 할 수 클라이언트에서 보안 검사를 가지고 있지만 효과적으로에 (클라이언트가 이미 대답은 "아니오"입니다 것을 알고하지 않는 경우 서버에 비싼 왕복을 피하기 위해)는 "캐시 '역할을합니다.

일련의 사용자로부터 정보를 유지하려면 해당 사용자의 클라이언트 가 해당 정보를 얻지 않도록하십시오. "비밀 데이터"를 지침과 함께 "하지만 표시하지 마십시오"와 함께 보내면 해당 요청을 확인하는 코드를 비활성화하는 것이 쉽지 않습니다.

보시다시피이 답변에는 실제로 JavaScript / 브라우저 관련 내용이 언급되어 있지 않습니다. 고객이 무엇이든 관계없이이 개념은 동일하기 때문입니다. 뚱뚱한 클라이언트 (전통적인 클라이언트 / 서버 앱), 구식 웹 응용 프로그램 또는 광범위한 클라이언트 측 JavaScript가있는 단일 페이지 응용 프로그램인지는 중요하지 않습니다.

데이터가 서버를 떠나면 공격자가 서버에 완전히 액세스 할 수 있다고 가정해야합니다.


감사합니다. 조금 더 설명 할 수 있다면 사랑 스러울 것입니다. 보안 지식이 그다지 좋지 않으며 내가 이해하는 유일한 부분은 내가 틀렸다는 것입니다 .P. 캐싱에 대해 이야기 할 때 서버가 아니오라고 말할 때만 캐시하는 것입니까? 서버가 한 번 예라고 대답하면 캐시 할 수 없습니다.
Jesus Rodriguez

3
나는 것을 추가하는 것처럼 거라고 이다 특히 :) 디버거, (당신이 언급 한 모듈 패턴처럼) 브라우저에서 액세스 폐쇄 변수 가능
벤자민 Gruenbaum에게

2
@ BenjaminGruenbaum : JS 측에 초점을 맞춘 답변으로 자유롭게 확장하십시오. 여기서는 고급 기술에 대한 개요 만 제공했습니다. JS 자체에 중점을 둔 답변도 좋습니다!
Joachim Sauer 2018 년

1
간단히 말해서, 자바 스크립트 변수에 따라 일부 정보 / 경로 / 액세스 가능한 것이 있으면 해당 변수를 쉽게 변경하여 개인 정보에 액세스 해야하는 것을 말할 수 있기 때문에 안전하지 않습니다.
Jesus Rodriguez

4
@ JoachimSauer 나는 당신이 멋지게 못 박은이 질문의 요점을 놓칠 것이라고 생각합니다. 클라이언트가 취한 보안 조치에 관계없이 통신 을 손상시킬 있습니다. JavaScript로 매우 견고한 인증 시스템을 만들 수 있지만 다른 클라이언트가 진실의 원천으로 취급하는 서버에 통신을 삽입하는 순간에는 아무런 가치가 없습니다. 소스 코드는 모두 클라이언트 측으로 전송되며, 스마트 공격자는이 코드를 읽고 서버에 대한 HTTP 요청을 모방 할 수 있습니다. 서버에서 검증되지 않는 한 클라이언트에서 발생하는 모든 것을 신뢰할 수없는 것으로 처리해야합니다.
Benjamin Gruenbaum

10

게임 커뮤니티에는 " 고객이 적의 손에 달려 있습니다.". 서버와 같은 보안 영역 외부에서 실행되는 모든 코드는 취약합니다. 가장 기본적인 시나리오에서는 처음에는 실행되지 않을 수 있습니다. 실제로"보안 코드 "를 실행하려는 클라이언트의 결정에 따라 사용자가 네이티브 코드를 사용하면 최소한 침입자가 자동으로 난독 처리하고 공격자가이를 조작하기 위해 훌륭한 프로그래머가되어야한다는 추가적인 보호 계층이 있지만 JS는 일반적으로 난독 화되지 않은 일반 텍스트로 제공됩니다. 공격을 준비하려면 프록시 서버 및 텍스트 편집기와 같은 기본 도구 만 있으면되지만 공격자는 프로그래밍과 관련하여 일정 수준의 교육이 필요하지만 실행 파일에 코드를 삽입하는 것보다 텍스트 편집기를 사용하여 스크립트를 수정하는 것이 더 쉽습니다.


집회는 난독 화가 아니며, 다른 방법으로는 전쟁 게임을 한 적이 없다고 생각하는 사람
miniBill

@miniBill : 보통 수준의 경험이있는 공격자는 어셈블 된 코드에 문제가 없지만 매우 기본적인 고역 통과 필터를 제공합니다. (아아, 이것은 스크립트 키디를 제거하는 것이 OP 시나리오의 보안을 최소한으로 향상시키기 때문에 학문적입니다)
Piskvor

1

이것은 자바 스크립트 해킹의 문제가 아닙니다. 앱을 공격하려면 트래픽을 캡처, 수정 및 재생할 수있는 개인 프록시를 사용합니다. 제안 된 보안 체계가 이에 대한 보호 수단이없는 것 같습니다.


0

Angular에 대해 구체적으로 말하면 :

라우트 클라이언트 측을 보호하는 것은 존재하지 않습니다. 해당 경로에 버튼을 '숨겨'도 사용자는 항상 입력 할 수 있지만 Angular는 불평하지만 클라이언트는 그 주위를 코딩 할 수 있습니다.

어떤 시점에서 컨트롤러는 뷰를 렌더링하는 데 필요한 데이터를 서버에 요청해야합니다. 사용자가 해당 데이터에 액세스 할 권한이 없으면 서버 측 에서이 데이터를 보호했기 때문에 데이터를 수신하지 못합니다 , Angular 앱은 401을 적절하게 처리해야합니다.

원시 데이터를 보호하려는 경우 특정 사용자 만 특정 방식으로 만 공통 데이터를 볼 수 있도록하려면 클라이언트 측에서 클라이언트 측으로 전송할 수 없습니다. 원시 데이터를 클라이언트에 전달하고 재구성해야합니다 (성능상의 이유로 이미이 작업을 수행해야 함).

참고 사항 : Angular가 요청하는 뷰 템플릿에는 민감한 민감한 내용이 없어야합니다. 미친 이유가 있다면 서버 측 렌더링을하는 것처럼 서버 측에서 해당 뷰 템플릿을 보호해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.