그누보드 최신버전 (5.0.36) 살펴보기 - common.php (3) 정보
그누보드5 그누보드 최신버전 (5.0.36) 살펴보기 - common.php (3)본문
그누보드 최신버전 (5.0.36) 살펴보기 - common.php (3)
common.php 그누보드에서 가장 기본이 되는 파일이라고 볼수 있습니다.
모든 파일에 기본적으로 인클루드 되어서 사용됩니다.
에러출력 설정, 보안적인 처리, 기본적인 경로 설정, 디비연결, 세션 설정및 시작, 공용변수의 초기화 및 재설정, 기타 확장 등의 내용으로 이루어져 있습니다.
function array_map_deep($fn, $array)
{
if(is_array($array)) {
foreach($array as $key => $value) {
if(is_array($value)) {
$array[$key] = array_map_deep($fn, $value);
} else {
$array[$key] = call_user_func($fn, $value);
}
}
} else {
$array = call_user_func($fn, $array);
}
return $array;
}
"array_map_deep" 은 어떤 배열을 $array 로 받았을때 하위 모든 배열의 값에 어떤 처리를 일괄적으로 하기 만들어진 함수입니다.
php 에서 기본 제공하는 "array_map" 이 있지만 이것은 일차원배열만 처리되므로, 다차원의 배열을 처리하기 위해 만들어진 함수입니다.
http://php.net/manual/kr/function.array-map.php
array array_map ( callable $callback , array $array1 [, array $... ] )
에서 callable $callback 이라는 것이 보이는데 말그대로 지정된 함수나 클래스를 호출하고 값을 돌려받는다는 의미입니다.
array_map_deep($fn, $array) 여기에서는 $fn 이 위의 $callback 과 같은 것이라고 보시면 됩니다.
배열일때만 실행하고 배열이 아닐경우에는 $array에 아무 처리를 하지 않고 원래 그대로 리턴합니다.
foreach($array as $key => $value) {
if(is_array($value)) {
$array[$key] = array_map_deep($fn, $value);
} else {
$array[$key] = call_user_func($fn, $value);
}
}
배열 크기 대로 돌려서 현재 배열의 값이 배열이면 자기 자신을 재귀호출 하여 리턴값을 받고
배열이 아닐경우에는 콜백 함수를 실행하여 리턴값을 받는다라는 의미 입니다.
"call_user_func" 는 함수명을 알고 있을 때 그 함수를 호출해주고 리턴값을 돌려주는 함수입니다.
함수명이 특정 변수의 조합으로 이루어질때 사용하기 유용합니다.
http://php.net/manual/kr/function.call-user-func.php
예를 들어 회원 레벨 마다 특별한 체크가 필요한경우
function level_check_2($mb) {
......
}
function level_check_3($mb) {
......
}
function level_check_4($mb) {
......
}
......
이런 식으로 각 레벨마다 체크함수가 다르다고 한다면
$check_result = call_user_func('level_check_' . $member['mb_level'], $member);
이런식으로 사용이 가능합니다.
function sql_escape_string($str)
{
if(defined('G5_ESCAPE_PATTERN') && defined('G5_ESCAPE_REPLACE')) {
$pattern = G5_ESCAPE_PATTERN;
$replace = G5_ESCAPE_REPLACE;
if($pattern)
$str = preg_replace($pattern, $replace, $str);
}
$str = call_user_func('addslashes', $str);
return $str;
}
이 함수는 sql 인젝션 공격에 대비한 함수라고 보면 됩니다.
기존에는 "mysql_real_escape_string" 을 주로 썻지만, 이 함수를 쓰기 위해서는 디비 연결이 선행되어야 하기 때문에 "addslashes" 라는 함수를 쓴것으로 보입니다.
http://php.net/manual/kr/function.mysql-query.php
그누보드4 버전 같은 경우는 $_POST 나 $_GET, $_COOKIE 값을 임의로 "addslashes" 로 가공 한 후 사용하였기 때문에
여러가지 문제들이 좀 있었지만, 그누보드5 에선 넘긴 데이타의 원형 그대로를 사용하기 때문에 이전에 가졌던 문제는 없어졌다고 보는것이 맞습니다.
따라서 "addslashes" 만으로도 충분히 sql 인젝션 공격에 대비 할수 있습니다.
http://php.net/manual/kr/function.addslashes.php
if(defined('G5_ESCAPE_PATTERN') && defined('G5_ESCAPE_REPLACE')) {
......
}
이부분은 상위에서 인클루드 되어진 config.php 에서 "G5_ESCAPE_PATTERN" 과 "G5_ESCAPE_REPLACE" 가 설정 되어 있다면, 치환을 하겠다는 뜻입니다.
현재는 설정이 되어있지 않습니다.
$str = call_user_func('addslashes', $str);
여기서는 함수의 인자로 콜백 함수명을 받지 않기 때문에
$str = addslashes($str);
로 사용하는 것이 더 바람직한 것 같습니다.
아무튼 "sql_escape_string" 이 함수는 sql 인젝션 공격에 방어하기 위해서 만들어진 함수 이며, 주 내용은 "addslashes" 처리를 한다는 것입니다.
그리고, config.php 에서
define('G5_ESCAPE_FUNCTION', 'sql_escape_string');
식으로 등록되어져서 사용 되어집니다.
if (get_magic_quotes_gpc()) {
$_POST = array_map_deep('stripslashes', $_POST);
$_GET = array_map_deep('stripslashes', $_GET);
$_COOKIE = array_map_deep('stripslashes', $_COOKIE);
$_REQUEST = array_map_deep('stripslashes', $_REQUEST);
}
php 설정상 magic_quotes_gpc 가 1 인 경우에는
$_POST, $_GET, $_COOKIE 등에 자동적으로 "addslashes" 처리가 되기 때문에
넘길 당시의 원형의 값을 받기 위해 "array_map_deep" 함수를 사용 하여 "stripslashes" 처리를 해주는 것입니다.
$_POST = array_map_deep(G5_ESCAPE_FUNCTION, $_POST);
$_GET = array_map_deep(G5_ESCAPE_FUNCTION, $_GET);
$_COOKIE = array_map_deep(G5_ESCAPE_FUNCTION, $_COOKIE);
$_REQUEST = array_map_deep(G5_ESCAPE_FUNCTION, $_REQUEST);
$_POST, $_GET, $_COOKIE 등에 "G5_ESCAPE_FUNCTION" 로 등록된 함수를 통하여 미리 데이타를 가공하는 의미입니다.
원래는 이렇게 선처리 보다 각 디비 처리시 개별적으로 일일이 넣어주는것이 좋으나,
이전에서도 설명 한 바 있듯이, 스킨이나 사용자가 직접 추가 수정한 부분에서 사용하지 않을 수도 있으므로
보안상 일괄적으로 미리 처리하는 의미입니다.
@extract($_GET);
@extract($_POST);
@extract($_SERVER);
제가 이전 내용에서 "extract" 는 사용되지 않는다고 하였는데......
아마도 이것역시 기존 스킨이나 사용자가 직접 추가한 부분에서 사용되는 것들에 대한 대비로서 넣어 놓은 부분 인것 같습니다.
그러나, 이것도 앞으로는 빠져야 할 부분이라고 생각합니다.
$config = array();
$member = array();
$board = array();
$group = array();
$g5 = array();
그누보드의 중요 변수의 초기화 입니다.
그누보드 내부적으로 사용되는 중요 변수 이므로, 이전에 정의 되었거나 $_GET 이나 $_POST 로 넘어 온것에 대한 "extract" 로 먼저 정의 되어있을수 있는 것을 방지 하기 위한 차원이며,
프로그램 상 형선언의 의미도 있습니다.
8
댓글 16개
이런 내용정도 파악이 용이합니다. 그러나 곧.. 굉장해 질 것 같아요. ^^
모두 선생님께서 이롭고자 움직여 주신 은공입니당~~
고맙습니다. 선생님..
감사합니다.
밥먹고 와서 다시 보니 이해가 되네요~^^
좋은 강좌 올려주셔서 감사합니다.
고맙습니다.
기본기가 탄탄해지는 기분이 듭니다. 감사합니다....^^
유선생님, 그런데 마지막 그누보드 변수 초기화 부분에서
"프로그램 상 형선언의 의미도 있습니다."
이 부분을 잘 이해 못했습니다.
초보의 질문을 너그러이....ㅜㅜ (__)
앞으로 이런 변수를 이런 데이타 타입으로 쓰겟다고 미리 지정 하고, 메모리에 할당해 놓는것을 말합니다.
php 나 자바스크립트 같은 것들은 비교적 이런것에 자유롭기 때문에
형(변수)선언을 하지 않아도 크게 문제가 없지만,
원래는 써주는것이 정석입니다.
답변이 되었는지 모르겠습니다.
열공하겠습니다. (__)
유창화님의 글 솜씨는 분명 책을 내도 되실 분이십니다.
혹시 기존에 이미 저술하신 경험이 계십니까?
낸적은 없습니다.
혹시 궁금한 점이 있어서 여쭈고자 하는게,
인터넷에 아무리 찾아봐도 자세한 내용이 없어서 질문드려요.
sql 인젝션 대응을 하기 위에 addslashes ( ) 함수를 흔히 이용하는데,
백슬래쉬를 ', ",\, 등 앞에 추가시키는 기능을 하면, 그것이 정확히 어떻게 sql 인젝션을 막는건가요?
이해가 안 가서요.
예를 들어,
SELECT full_name AND password WHERE user_name='bla' OR '1'='1'
어느 해커가 sql 을 이렇게 수정하였다 치면,
제가 addslashes([$_POST('user_name')]);
addslashes([$_POST('password')]);
방지를 위해 이렇게 쓴다고 하여도,
결국엔
SELECT full_name AND password WHERE user_name=\'bla\' OR \'1\'=\'1\'
가 되어, \'1\'=\'1\' 가 성립이 되어 결국에는 유출이 되고 말지 않나요??