SQL Injection 에 대한 조치를 진행해본다. 

 

예를 들면 검색 기능을 구현한다고 보면 간단하게 아래와 같은 쿼리를 작성하게 된다. 

SELECT * FROM MYTABLE WHERE NAME LIKE '% ?'; 

 

만약 악의적인 사용자가 파라메터값으로 " '; SHOW DATABASES; -- " 이런 구문을 입력해 온다면 

SELECT * FROM MYTABLE WHERE NAME LIKE '%'; SHOW DATABASE; -- '; 

나의 쿼리 문은 종료되고, 뒤엔 데이터베이스를 출력할 수 있는 쿼리가 실행되게 된다. 

만약 공격자가 테이블을 조회하는 쿼리를 넣었다면 테이블명까지 노출되고 

심할경우 drop을 통해 테이블이 삭제되는 경우에 이를 수 있다. 

이렇게 입력값을 이용해 내 쿼리를 조회를 방해하고, 악의적으로 데이터를 갈취할수 있는데 

이에 방어하기 위한 조치를 진행해본다. 

 

1. Codeigniter 에서 제공하는 xss_clean 사용! 

xss_clean크로스 사이트 스크립팅 공격을 방지하는 XSS 필터는 자바스크립트실행을 시도한다거나, 쿠키를 하이재킹한다거나, 다른 해괴망측한 짓거리들을 한다거나 하는 것을 막는 기술입니다. 만약 금지된 문자나 코드 등을 찾으면 데이터를 안전한 HTML 엔터티로 변환하여 표시합니다.

컨트롤러에서 검색값을 받을때 아래와 같이 필터링해준다. 

$search["keyword"] = $this->security->xss_clean(@trim($search["keyword"]));

 

2. 정규식을 이용한 문자열 치환 

파라메터값에서 쿼리 조회에 문제가 되는 텍스트가 있다면 "" 으로 변경해준다. 

$string = @trim(preg_replace("/[#\&\+\-%@=\/\\\:;,\.'\"\^`~\_|\!\?\*$#<>()\[\]\{\}]/i", "", $string));

 

3. 한번 더 문자열 치환! 

이건 경우에 따라 다를 것 같다.  나같은 경우 들어올 사용자 이름 조회에 사용하고있으므로

파라메터에 select 와 같은 문구가 들어올 경우가 적기에 이 또한 "" 처리했는데, 

케바케로 용도에 맞게 사용해야할것같다. (str_ireplace = 이건 대소문자 구분없이 문자열 변경해준다. ) 

//iframe 제거 
$string = preg_replace("!<iframe(.*?)<\/iframe>!is","",$string);

//script 제거 
$string = preg_replace("!<script(.*?)<\/script>!is","",$string);

//meta 제거 
$string = preg_replace("!<meta(.*?)>!is","",$string); 

//style 태그 제거  
$string = preg_replace("!<style(.*?)<\/style>!is","",$string); 

// 기타 쿼리 조회에 사용되는 문구 제거 
$string = @trim(str_ireplace("select", "", $string));
$string = @trim(str_ireplace("union", "", $string));
$string = @trim(str_ireplace("insert", "", $string));
$string = @trim(str_ireplace("update", "", $string));
$string = @trim(str_ireplace("delete", "", $string));
$string = @trim(str_ireplace("drop", "", $string));
$string = @trim(str_ireplace("from", "", $string));

 

4. 한번 더 걸러준다.. ( 절대 안되게 할꺼야! )ㅋㅋ

날짜와 같이 스크립트로 값을 입력해 가져오는 파라메터들에 방심하는 경우가 있다. 

공격툴을 이용하면 파라메터 값을 마음대로 셋팅할 수 있으므로,  입력받는 파라메터라면 모두 처리해주어야한다. 

$search["keyword"] = addslashes($search["keyword"]);
$search["sdate"] = addslashes($search["sdate"]);
$search["edate"] = addslashes($search["edate"]);

 

 

쿼리 실행 코드 뒤에 아래 코드를 입력하면 화면에 

찍힌다~!! 

$last_query = $this->db->last_query();
echo $last_query;

 

'PHP' 카테고리의 다른 글

Codeigniter Hooks 사용방법!  (0) 2021.01.28

 

uri로 영문, 국문 페이지를 구분하는 사이트를 운영하게 되었다.. 

(controller 자체가 국문용, 영문용 따로 생성되어있는.. )

이렇게 되어있다보니 요청한 url에 따라 영/국문 페이지는 잘 나오지만

페이지내 locale 설정값을 통해 나오는 문자와 이미지가 제대로 나오지 않는 이슈가 있었다~ 

예) 로케일이 국문으로 되어있는데 영문 url를 치고 들어오면 국문용 이미지가 출력됨.. ;; 

애초에 로케일 값만 가지고 구축했으면 좋았겠지만 안되어있으니 아쉬운대로 나는 작업을 이어간다.

예전엔 이런걸 보면 왜이렇게 해두는거지??? 했지만 이젠 다 사정이 있겠거니 하는 마음이 든다..ㅎㅎ; 왜지? 

 

무튼 

hook으로 controller 들어가기 전에 uri 값을 읽어와서 locale 설정을 변경해주는 방향으로 작업하려고 한다. 

 

시작! 

1. application/config/config.php 에 들어가서 아래값을 true로 설정한다. hooks 활성화 해주는거~ 

