Codeigniter

 

1.   helper 에서 form 로드와  , 라이브러이에서  form_validation 로드 는 필수입니다.

 

 $this->load->helper('form');

 $this->load->library('form_validation');

 

2. CSRF 보안을 위해 cofing 폴더 에서 config/config.php  csrf_protection TRUE 로 합니다.

$config['csrf_protection'] = TRUE;
$config['csrf_protection']=FALSE;
$config['csrf_token_name'] = 'csrf_test_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;

 

이때 CSRT 보안을 위해 ajax 처리시 필요한것이 쿠키값 입니다. 이것은 다음과 같은 자바스크립트 코드를 사용해서 처리합니다.

function getCookie( name )
{
    var nameOfCookie = name + "=";
        var x = 0;
 
        while ( x <= document.cookie.length )
        {
            var y = (x+nameOfCookie.length);
 
            if ( document.cookie.substring( x, y ) == nameOfCookie ) {
                if ( (endOfCookie=document.cookie.indexOf( ";", y )) == -1 )
                    endOfCookie = document.cookie.length;
 
                return unescape( document.cookie.substring( y, endOfCookie ) );
            }
 
            x = document.cookie.indexOf( " ", x ) + 1;
 
            if ( x == 0 )
 
            break;
        }
 
        return "";
}

 

3.  컨트롤에서 다음과  같은 코드 처리를 해서 보안을 위해 ajax 형식이 아니면 차단 합니다.

 if(!$this->input->is_ajax_request()){echo "bad req" ;};

 

4. form_validation  처리에서 규칙 참조는 

규칙 참조 Rule Reference 링크 주소에서 확인합니다.

http://www.ciboard.co.kr/user_guide/kr/libraries/form_validation.html#rule-reference

 

 

5. ajax 처리시  $this->form_validation->set_rules("nickname", "required|min_length[2]|max_length[10]");

이와같은 처리방법이 아니라 다음과 같은 처리 방식을 해야 합니다.

           $RULES=array(
                array(
                    'field'=>'nickname',
                    'label'=>'닉네임',
                    'rules' =>'required|min_length[2]|max_length[10]'     
                )
            );
     
            $this->form_validation->set_rules($RULES);

 

자세한 규칙 설정은 링크 주소를 참조 하세요.

http://www.ciboard.co.kr/user_guide/kr/libraries/form_validation.html#associating-a-controller-method-with-a-rule-group

 

6. 컨트롤에서 form_validation 성공시와 실패시 처리 방법은 다음과 같이 하면 됩니다.

if($this->form_validation->run()){
                $nickname=$this->input->post("nickname", TRUE);
                
                echo "success"; 
               return;
  }else{
  
              echo validation_errors();
               return ;
   }

 

7,  SQL 삽입 공격 방어 및 XSS 방어의 보안 처리로 다음과 같은 코드로 작성하는 것이 좋다고 생각 합니다.

TRUE 방어

$nickname=$this->input->post("nickname", TRUE);

 

그럼 1~ 7을 참조해서  macaroncis 의 제 개발 사이트에서 ajax로 닉네임 변경한코드를 보여드리겠습니다.

 

