가이드 시작 부분에서 우리는 데이터 필터링이 모든 언어와 플랫폼에서 웹 애플리케이션 보안의 초석이라고 말했습니다. 여기에는 애플리케이션과의 데이터 입력 확인이 포함되며, 좋은 소프트웨어 설계는 개발자에게 도움이 될 수 있습니다.
즉, 데이터 필터링을 우회할 수 없도록 하고,
불법 정보가 법적 정보에 영향을 미치지 않도록 하고,
데이터 소스를 식별하는 데 도움이 될 수 있습니다.
데이터 필터링을 우회할 수 없도록 하는 방법에 대한 다양한 견해가 있으며, 그 중 두 가지는 다른 것보다 더 일반적이며 더 높은 수준의 보증을 제공합니다.
예약 방법 이 방법은 단일 PHP 스크립트(URL을 통해)로 예약됩니다. 필요한 경우 include 또는 require를 사용하여 다른 작업이 포함됩니다. 이 접근 방식에서는 일반적으로 각 URL에 디스패치용 별도의 GET 변수가 전달되어야 합니다. 이 GET 변수는 스크립트 이름을 대체하는 보다 단순화된 디자인으로 생각할 수 있습니다. 예:
http://example.org/dispatch.php?task=print_formdispatch.php 는 유일한 루트 파일(문서 루트)입니다. 이를 통해 개발자는 매우 중요한 두 가지 작업을 수행할 수 있습니다. 즉,
처음에 dispatch.php에서 전역 보안 처리를 구현하고 이러한 처리를 우회할 수 없도록 하는 것입니다.
특히 일부 특수 목적의 제어 흐름 작업의 경우 데이터 필터링이 필요한 위치를 쉽게 결정할 수 있습니다.
dispatch.php 스크립트에 대한 자세한 내용은 다음 예를 참조하세요.
<?php/* 전역 보안 처리*/switch ($_GET['task']){case 'print_form':include '/inc/presentation/form.inc '; break;case 'process_form':$form_valid = false;include '/inc/logic/process.inc';if ($form_valid){include '/inc/presentation/end.inc';}else{include '/ inc/ Presentation/form.inc';}break;default:include '/inc/presentation/index.inc';break;}?>이것이 공개적으로 액세스할 수 있는 유일한 PHP 스크립트라면 이 프로그램의 디자인은 다음과 같습니다. 초기 글로벌 보안 처리를 우회할 수 없도록 보장합니다. 또한 개발자가 특정 작업의 제어 흐름을 쉽게 확인할 수 있습니다. 예를 들어, 전체 코드를 검색하지 않고도 쉽게 알 수 있습니다. $form_valid가 true인 경우 end.inc는 process.inc가 포함되기 전이고 방금 false로 초기화되었기 때문에 사용자에게 표시되는 유일한 항목입니다. process.inc의 내부 논리가 이를 true로 설정한다고 판단할 수 있습니다. 그렇지 않으면 양식이 다시 표시됩니다(아마도 관련 오류 메시지와 함께).
index.php(dispatch.php 대신)와 같은 디렉토리 지시문 파일을 사용하는 경우 다음과 같은 URL 주소를 사용할 수 있습니다: http://example.org/?task=print_form .
ApacheForceType 리디렉션 또는 mod_rewrite를 사용하여 URL 주소( http://example.org/app/print-form ) 를 조정할 수도 있습니다.
메소드를 포함하는 또 다른 방법은 모든 보안 처리를 담당하는 단일 모듈을 사용하는 것입니다. 이 모듈은 모든 공개 PHP 스크립트의 앞부분(또는 맨 앞부분)에 포함되어 있습니다. 다음 스크립트를 참조하십시오. security.inc
<?phpswitch ($_POST['form']){case 'login':$allowed = array();$allowed[] = 'form';$allowed[] = 'username' ; $allowed[] = 'password';$sent = array_keys($_POST);if ($allowed == $sent){include '/inc/logic/process.inc';}break;}?>이 경우 , 제출된 각 양식은 양식의 고유한 확인 값을 포함하는 것으로 간주되며 security.inc는 필터링이 필요한 양식의 데이터를 독립적으로 처리합니다. 이 요구 사항을 구현하는 HTML 형식은 다음과 같습니다.
<form action="/receive.php" method="POST"><input type="hidden" name="form" value="login" /><p>사용자 이름 : <input type="text" name="username" /></p><p>비밀번호:<input type="password" name="password" /></p><input type="submit" / > </form>$allowed라는 배열은 어떤 양식 변수가 허용되는지 확인하는 데 사용됩니다. 이 목록은 양식이 처리되기 전에 일관성이 있어야 합니다. 프로세스 제어는 무엇을 실행할지 결정하고, process.inc는 실제 필터링된 데이터가 도착하는 곳입니다.
security.inc가 항상 모든 스크립트의 시작 부분에 포함되도록 하는 더 좋은 방법은 auto_prepend_file 설정을 사용하는 것입니다.
필터링 예 화이트리스트를 생성하는 것은 데이터 필터링에 매우 중요합니다. 접할 수 있는 모든 양식 데이터에 대해 예를 제공하는 것은 불가능하므로 몇 가지 예를 통해 일반적인 이해를 도울 수 있습니다.
다음 코드는 이메일 주소의 유효성을 검사합니다.
<?php$clean = array();$email_pattern = '/^[^@s<&>]+@([-a-z0-9]+.) +[ az]{2,}$/i';if (preg_match($email_pattern, $_POST['email'])){$clean['email'] = $_POST['email'];}?> 아래 코드 $_POST['color']의 내용이 빨간색, 녹색 또는 파란색인지 확인합니다.
<?php$clean = array();switch ($_POST['color']){case 'red':case 'green ' :case 'blue':$clean['color'] = $_POST['color'];break;}?>다음 코드는 $_POST['num']가 정수인지 확인합니다.
<?php$ clean = array ();if ($_POST['num'] == strval(intval($_POST['num']))){$clean['num'] = $_POST['num'];} >다음 코드는 $_POST['num']가 float인지 확인합니다:
<?php$clean = array();if ($_POST['num'] == strval(floatval($_POST['num ']))){ $clean['num'] = $_POST['num'];}?> 각 예에서는 이름 변환 전에 $clean 배열을 사용합니다. 이는 개발자가 데이터가 잠재적으로 손상되었는지 확인하는 좋은 방법입니다. 데이터를 검증한 후에는 절대로 $_POST 또는 $_GET에 저장하지 마십시오. 개발자는 항상 슈퍼 전역 배열에 저장된 데이터를 완전히 의심해야 합니다.
$clean을 사용하면 필터링되지 않은 항목을 생각하는 데 도움이 될 수 있으며 이는 화이트리스트의 역할과 더 유사합니다. 보안 수준을 향상시킬 수 있습니다.
검증된 데이터만 $clean에 저장하는 경우 데이터 검증의 유일한 위험은 필터링되지 않은 위험한 데이터가 아니라 참조하는 배열 요소가 존재하지 않는다는 것입니다.
타이밍 PHP 스크립트가 실행되기 시작하면 모든 HTTP 요청이 종료되었음을 의미합니다. 이 시점에서 사용자는 스크립트에 데이터를 보낼 기회가 없습니다. 따라서 (register_globals가 켜져 있는 경우에도) 스크립트에 데이터를 입력할 수 없습니다. 이것이 바로 변수를 초기화하는 것이 매우 좋은 습관인 이유입니다.