PHP 양식 검증

이 장과 다음 장에서 PHP를 사용하여 양식 데이터를 확인하는 방법에 대해 설명합니다.

PHP 양식 검증

건의:PHP 양식을 처리할 때 안전성을 중시하십시오!

이 페이지는 PHP 양식을 안전하게 처리하는 방법을 보여줍니다. HTML 양식 데이터를 적절히 검증하는 것은 해커와 스팸 메일을 방지하는 데 중요합니다!

나중에 사용할 HTML 양식에는 여러 가지 입력 필드가 포함됩니다: 필수와 선택 사항의 텍스트 필드, 단일 선택 버튼 및 제출 버튼:

위의 양식은 다음과 같은 검증 규칙을 사용합니다:

필드 검증 규칙
Name 필수. 문자와 공백을 포함해야 합니다.
E-mail 필수. 유효한 이메일 주소( @ 및 . 포함)를 포함해야 합니다.
Website 선택 사항. 선택하면 유효한 URL을 포함해야 합니다.
Comment 선택 사항. 다중 행 입력 필드(텍스트 박스)
Gender 필수. 반드시 선택해야 합니다.

먼저 이 양식의 원본 HTML 코드를 보겠습니다:

텍스트 필드

name, email 및 website는 텍스트 입력 요소이며, comment 필드는 텍스트 박스입니다. HTML 코드는 다음과 같습니다:

Name: <input type="text" name="name">
E-mail: <input type="text" name="email">
Website: <input type="text" name="website">
Comment: <textarea name="comment" rows="5" cols="40"></textarea>

단일 선택 버튼

gender 필드는 단일 선택 버튼이며, HTML 코드는 다음과 같습니다:

Gender:
<input type="radio" name="gender" value="female">Female
<input type="radio" name="gender" value="male">Male

양식 요소

양식의 HTML 코드는 다음과 같습니다:

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>

이 양식을 제출할 때, method="post"를 통해 양식 데이터를 전송합니다.

$_SERVER["PHP_SELF"] 변수는 무엇인가요?

$_SERVER["PHP_SELF"]는 현재 실행 스크립트의 파일 이름을 반환하는 전역 변수입니다.

따라서, $_SERVER["PHP_SELF"]는 양식 데이터를 페이지 자체로 전송하여 다른 페이지로 이동하지 않습니다. 이렇게 하면 사용자가 양식 페이지에서 오류 표시 정보를 얻을 수 있습니다.

htmlspecialchars() 함수는 무엇인가요?

htmlspecialchars() 함수는 특수 문자를 HTML 엔티티로 변환합니다. 이는 <와 >와 같은 HTML 문자가 <와 >로 변환되는 것을 의미합니다. 이렇게 하면 공격자가 폼에 HTML 또는 JavaScript 코드를 주입하여 코드를 활용하는 크로스사이트 스크립팅 공격을 방지할 수 있습니다.

PHP 퍼블릭 폼 보안에 대한 중요한 팁

$_SERVER["PHP_SELF"] 변수는 해커에 의해 활용될 수 있습니다!

PHP_SELF를 사용하는 페이지에서는 사용자가 아래 줄을 입력하면 크로스사이트 스크립팅(XSS)을 실행할 수 있습니다.

건의:크로스사이트 스크립팅(XSS)은 웹 애플리케이션에서 흔히 발생하는 컴퓨터 보안 취약점입니다. XSS는 공격자가 다른 사용자가 탐색하는 웹 페이지에 클라이언트 스크립트를 입력할 수 있게 합니다.

가정해보면, "test_form.php"라는 이름의 페이지에 다음과 같은 폼이 있습니다:

<form method="post" action="<?php echo $_SERVER["PHP_SELF"];?>">

이제, 사용자가 주소줄에 있는 정상적인 URL에 접근한 경우: "http://www.example.com/test_form.php" 위의 코드는 다음과 같이 변환됩니다:

<form method="post" action="test_form.php">

지금까지는 모든 것이 정상입니다.

하지만, 사용자가 다음과 같은 URL을 주소줄에 입력했을 때:

