'Tip'에 해당하는 글 36건

PHP Security

Tip/PHP 2012. 12. 12. 00:10

1. 외부/입력 데이터 처리

 

GET/POST/COOKIE/SESSION 변수, DB, php config 등으로 전달되는 데이터는 변조될 수 있으므로 정규식을 사용하여 입력 처리.

 

function cleanInput($input){
    $clean = strtolower($input);
    $clean = preg_replace("/[^a-z]/", "", $clean);
    $clean = substr($clean,0,12);
    return $clean;
}

 

$userId = cleanInput($_POST['userid']);

 

입력받은 $_POST['userid'] 변수의 형식이 영문(소문자), 12자 이내로만 이루어져야 한다면,
위와 같이, 입력 변수를 체크할 수 있도록 처리합니다.
특히 사용자 입력값에 길이 제한을 두는 것은 여러 공격에 대하여 방지해 줍니다.

 

 

2. PHP config 의 보안 설정

 

php.ini 파일 편집

 

register_globals = off  
// GET,POST,COOKIE,SESSION,SERVER 등의 변수 공유 악용 방지
// php5.3 deprecated, 5.4 removed)

 

display_errors = off
// 오류정보 출력에 대한 악용 방지.
// 개발시에는 많은 오류가 보고되는 것이 좋지만, 완료 후에는 오류 대신에 파일로 대체.

 

 

3. SQL Injection 공격 회피

 

where username = '{$_GET['username'}' and password = '{$_GET['password']}' 의 경우
$_GET['password'] 에 악의적인 코드를 삽입하여 쿼리를 통과할 수 있습니다.
password 입력 항목에 ' or '1'='1 이라고 입력한다면,
where username = '' and password = '' or '1'='1' 이 되어 무조건 통과하게 됩니다.
이를 방지하기 위해 입력 값에 mysql_real_escape_string 함수를 사용하여 '등의 특수문자를 회피할 수 있도록 합니다.

 

 

4. 버퍼 오버플로우 공격 방지

 

특정 버퍼를 전복시키거나 다음 버퍼에 악성 코드를 삽입하여 데이터를 손상시키는 오버플로우에 대해서는 데이터 길이 제한을 두고,
16진 문자열에 대해서는 이 문자열을 제거하는 정규식을 추가합니다.

 

function cleanHex($input){
    $clean = preg_replace("![\][xX]([A-Fa-f0-9]{1,3})!", "",$input);
    return $clean;
}

 

$name = cleanHex($_POST['name']);

 

 

5. 교차 사이트 스크립팅(XSS) 공격 방지

 

사용자 입력 폼에서 이름, 이메일, 내용 등을 넣을 때 악성 스크립트로 쿠키 등의 정보를 훔칠 수 있습니다.
전달된 값에 태그 변환 strip_tags(), HTML 엔티티 변환 htmlspecialchars() 등을 사용해 공격을 차단하도록 합니다.

 

 

6. 원격 폼 전송 차단

 

폼 페이지를 저장하여 타 사이트에 게재하고 form action 값을 위장할 수 있습니다.
HTTP_REFERER 을 확인할 수도 있으나 가장 좋은 대처 방법은,
토큰을 생성하여 session 변수와 폼에 배치시키고 전송 뒤에 이 값들을 확인하는 방법입니다.
토큰을 무작위로 작성하려면 md5(), uniqid(), rand() 함수를 사용해야 합니다.

 

#form.php
$token = md5( uniqid( rand(), true ) );
$_SESSION['token']= $token;

 

<input type="hidden" name="token" value="<?=$token?>"/>

 

#action.php
if ( $_SESSION['token'] != $token ) {
    die( 'Invalid token!' );
}


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

트랙백  0 , 댓글  2개가 달렸습니다.
  1. 잘 보고갑니다~
secret

 

팝업 띄울 때, 모니터 중앙에 오도록 배치하기.
* 듀얼 모니터 사용시에도 해당 모니터 중앙에 오도록 배치

 

# vi popup.html