컨트롤러 

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class User_setting extends  MY_Controller{

         ~ 생략

 function nicknamechange()
    {
       ~ form helper 에서 form 로드 인덱스에서 생성 해서 생략 

       $this->load->library('form_validation');    
       if(!$this->input->is_ajax_request()){echo "bad req" ;}; //해커 - 보안 ajax 형식이 아니면 아웃
       if(@$this->session->userdata('logged_in')==TRUE OR @$this->session->userdata("auth_code") ==15){ //로그인한 유저만
     
           $RULES=array(
                array(
                    'field'=>'nickname',
                    'label'=>'닉네임',
                    'rules' =>'required|min_length[2]|max_length[10]'     
                )
            );
     
            $this->form_validation->set_rules($RULES);
            
            if($this->form_validation->run()){
                $nickname=$this->input->post("nickname", TRUE);
                
                echo "success"; 
            }else{
                echo validation_errors();
                return ;
            }
          
       }else{
            alert("로그인을 먼저 하세요!", '/index.php/auth');
            exit;
       }
    }
    

 

뷰 입니다.

 

<div class="modal fade" id="nickModal">
<div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title">닉네임 변경</h4>
      </div>
      <div class="modal-body">
     <?php 
        $attrs=array("id" =>"nickname_form");
        echo form_open("/index.php/user/user_setting/nicknamechange", $attrs);
     ?>
      <div class="modal-body">
        <p><input type="text" name="nickname" id="nickname" value="<?php echo $info->nickname; ?>" class="form-control" ></p>
        <p id="errorMessage" style="color:red"></p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary" id="nicknameSubmit">변경하기</button>
      </div>
     <?php echo form_close(); ?>
     </div>
     
       </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

뷰에서 ajax 처리 코드 입니다.

<script>
$(document).ready(function(){
  
    
    $("#nicknameSubmit").click(function(){
       
       var csrf_test_name=getCookie('csrf_cookie_name');
       $.ajax({
            url:"/index.php/user/user_setting/nicknamechange",
            type:"post",
            data:{
                "csrf_test_name":getCookie('csrf_cookie_name'),
                "nickname":$("#nickname").val()
            },
            dataType:"text",
            success:function(textStatus){
                 
                    console.log($.trim(textStatus));    
                    $("#errorMessage").html($.trim(textStatus));
                    
                if($.trim(textStatus)==500){
                    alert("로그인을 먼저하세요.");
                    location.href="/";
                }
            },
            error:function(textStatus){
                
            }    
       });
               
    });
    

    
});  
 
function getCookie( name )
{
    var nameOfCookie = name + "=";
        var x = 0;
 
        while ( x <= document.cookie.length )
        {
            var y = (x+nameOfCookie.length);
 
            if ( document.cookie.substring( x, y ) == nameOfCookie ) {
                if ( (endOfCookie=document.cookie.indexOf( ";", y )) == -1 )
                    endOfCookie = document.cookie.length;
 
                return unescape( document.cookie.substring( y, endOfCookie ) );
            }
 
            x = document.cookie.indexOf( " ", x ) + 1;
 
            if ( x == 0 )
 
            break;
        }
 
        return "";
}
</script>

 

 

추가적인 방법은

form_open("/index.php/user/user_setting/nicknamechange", $attrs);

처리를 해서 자동으로 쿠키가 생성 됩니다. 이때 getCookie 함수를 사용하지 않고 .serialize() 사용해도 

됩니다. 

var params = jQuery("#폼명").serialize() 또는 var params = $("#폼명").serialize()

serialize() 사용 하면 일일이

 data:{ "csrf_test_name":getCookie('csrf_cookie_name'), "nickname":$("#nickname").val() }

이와 같이 처리를 하지 않고 data : $("#폼명").serialize() 만작성해도

데이터 을  form 안에 입력된 데이터를 전부 넘겨 주게 됩니다.

 

 

래 이미지는 위 코드를 작성 후 성공시 보여주는 이미지 입니다.

 

 

 

아래 이미지는 실패시 보여주는 이미지 입니다.

 

 

아래 이미지는 보안 테스트에서 ajax 가 아닌 경우에는 bad req 보냅니다.

Restlet Client 로 테스트 

https://chrome.google.com/webstore/detail/restlet-client-rest-api-t/aejoelaoggembcahagimdiliamlcdmfm

 

보안 처리 코드

 if(!$this->input->is_ajax_request()){echo "bad req" ;};

 

 

 


 

 

 

about author

PHRASE

Level 60  머나먼나라

정신도 몸과 마찬가지로 끊임없이 깨끗하게 해야 한다.

댓글 ( 4)

댓글 남기기

작성