http://www.example.com/test_form.php/%22%3E%3Cscript%3Ealert('hacked')%3C/script%3E

이 경우, 위의 코드는 다음과 같이 변환됩니다:

<form method="post" action="test_form.php"/><script>alert('hacked')</script>

이 코드는 스크립트와 알림 명령어를 추가했습니다. 이 페이지가 로드되면 JavaScript 코드가 실행됩니다(사용자는 알림 팝업을 볼 수 있습니다)。이것은 PHP_SELF 변수가 어떻게 활용되는지에 대한 간단하고 무해한 예제입니다.

알아야 할 것은 <script> 태그 내에 어떤 JavaScript 코드든 추가할 수 있습니다! 해커는 사용자를 다른 서버의 파일로 이동시키고, 그 파일의 악성 코드가 전역 변수를 변경하거나 사용자 데이터를 다른 주소로 전송하는 등 다양한 방법으로 공격할 수 있습니다.

$_SERVER["PHP_SELF"]를 이용할 수 없게 어떻게 합니까?

htmlspecialchars() 함수를 사용하여 $_SERVER["PHP_SELF"]를 이용할 수 없게 합니다.

양식 코드는 다음과 같습니다:

<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

htmlspecialchars() 함수는 특수 문자를 HTML 엔티티로 변환합니다. 사용자가 PHP_SELF 변수를 이용하려고 시도하면 다음과 같은 출력이 발생합니다:

<form method="post" action="test_form.php/"><script>alert('hacked')</script>">

사용할 수 없으며, 위험도 없습니다!

PHP를 통해 양식 데이터 검증

첫 번째로 PHP의 htmlspecialchars() 함수를 통해 모든 변수를 전달해야 합니다.

htmlspecialchars() 함수를 사용하여, 사용자가 텍스트 필드에 다음과 같은 내용을 제출하려고 시도할 때:

<script>location.href('http://www.hacked.com')</script>

- 코드는 이렇게 저장되어 있기 때문에 실행되지 않습니다:

<script>location.href('http://www.hacked.com')</script>

이 코드는 페이지에 표시되거나 이메일에 보내지면 안전합니다.

사용자가 이 양식을 제출할 때, 추가로 두 가지 작업을 수행해야 합니다:

  1. (PHP trim() 함수를 통해) 사용자 입력 데이터 중 불필요한 문자(额外的 공백, 탭, 개행) 제거
  2. (PHP stripslashes() 함수를 통해) 사용자 입력 데이터 중 반대slashes(\) 제거

다음으로, 코드를 반복적으로 작성하는 대신 효율성을 높이기 위해 체크 함수를 생성했습니다.

함수 이름을 test_input()로 지정했습니다.

지금, test_input() 함수를 통해 각 $_POST 변수를 확인할 수 있습니다. 이 스크립트는 다음과 같습니다:

예제

<?php
// 변수 정의하고 공백 값으로 설정
$name = $email = $gender = $comment = $website = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
  $name = test_input($_POST["name"]);
  $email = test_input($_POST["email"]);
  $website = test_input($_POST["website"]);
  $comment = test_input($_POST["comment"]);
  $gender = test_input($_POST["gender"]);
}
function test_input($data) {
  $data = trim($data);
  $data = stripslashes($data);
  $data = htmlspecialchars($data);
  return $data;
}
?>

실행 예제

스크립트의 시작 부분에서는 양식이 $_SERVER["REQUEST_METHOD"]를 통해 제출되었는지 확인했습니다. REQUEST_METHOD가 POST라면 양식이 제출되었음을 의미하며, 검증해야 합니다. 제출되지 않았다면 검증을 건너뛰고 빈 양식을 표시합니다.

그러나 위의 예제에서는 모든 입력 필드가 선택 사항입니다. 사용자가 어떤 데이터도 입력하지 않았더라도 스크립트가 정상적으로 작동합니다.

다음 단계는 필수 입력 필드를 만들고 필요시 사용할 오류 메시지를 생성하는 것입니다.