개발 중이든, 인터뷰 중이든, 기술 논의 중이든 보안에 대한 심층적인 이해와 숙달이 필요합니다.
목표
이 튜토리얼의 목표는 여러분이 구축하는 웹 애플리케이션을 보호하는 방법을 이해하는 것입니다. SQL 주입, GET 및 POST 변수 조작, 버퍼 오버플로 공격, 사이트 간 스크립팅 공격, 브라우저 내 데이터 조작, 원격 양식 제출 등 가장 일반적인 보안 위협으로부터 보호하는 방법을 알아보세요.
보안에 대한 간략한 소개
웹 애플리케이션에서 가장 중요한 부분은 무엇인가요? 이 질문에 대한 대답은 누가 대답하느냐에 따라 달라질 수 있습니다. 비즈니스 사람들에게는 안정성과 확장성이 필요합니다. IT 지원 팀에는 강력하고 유지 관리가 가능한 코드가 필요합니다. 최종 사용자는 작업 수행 시 아름다운 사용자 인터페이스와 높은 성능을 요구합니다. 그러나 대답이 "보안"이라면 이것이 웹 애플리케이션에 중요하다는 점에는 모두가 동의할 것입니다.
그러나 대부분의 논의는 여기서 그칩니다. 보안은 프로젝트 체크리스트에 있지만 프로젝트가 전달될 때까지 해결되지 않는 경우가 많습니다. 이 접근 방식을 사용하는 웹 애플리케이션 프로젝트의 수는 엄청납니다. 개발자들은 웹 애플리케이션을 대중에게 공개하기 위해 마지막에 보안 기능을 추가하면서 몇 달 동안 작업했습니다.
보안 기능이 추가되기 전에 코드를 검사하고, 단위 테스트하고, 더 큰 프레임워크에 통합했기 때문에 결과가 엉망이거나 재작업이 필요한 경우가 많습니다. 보안을 추가한 후 주요 구성 요소의 작동이 중지될 수 있습니다. 보안 통합은 원활하지만 안전하지 않은 프로세스에 추가 부담이나 단계를 추가합니다.
이 튜토리얼은 PHP 웹 애플리케이션에 보안을 통합하는 훌륭한 방법을 제공합니다. 몇 가지 일반적인 보안 주제를 논의한 다음 주요 보안 취약점과 이를 연결하는 방법을 자세히 살펴봅니다. 이 튜토리얼을 마치면 보안에 대해 더 잘 이해하게 될 것입니다.
주제:
SQL 주입 공격
GET 문자열 조작
버퍼 오버플로 공격
교차 사이트 스크립팅 공격(XSS)
브라우저 내 데이터 조작
원격 양식 제출
웹 보안 101
보안 구현의 세부 사항을 논의하기 전에 높은 수준의 관점에서 웹 애플리케이션 보안을 논의하는 것이 가장 좋습니다. 이 섹션에서는 어떤 종류의 웹 애플리케이션을 생성하든 염두에 두어야 할 몇 가지 기본 보안 철학을 소개합니다. 이러한 아이디어 중 일부는 Chris Shiflett(PHP 보안에 관한 책이 귀중한 보고임), 일부는 Simson Garfinkel(참고자료 참조), 일부는 수년간 축적된 지식에서 나왔습니다.
규칙 1: 외부 데이터나 입력을 절대 신뢰하지 마세요
웹 애플리케이션 보안에 대해 가장 먼저 깨달아야 할 것은 외부 데이터를 신뢰해서는 안 된다는 것입니다. 외부 데이터에는 프로그래머가 PHP 코드에 직접 입력하지 않은 모든 데이터가 포함됩니다. 다른 소스(예: GET 변수, 양식 POST, 데이터베이스, 구성 파일, 세션 변수 또는 쿠키)의 모든 데이터는 보안을 보장하기 위한 조치를 취할 때까지 신뢰할 수 없습니다.
예를 들어 다음 데이터 요소는 PHP에서 설정되므로 안전하다고 간주할 수 있습니다.
목록 1. 안전하고 흠집 없는 코드
define("GREETING", 'hello there' . $myUsername); [/php]
그러나 다음 데이터 요소에는 결함이 있습니다.
목록 2. 안전하지 않고 결함이 있는 코드
', 'tommy'); //오염되었습니다!
define("GREETING", '안녕하세요' . $myUsername) //오염되었습니다.
첫 번째 변수 $myUsername에 결함이 있는 이유는 무엇입니까? POST 형식에서 직접 제공되기 때문입니다. 사용자는 파일을 정리하거나 이전에 업로드한 파일을 실행하기 위한 악성 명령을 포함하여 이 입력 필드에 임의의 문자열을 입력할 수 있습니다. "A-Z 문자만 허용하는 클라이언트측(JavaScript) 양식 유효성 검사 스크립트를 사용하면 이러한 위험을 피할 수 없나요?"라고 물을 수 있습니다. 예, 이는 항상 유익한 단계이지만 나중에 살펴보겠지만 누구나 어떤 양식이든 컴퓨터에 다운로드하여 수정하고 필요한 것을 다시 제출할 수 있습니다.
해결책은 간단합니다. 삭제 코드는 $_POST['username']에서 실행되어야 합니다. 이렇게 하지 않으면 $myUsername을 사용할 때마다(배열이나 상수 등에서) 이러한 개체가 오염될 위험이 있습니다.
사용자 입력을 삭제하는 간단한 방법은 정규식을 사용하여 처리하는 것입니다. 이 예에서는 문자만 허용됩니다. 문자열을 특정 문자 수로 제한하거나 모든 문자를 소문자로 요구하는 것도 좋은 생각일 수 있습니다.
목록 3. 사용자 입력을 안전하게 만들기
[php]$myUsername = cleanInput($_POST['username']) //clean!
$arrayUsers = array($myUsername, 'tom ', '토미'); //깨끗해요!
Define("GREETING", '안녕하세요' . $myUsername); //clean!
function cleanInput($input){
$clean = strtolower($input);
$clean = preg_replace(" /[^a-z]/", "", $clean);
$clean = substr($clean,0,12);
return $clean;
}[/php]
규칙 2: 보안 구현을 어렵게 만드는 PHP 설정 비활성화
이제 사용자 입력을 신뢰할 수 없으므로 PHP가 시스템에서 구성되는 방식도 신뢰해서는 안 된다는 점을 알아야 합니다. 예를 들어, Register_globals가 비활성화되어 있는지 확인하십시오. Register_globals가 활성화되면 $variable을 사용하여 GET 또는 POST 문자열을 동일한 이름으로 바꾸는 것과 같은 부주의한 작업을 수행할 수 있습니다. 이 설정을 비활성화하면 PHP는 올바른 네임스페이스에서 올바른 변수를 참조하도록 강제합니다. POST 형식의 변수를 사용하려면 $_POST['variable'] 을 인용해야 합니다. 이렇게 하면 이 특정 변수를 쿠키, 세션 또는 GET 변수로 착각하지 않을 것입니다.
두 번째로 확인해야 할 설정은 오류 보고 수준입니다. 개발 중에는 가능한 한 많은 오류 보고서를 얻고 싶지만, 프로젝트를 전달할 때는 오류가 화면에 표시되지 않고 로그 파일에 기록되기를 원합니다. 왜? 악의적인 해커가 오류 보고 정보(예: SQL 오류)를 사용하여 애플리케이션이 수행하는 작업을 추측할 수 있기 때문입니다. 이러한 종류의 정찰은 해커가 애플리케이션을 침해하는 데 도움이 될 수 있습니다. 이 취약점을 해결하려면 php.ini 파일을 편집하여 error_log 항목에 적합한 대상을 제공하고 display_errors를 Off로 설정하십시오.
규칙 3: 이해하지 못하면 보호할 수 없습니다
일부 개발자는 이상한 구문을 사용하거나 명령문을 매우 촘촘하게 구성하여 짧지만 모호한 코드를 만듭니다. 이 접근 방식은 효율적일 수 있지만 코드가 수행하는 작업을 이해하지 못하면 코드를 보호하는 방법을 결정할 수 없습니다.
예를 들어, 다음 두 가지 코드 중 어떤 코드가 마음에 드시나요?
목록 4. 코드를 보호하기 쉽게 만드세요
”);
//난독되지 않은 코드
$input = ”;
if (isset($_POST['username'])){
$input = $_POST['username'];
}else{
$input = ”;
}[/php]
두 번째로 명확한 코드 조각에서는 다음을 수행하는 것이 쉽습니다. $input에 결함이 있어 청소해야 합니다.
규칙 4: "심층 방어"가 새로운 마법 무기입니다.
이 튜토리얼에서는 예제를 사용하여 온라인 양식을 보호하는 방법을 설명합니다. , 양식을 처리하는 PHP 코드에서 필요한 조치를 취하는 동안 PHP 정규식을 사용하여 GET 변수가 완전히 숫자인지 확인하는 경우에도 SQL 쿼리가 이스케이프된 사용자 입력을 사용하도록 조치를 취할 수 있습니다.
심층 방어
이제 기본 규칙에 대해 논의했으니 첫 번째 위협인 SQL 주입 공격을 살펴보겠습니다.
SQL 주입 공격 방지
SQL 삽입 공격에서 사용자는 양식 또는 GET 쿼리 문자열을 조작하여 정보가 데이터베이스 쿼리에 추가됩니다. 예를 들어 이 데이터베이스의 각 레코드에는 사용자 이름 필드와 비밀번호가 있다고 가정합니다. 필드. 사용자가 로그인할 수 있는 로그인 양식을 작성하십시오.
목록 5. 간단한 로그인 양식 본문>