발자취

#08 클라이언트 통제 우회 본문

3-1/웹 어플리케이션 보안

#08 클라이언트 통제 우회

해린 2023. 5. 7. 01:57

#01 클라이언트를 통한 데이터 전송
- 많은 애플리케이션들은 클라이언트 (사용자)측에서 데이터를 서버 측에 보낼 수 있도록 구현됨
    - 중요한 데이터를 사용자가 변경할 가능성이 있음
    - 사용자에 의한 데이터 변경을 막기 위해 다음과 같은 방법들이 사용됨
        - 숨겨진 폼 필드
        - HTTP 쿠키
        - URL 파라미터
        - Referer 헤더
        - Qpaque 데이터
        - ASP.NET ViewState
        => 완벽하게 막진 못함 (클라이언트에서 서버로 전송되는 모든 데이터들이 사용자의 완전한 통제 아래에 있기 때문)
 
1. 숨겨진 폼 필드
- HTML 폼
    - 숨기고 싶은 필드는 type을 hidden으로 표기하여 폼에 나타나지 않고 변경될 수 없게 함
- 사용자가 숨겨진 데이터 필드 값 변경하는 방법
    - 사용자 직접 변경
        (1) HTML 페이지의 소스코드를 저장하고 필드 값을 변경함
        (2) 소스코드를 브라우저에 reload 함
        (3) submit 버튼을 클릭함
    - 프록시 (proxy)를 이용해서 변경
        (1) 프록시 (proxy)를 클라이언트와 서버 사이에 위치시킴
        (2) 프록시를 이용해서 클라이언트에서 서버로 전송중인 데이터를 가로채서 (intercept) 필드 값을 변경(modify) 함
        (3) 변경된 데이터를 서버로 재전송(replay) 함
 
 
2. HTTP 쿠키
- 서버가 클라이언트에게 쿠키 발급 -> 클라이언트는 그 발급받은 쿠키를 서버에게 다시 전송하여 내가 맞다는 것을 증명
- HTTP 쿠키는 온라인 상에 나타나지 않으며, 사용자가 직접적으로 그 값을 변경할 수 없음
- HTTP 쿠키는 프록시에 의해서 intercept 되어 변경될 수 있음
- 클라이언트를 경유해서 전송된 데이터를 안전하게 보호해야 함
 
 
3. URL 파라미터
- 사용자가 제품 카탈로그를 browse할 때, 애플리케이션은 URL에 대한 하이퍼링크 제공함
- 사용자는 값을 자신이 원하는 값으로 변경할 수 있음
- 데이터 필드 값이 URL 파라미터 형태로 표기되는 경우, 직접 또는 프록시를 이용해서 필드 값을 변경할 수 있음
 
 
4. Referer 헤더
- Referer 헤더는 현재 요청을 시작한 웹 페이지의 URL 정보를 갖고 있음
- 예: 패스워드 재설정
        - 패스워드를 잃어버린 경우, 패스워드를 재설정하기 위해 요청을 서버 애플리케이션에 보냄
        - 애플리케이션은 Referer 헤더를 이용해서 해당 요청이 올바른 단계에서 시작된 경우에만, 패스워드 재설정을 허용함
        -> 같은 Referer 헤더를 갖는 악의적인 URL을 중간에 끼워넣으면 사용자는 알아채지 못함
 
 
5. Opaque 데이터 (암호화하거나 난독화된 데이터)
- 서버는 암호화하거나 난독화된 데이터를 사용자에게 보냄으로써, 사용자가 해당 데이터를 변경하기 힘들게 만듦
- 예제: 값 필드가 opaque 데이터 형태로 표현된 경우 -> 난독화를 풀거나 복호화하지 못하면 공격 성공하기 어려움
- 다만, Known-plaintext 공격, chosen-plaintext 공격에 취약함 (암호 자체의 알고리즘의 취약점임. 안전한 알고리즘 선택하면 피해가 적을 것)
 
 
6. ASP.NET ViewState (모든 ASP.NET 웹 애플리케이션에서 기본적으로 생성되는 숨겨진(hidden) 데이터 필드)
- 현재 웹 페이지의 상태와 관련된 정보를 갖고 있음
- 상태 관련 정보가 서버에 저장,관리되지 않고 사용자 인터페이스 내에서 관리, 보존될 수 있도록 만듦
- ViewState가 누구나 디코드할 수 있는 인코드 방식을 사용하면 문제가 됨
    - EnableViewStateMac 옵션이 사용하면 ViewState내의 데이터 값을 임의로 변경하는 것이 쉽지 않음
      (서버만이 보유하고 있는 비밀키로 MAC을 생성할 수 있음)
 
 
7. HTML 폼
- 사용자로부터 입력 값을 받고 서버에 제출하는데 있어서 가장 단순하고 공통적인 메커니즘
- 사용자가 제공한 데이터에 대해 유효성 검사를 수행하거나 제한을 두는 목적으로 폼을 이용할 수 있음
    - 길이 제한
    - 스크립트 기반의 유효성 검사
    - 불능화된 요소
 
7-1. 길이 제한
- 회피: 
    - 프록시를 통해서 form 에 임의의 값을 입력할 수 있도록 요청을 수정함
    - 프록시를 통해서 form에서 maxlength 속성이 제거될 수 있도록 응답을 수정함
 
7-2. 스크립트 기반의 유효성 검사
- 입력 유효성 검사를 클라이언트 측 스크립트를 통해서 함 (자바스크립트를 통해 폼 자체를 검사할 수 있음)
    - onsubmit 속성
        - 사용자가 submit 버튼을 클릭 할 때, 브라우저는 ValidateForm 함수를 수행함
        - ValidateForm 함수가 true를 return 할 때, 실제로 form을 제출함
 
- 회피:
    - 브라우저 안에서 자바 스크립트를 불능화 (disable)함
        - 그러나 문제는, 애플리케이션이 클라이언트 측 스크립트에 의존하는 경우에, 애플리케이션이 정상적으로 동작 하지 못하는 문제가 발생할 수 있음
        - 그래서 다른 방법을 쓰자면, 입력 필드에 정상적인 값을 입력하고 프록시 기능을 이용해서 정상적인 입력 값을 변경함
 
7-3. 불능화(disable) 된 요소
- HTML 폼 상에 있는 요소가 disabled으로 표기되면,
    - 불능화된 요소는 스크린상에는 나타나지만 정상적인 방식으로 수정되거나 사용될 수 없음
    - 폼이 제출 될 때, 불능화된 요소는 서버에 전송되지 않음
 
 
8. 클라이언트 측 데이터 안전하게 다루기
- 중요한 데이터를 서버에서 관리하고 필요할 때 서버에서 직접적으로 액세스함
- 서버에서 관리하기 힘든 경우에, 서버는 데이터를 암호화하거나 서명을 첨부해서 클라이언트에게 전송함
    - replay 공격에 취약함
    - 사용자가 암호화된 데이터의 plaintext를 알거나 제어할 수 있으면 암호관련 공격이 발생할 수 있음