<html>
<head>
<script type="text/javascript">
function move_popup() {

    // window.innerWidth(Height) 를 사용하여 팝업 사이즈를 지정할 수도 있지만
    // 크롬에서 위 코드가 정상 작동하지 않을 시 직접 입력.
    var w = 800;
    var h = 600;

    // 팝업을 중앙으로 옮기기 위한 좌표 구하기
    var res_w = ( screen.availWidth - w ) / 2;
    var res_h = ( screen.availHeight - h ) / 2;

    // 팝업을 일단 모니터 좌측에 붙임.
    window.moveTo( 0, res_h );

    // 듀얼 모니터 사용시 팝업의 window.screenLeft 반환값은, 
    // 좌측 모니터에서는 0, 우측 모니터에서 좌측 모니터 가로길이가 계산되므로
    // 우측 모니터에서는 좌측 모니터 가로길이를 추가 계산.
   
 if ( window.screenLeft > window.screen.width ) {
        res_w = window.screen.width + res_w;
    }

    // 팝업을 중앙으로 재배치
    window.moveTo( res_w, res_h );
}
</script>

</head>
<body onload="move_popup()"><!-- call function -->


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

트랙백  0 , 댓글  0개가 달렸습니다.
secret

보안서버 구축시에 필요시 프로토콜 전환 작업이 필요합니다. http <-> https
로그인은 다음과 같은 처리 순서를 가집니다.

 

  1. http 로그인 폼에서 사용자로부터 입력을 받습니다.
  2. https 전달된 정보(id/pw)를 체크합니다.
  3. http return url로 이동합니다.

 

사용자 입력이 올바르다면 3번 과정에서 로그인 된 페이지가 출력되야 하는데,
IE에서는 로그인으로 나오지만, chrome, firefox 등에서는 로그인이 되지 않은 페이지가 출력됩니다.

 

결론적으로,

 

  1. http 는 로그인 되지 않은 상태.
  2. https 는 로그인이 된 상태.

 

몇몇 브라우저에서 http <-> https 간에 세션 공유를 못하는 것이 원인.

 

다음과 같이 해결 하였습니다.

 

  1. http 로그인 폼에서 사용자로부터 입력을 받고, https 로 전송할 때 session_id 값을 같이 전달합니다.
  2. https 에서 전달받은 session_id으로 session_id를 재설정합니다.

 

//https page
<? session_id( $_GET['sess_key'] ); ?>

 

주의할 것은 session_id() 설정은 session_start() 보다 먼저 와야 합니다.


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

트랙백  0 , 댓글  0개가 달렸습니다.
secret

Popup Layer

Tip/Javascript 2012. 9. 6. 13:56

 

 

경고창 혹은 팝업창을 대신하여 div를 이용한 popup layer.
페이지마다 모든 컨텐츠를 가릴 수 있는 div를 생성하기 위해 자바스크립트를 작성합니다.

 

var box_height = $('#container').height();
$('#black_layer).height( box_height );

 

#container 는 페이지의 모든 컨텐츠가 들어가 있는 div 엘리먼트.
이러면 popup layer 주변의 검은 배경이 페이지에 꽉 차서 스크롤을 내려도
페이지 컨텐츠의 모든 내용이 가려져야 하는데, Chrome 님께서 오작동을 하시네...
물론 뭔가 빠져서 정상 작동을 하는 것이겠지만.

 

브라우저별로 $('#container').height() 의 크기가 다르다는 불편한 진실.
ie : 1202px, chrome : 1064px 어쩔~^^;

 

$(window).load(function(){
...
});

 

로 감싸고 해결했습니다.
window.onload 이벤트에 넣어야 정상적인 세로 길이를 가져옵니다. $(document).ready() 도 가능하겠네요.
암튼 해결~ 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

트랙백  0 , 댓글  0개가 달렸습니다.
secret

1. 현재 접속자 확인

: who 명령으로 접속자를 확인합니다.

# w
 18:32:48 up 14 min,  2 users,  load average: 0.00, 0.33, 0.60
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
sally       tty1              -               18:22      10:27   0.00s    0.00s   -bash
root        pts/0    111.112.113.114    18:32       0.00s  0.03s    0.01s   w


2. 특정 접속자 KILL 

: skill 명령어로 TTY를 통해 PTY 장치에서 사용자 접속을 끊습니다.

# skill -KILL -v tty1
tty1     sally      3334 bash

# w
 18:46:16 up 27 min,  1 user,  load average: 0.00, 0.03, 0.24
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
root        pts/0    111.112.113.114    18:32       0.00s  0.03s    0.00s   w

WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

트랙백  0 , 댓글  0개가 달렸습니다.
secret