$config['enable_hooks'] = true;

 

2. application/config/hooks.php 사용할 hooks 선언을 해준다. 

$hook['post_controller_constructor'] = array(
	'class'    => 'Locale_init', // 클래스명, 그냥 파일명이라고 생각해도 될듯 
	'function' => 'inits', // 그안에 내가 쓸 함수명 
	'filename' => 'Locale_init.php', // 실제 파일명 
	'filepath' => 'hooks' // 저장된 경로이니 특별하지 않다면 그냥 두기 
);

$hook[''] 에 들어가는 값은 여러가지 타입이 있는데 내 사용용도에 맞게 적어주면 된다. 

나는 컨트롤러가 인스턴스화 된 직후 진행하려고 post_controller_constructor로 설정했다.

pre_system 
 - 시스템 작동초기입니다.벤치마크와 후킹클래스들만 로드된 상태로서, 라우팅을 비롯한 어떤 다른 프로세스도 진행되지않은 상태.
pre_controller 
- 컨트롤러가 호출되기 직전. 모든 기반클래스(base classes), 라우팅 그리고 보안점검이 완료된 상태.
post_controller_constructor 
 - 컨트롤러가 인스턴스화 된 직후. 사용준비가 완료된 상태. 하지만, 인스턴스화 된 후 메소드들이 호출되기 직전.
post_controller
-  컨트롤러가 완전히 수행된 직후.
display_override
-  _display() 함수를 재정의. 최종적으로 브라우저에 페이지를 전송할 때 사용됩니다. 이로서 당신만의 표시 방법( display methodology)을사용할 수 있음. 
   주의 : CI 부모객체(superobject)를 $this->CI =& get_instance() 로 호출하여 사용한 후에 최종데이터 작성은 $this->CI->output->get_output() 함수를 호출하여 할 수 있음

cache_override 
- 출력라이브러리(Output Library) 에 있는 _display_cache() 함수 대신 당신의 스크립트를 호출할 수 있도록 해줌. 
  이로서 당신만의 캐시 표시 메커니즘(cache display mechanism)을 적용할 수 있음
post_system 
- 최종 렌더링 페이지가 브라우저로 보내진후에 호출

 

3. application/config/configLocale_init.php

파일을 생성하고 원하는 작업을 코딩한다. 

<?php
defined('BASEPATH') OR exit('No direct script access allowed');


class Locale_init  {
    private $CI;
 
    function __construct()
    {
        $this->CI =& get_instance();
 
        if(!isset($this->CI->session)){  //Check if session lib is loaded or not
              $this->CI->load->library('session');  //If not loaded, then load it here
        }
    }
 
 
    public function inits(){
     
        $CI =& get_instance();
        $CI->load->library('session');   
        $uri= $_SERVER['REQUEST_URI']; //uri를 구합니다.
	
		
		$pieces = explode('/', $uri);
		
		if(isset( $pieces ) && count($pieces) > 1) { 
			$this->CI->session->set_userdata("__ss_lan", $pieces[1] );
			$lan = $this->CI->session->userdata("__ss_lan");
		}
		
    }
}

 

 

이제 실행해보면 잘된당~~ 

 

* 저는 php 개발자는 아니지만.. 임시적으로 운영중이니 코드에 이슈가 있다면 코멘트 남겨주세요! 

배우는 것을 좋아합니다~~~!! 

 

'PHP' 카테고리의 다른 글

PHP Codeigniter 쿼리 찍어보기  (0) 2021.02.22

main.php

<script>
function set_lan(obj) {
		$.ajax({
			type: "POST",
			url: "/main/set_lan",
			data: {"lan":obj.value},
			success:function(r) {
				window.location.reload();
			},
			error:function(r) {
				//alert(r.status);
			},
			dataType: "json"
		});
	}
<script>


<div class="lang_box">
  <select class="sel_lang" onchange="set_lan(this)">
    <option value="ko" <?php if( $_SESSION["lan"] == "ko" ) echo "selected=selected"; ?>>한국어</option>
    <option value="en" <?php if( $_SESSION["lan"] == "en" ) echo "selected=selected"; ?>>ENGLISH</option>
  </select>
</div>

 

Controller

public function set_lan() {
	$lang = $this->input->post("lan", false);

	if( @trim($lang) == "" ) {
		$lang = "ko";
  	}

	$this->session->set_userdata("lan", $lang );


	$r = array();
	$r["result"] = "OK";
	$r["message"] = "언어 변경 완료!.";

	echo json_encode($r);
	exit;
}

 

기본적으로 Apache와 PHP가 설치된 상황에서 확인 가능하다~!! 

 

압축파일을 열어보면 index.php 페이지가 있다. 

이페이지에서 캡차가 실행된다. 

 

 

simple-php-captcha.php 로직을 쓱 보니 

배경이미지를 가져와 난수로 생성된 코드값을 합쳐 이미지를 하나 생성한다. 

 

생성된 이미지를 사용자에게 보여주고 

사용자가 입력한 값과 출력되고있는 난수값이 일치하는 경우! 

일치!! 라는 메세지를 출력하도록 구현되어있다. 

 

로그인을 시도하거나 휴대폰 번호를 통해 SMS가 무작위로 발송되는 경우를 막기 위해 

사용하면 좋겠다. 

 

test.zip
0.41MB

 

+ Recent posts