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);
자세한 규칙 설정은 링크 주소를 참조 하세요.
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">×</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" ;};
댓글 ( 4)
댓글 남기기