XSS...?
사이트 간 스크립팅(또는 크로스 사이트 스크립팅, 영문 명칭 cross-site scripting, 영문 약어 XSS)은 웹 애플리케이션에서 많이 나타나는 취약점의 하나로 웹사이트 관리자가 아닌 이가 웹 페이지에 악성 스크립트를 삽입할 수 있는 취약점이다.
Environment
일반적인 사이트에서 공격을 시도하면 안 되기 때문에 간단하게 취약한 게시판을 구현한 후 이를 통해 진행한다.
취약한 게시판은 다음과 같이 스크립트를 포함한 글을 등록한 후
해당 게시판을 확인하면 다음과 같이 스크립트가 작동하도록 구축하였다.
XSS Mitigation
XSS 공격에 대한 보호기법은 CSP, X-XSS-Protection 등 다양한 보호 기법이 존재하지만 PHP를 통해 직접 적용시킨 후 어떠한 변화가 나타나는지 확인하기 위해 다음 두 가지를 적용한다.
Escape
사용자가 입력한 값 중 '<', '>' 와 같은 특수문자가 HTML 태그로 인식하는 것이 아닌 단순한 문자로 인식하기 위해 HTML Entity로 변환하여 스크립트가 작동되지 않도록 적용한다.
htmlentities
htmlentities ( string $string , int $flags = ENT_COMPAT , string|null $encoding = null ,
bool $double_encode = true ) : string
- htmlentities 함수는 모든 문자를 HTML entities 로 변환한다.
- 인자
- string : 변환할 문자열
- flags : 따옴표나 변환할 문서 유형을 설정한다. (기본적으로 ENT_COMPAT | ENT_HTML401 설정되어 있다)
- ENT_COMPAT : 큰 따옴표만 변환한다.
- ENT_QUOTES : 큰, 작은 따옴표 둘 다 변환한다.
- ENT_NOQUOTES : 큰, 작은 따옴표 둘 다 변환하지 않는다.
- encoding : 문자열 변환 시 사용할 인코딩 유형을 설정할 수 있다. (기본적으로 UTF-8로 설정되어 있다)
- double_encode : false로 설정 시 문자열을 html entity로 변환하지 않는다.
- 코드 적용
echo htmlentities($row['title']);
echo htmlentities($row['contents']);
적용 시 다음 그림과 같이 스크립트가 페이지에 삽입되는 것이 아니라 단순한 문자로 보이는 것을 확인할 수 있다.
htmlspecialchars
htmlspecialchars ( string $string , int $flags = ENT_COMPAT ,
string|null $encoding = null , bool $double_encode = true ) : string
- htmlspecialchars 함수는 다음과 같이 특정 문자를 HTML entities 로 변환한다.
- &(ampersand) → &
- "(double quote) → "
- '(single quote) → ' (for ENT_HTML401)
- <(less than) → <
- (greater than) → >
- 인자
- htmlentities와 동일하다.
- 적용
echo htmlspecialchars($row['title']);
echo htmlspecialchars($row['contents']);
적용 시 htmlentities 함수와 같은 모습이 보여지는 것을 확인할 수 있다.
strip_tags
strip_tags ( string $string , array|string|null $allowed_tags = null ) : string
- strip_tags 함수는 문자열에 포함된 HTML, PHP 태그를 제거한다.
- 인자
- string : 태그를 제거할 문자열
- allowed_tags : 제거하지 않을 태그
- 적용
echo strip_tags($row['title']);
echo strip_tags($row['contents']);
적용 시 다음과 같이 'script' 태그만 제거되어 alert`xss` 만 남아있는 것을 확인할 수 있다.
Filtering
사용자가 입력한 값 중 'script', 'alert()', 'onerror=' 와 같이 악의적인 행동을 위해 사용하는 태그, 함수, 이벤트 등을 필터링하여 입력할 수 없도록 적용한다.
str_replace
str_replace ( array|string $search , array|string $replace ,
string|array $subject , int &$count = null ) : string|array
- str_replace 함수는 검색하려는 문자열 모두를 특정 문자열로 교체한다.
- 인자
- search : 변경할 대상인 값
- replace : 검색된 값을 변경할 값
- subject : 대상 문자열
- count : 매칭된 대상을 변경하지 않고 넘어갈 횟수
preg_replace
preg_replace ( string|array $pattern , string|array $replacement ,
string|array $subject , int $limit = -1 , int &$count = null ) : string|array|null
- preg_replace 함수는 정규표현식을 사용하여 문자를 찾아 변경한다.
- 인자
- pattern : 문자 탐색을 위한 정규표현식
- replacement : 검색된 값을 변경할 값
- subject : 대상 문자열
- limit : 패턴에 매칭 할 최대 수. 기본적으로 -1(제한 없음)으로 설정되어 있다.
- count : 매칭된 대상을 변경하지 않고 넘어갈 횟수
- 적용
$contents = str_replace("<\script>", "_", $contents); //<\script> \ 제외
$contents = preg_replace("/onerror\s*=/i", "_", $contents);
적용 후 다음과 같이 대/소문자 둘 다 포함한 글을 적는다면
다음과 같이 str_replace 함수는 대/소문자를 다르게 적용되기 때문에 'SCRIPT'는 필터링되지 않지만 preg_replace 함수는 대/소문자 모두 필터링되는 것을 확인할 수 있다.
Reference
'Tech > web' 카테고리의 다른 글
WSL2에서 Burp Suite의 Proxy 기능 사용 (0) | 2021.04.08 |
---|