파일 업로드시 php 나 html 등 위험한 파일은 보통 제한하게 됩니다. 그래서 다양한 방법으로 허용가능 파일인지 체크 스크립트를 작성해 주는데, 문제는 잘못된 방법으로 개발자도 모르는 우회하여 파일을 업로드 됩니다. 예를 들어 다음과 같을 것입니다.

<?php 
 $filename = "test.php.";
 $ext = array_pop(explode(".", strtolower($filename)));

 if(preg_match("/php|php3|php4|htm|inc|html/", $ext)){
   echo "죄송합니다. php, html 파일은 업로드가 제한됩니다.";
 }
 ?>

아무 문제 없어 보이지만, 실은 php. 나 htm. gif. 등 모두 실행 가능한 파일 임을 알아 둘 필요가 있습니다. 그러므로 다음 같이 한 번더 체크해서 공격자가 우회하지 못하게 해주는 게 좋습니다.
<?php 
 $filename = "test.gif.bmp.php.";
 $ext = explode(".", strtolower($filename));

 $cnt = count($ext)-1;
 if($ext[$cnt] === ""){
   if(preg_match("/php|php3|php4|htm|inc|html/", $ext[$cnt-1])){
     echo "죄송합니다. php, html 파일은 업로드가 제한됩니다.";
   }
 } else if(preg_match("/php|php3|php4|htm|inc|html/", $ext[$cnt])){
   echo "죄송합니다. php, html 파일은 업로드가 제한됩니다.";
 }
 ?>

파일길이 255자 이상이면 다른 의도를 가진 파일이라고 생각해야 됩니다.
<?php
/*
*************************   확장자 추출   *************************
 파일: test.php.gif                  -> gif
 파일: test . bmp.  .                -> bmp
 파일: test.php . jpg-.              -> jpg-
 파일: test....bmp....   .. .     .. -> bmp
*/
function extExtract($filename)
{
  if(strlen($filename) > 255)
  {
    return false;
  }

  $basename = trim(basename($filename));
  $resource = explode(".", $basename);
  $i = count($resource)-1;
  $resource[$i] = trim($resource[$i]);

  if($resource[$i] === "")
  {
    while($i > 0)
    {
      $i--;
      $resource[$i] = trim($resource[$i]);
      if(!empty($resource[$i]))
      {
        return strtolower($resource[$i]);
      }
    }
    return false;
  }
  elseif(!empty($resource[$i]))
  {
    return strtolower($resource[$i]);
  }
  else
  {
    return false;
  }
}
?>

0 댓글