그누보드 보안성능 개선 - get_params_merge_url($params) 수정 > 그누보드5 팁자료실

그누보드5 팁자료실

그누보드 보안성능 개선 - get_params_merge_url($params) 수정 정보

그누보드 보안성능 개선 - get_params_merge_url($params) 수정

본문

그누보드소스에는 루트폴더/lib/common.lib.php 가 있습니다.
여기서 정의 한 get_params_merge_url() 함수가 자주 호출됩니다.
대표적으로 get_params_merge_url()함수는 모든 홈페이지들의 아랫단에 있는 [PC버전] 또는 [모바일버전] 메뉴 링크를 사용자가 어떤 URL을 호출하든 전체 URL의 맨뒤에 항상 device=mobile 또는 device=pc 쿼리를 덧붙여주는 기능을 수행합니다.
그런데 그 함수정의부분을 보면 
if($_SERVER['QUERY_STRING']) {
        foreach($_GET as $key=>$val) {
            $key = strip_tags($key);
            $val = strip_tags($val);

            if($key && $val)
                $q[$key] = $val;
        }
    }

와 같은 로직이 있습니다.

이제 취약점분석을 위해 다음과 같이 쿼리를 실행합시다.
http://localhost/?view[]=v

 

이렇게 하면 홈페이지 맨 밑단에 [PC버전] 또는 [모바일버전] 메뉴대신에 에러구문이 출력됩니다.
( ! ) Warning: strip_tags() expects parameter 1 to be string, array given in D:\workspace\www\eshop\lib\common.lib.php on line 3440 Call Stack #TimeMemoryFunctionLocation 10.2014404056{main}( )...\index.php:0 20.25371650696require_once( 'D:\workspace\www\eshop\theme\basic\index.php' )...\index.php:8 30.45651873832include_once( 'D:\workspace\www\eshop\theme\basic\tail.php' )...\index.php:67 40.46321880040get_device_change_url( )...\tail.php:30 50.46321880312get_params_merge_url( )...\common.lib.php:3470 60.46321881032
strip_tags
( )...\common.lib.php:3440 http://localhost/eshop/?device=mobile">모바일버전

물론 실 홈페이지를 운영할때에는 구문오류 같은게 출력되지 않게 환경설정 해놓았을것입니다.

단 get_params_merge_url()함수는 사실상 사용자가 요청한 URL의 뒤에 내부파라미터로 넘어오는 $params를 URL구문에 맞추어 덧붙여주는 기능만을 수행할뿐입니다.
때문에 위에서처럼 사용자의 악의적이든 어떻게든 임의의 모든 요청에 대하여 늘 get_params_merge_url()함수가 정상작동하도록 하는것이 필수이라고 봅니다.
완벽한 get_params_merge_url()함수의 기능을 구현하면서도 간단히 로직을 구성한 새 get_params_merge_url()함수를 공개합니다.

function get_params_merge_url($params){
    $href = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    $add = http_build_query($params, '', '&');
    if($_SERVER['QUERY_STRING']) {
        $href .= '&'.$add;
    } else {
        $href .= '?'.$add;
    }
    return $href;
}

또는 아래처럼 로직을 구현해도 됩니다.
function get_params_merge_url($params){
    $href = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://" . $_SERVER['HTTP_HOST'];
    if( $tmp = explode('?', $_SERVER['REQUEST_URI']) ){
        if( isset($tmp[0]) && $tmp[0] )
            $href .= $tmp[0];
    }
    $query = array_merge($_GET, $params);
    $add = http_build_query($query, '', '&');
    $href .= '?'.$add;
    return $href;
}


원래 로직이 28줄 짜리 코드였다면 새 로직은 단 10줄미만으로 축소되었고 임의의 사용자요청에 잘 대응하여 자기 기능을 수행합니다.

[별첨]
사실상 $_SERVER['REQUEST_URI']에는 이미 요청URL이 인코드되어 있기때문에 <, >기호 역시 인코드된 문자열로 반영됩니다. http_build_query()함수 역시 인코딩하여 돌려줍니다.
설령 http://localhost/eshop/?a='<script>alert(1)</script>' URL을 요청했다고 가정하면
$_SERVER['REQUEST_URI'] 값은 a=%5C%27%3Cscript%3Ealert(1)%21%3C%2Fscript%3E%5C%27로 문자열 인코딩되어집니다.

그누보드에 소스들을 보면 strip_tags를 자주 사용하고 있는데 이것은 사실상 XSS공격에는 취약한 함수입니다.
위의 예를 보아도 몇가지 특수문자열을 쿼리에 삽입해도 홈페이지는 오류를 출력하는데 운영중의 홈페이지에 아름답지 못한 결과를 접속자들에게 내보내는것은 좋지 않다고 봅니다.
유저 요청을 받고 최종 결과를 유저에게 되돌려줄때 그 결과에 xss취약점 대응하는 함수 적용하고 중간로직에서는 원래의 요청데이터 그대로 유지하는것이 더 나은 방법인듯 합니다.
get_params_merge_url()함수를 예를 든다면
이 함수는 중간 로직을 담당하고 실지 말단에 최종결과물을 되돌려주는 함수는 get_params_merge_url()함수를 호출한 get_device_change_url()함수입니다.
때문에 get_params_merge_url()함수에서는 요청데이터의 원본을 그대로 유지하면서 자기 기능을 실행하게 하고, 최종 결과를 말단에 출력해주는 get_device_change_url()함수에서는 
return htmlspecialchars(get_params_merge_url($q));

로 출력해주면 그 어떤 요청에 대해서도 항시 오류 발생 없이 원만히 수행할것입니다.
때문에 앞으로 그누보드 버전 업그레이드할때에는 이런 측면 많이 참고해주시길 바랍니다.

그누보드 운영하시는 분들께 도움이 되길 희망합니다!!!

추천
10

댓글 2개

전체 2,427 |RSS
그누보드5 팁자료실 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT