zeroboardXE CSRF (Cross-site request forgery) 보안 취약점

관련링크 : http://www.zeroboard.com/17234648

수정파일 : config/func.inc.php

removeHackTabk(), removeJsEvent(), removeSrcHack() 함수

func.inc.php파일을 수정해 사용했다면 아래 코드를 참고하세요.

 
 /**
     * @brief iframe, script코드 제거
     **/
    
function removeHackTag($content) {
        
// iframe 제거
        
$content preg_replace("!<iframe(.*?)</iframe>!is"''$content);

        
// script code 제거
        
$content preg_replace("!<script(.*?)</script>!is"''$content);

        
// meta 태그 제거
        
$content preg_replace("!<meta(.*?)>!is"''$content);

        
// style 태그 제거
        
$content preg_replace("!<style(.*?)</style>!is"''$content);

        
// XSS 사용을 위한 이벤트 제거
        
$content preg_replace_callback("!<([a-z]+)(.*?)>!is"removeJSEvent$content);

        
/**
         * 이미지나 동영상등의 태그에서 src에 관리자 세션을 악용하는 코드를 제거
         * - 취약점 제보 : 김상원님
         **/
        
$content preg_replace_callback("!<([a-z]+)(.*?)>!is"removeSrcHack$content);

        return 
$content;
    }

    function 
removeJSEvent($matches) {
        
$tag strtolower($matches[1]);
        if(
preg_match('/(src|href)=("|'?)javascript:/i',$matches[2])) $matches[0] = preg_replace('/(src|href)=("|'?)javascript:/i','$1=$2_javascript:'$matches[0]);
        return 
preg_replace('/ on([a-z]+)=/i',' _on$1=',$matches[0]);
    }

    function 
removeSrcHack($matches) {
        
$tag strtolower(trim($matches[1]));

        
$buff trim(preg_replace('/(/>|>)/','/>',$matches[0]));
        
$buff preg_replace_callback('/([^=^"^ ]*)=([^ ^>]*)/i'fixQuotation$buff);

        
$oXmlParser = new XmlParser();
        
$xml_doc $oXmlParser->parse($buff);

        
// src값에 module=admin이라는 값이 입력되어 있으면 이 값을 무효화 시킴
        
$src $xml_doc->{$tag}->attrs->src;
        
$dynsrc $xml_doc->{$tag}->attrs->dynsrc;
        if(
_isHackedSrc($src) || _isHackedSrc($dynsrc) ) return sprintf("<%s>",$tag);

        return 
$matches[0];
    }

    function 
_isHackedSrc($src) {
        if(!
$src) return false;
        if(
$src && preg_match('/javascript:/i',$src)) return true;
        if(
$src) {
            
$url_info parse_url($src);
            
$query $url_info['query'];
            
$queries explode('&'$query);
            
$cnt count($queries);
            for(
$i=0;$i<$cnt;$i++) {
                
$pos strpos($queries[$i],'=');
                if(
$pos === false) continue;
                
$key strtolower(trim(substr($queries[$i], 0$pos)));
                
$val strtolower(trim(substr($queries[$i] ,$pos+1)));
                if((
$key == 'module' && $val == 'admin') || $key == 'act' && preg_match('/admin/i',$val)) return true;
            }
        }
        return 
false;
    }


+ Recent posts