오류 보고는 PHP 보안에 있어서 양날의 검입니다. 한편으로는 안전을 향상시킬 수 있지만, 다른 한편으로는 해로울 수도 있습니다.
시스템을 공격할 때 일반적으로 사용되는 기술은 잘못된 데이터를 입력한 다음 오류 메시지의 유형과 컨텍스트를 확인하는 것입니다. 이렇게 하면 공격자가 약점을 찾기 위해 서버 정보를 수집하는 데 도움이 됩니다. 예를 들어, 공격자가 페이지의 기반이 되는 양식 정보를 알고 있으면 변수를 수정하려고 시도합니다.
예 #1 사용자 정의 HTML 페이지를 사용하여 변수를 공격합니다
<form method="post" action="attacktarget?username=badfoo&password=badfoo"> <input type="hidden" name="username" value="badfoo" /> <input type="hidden" name="password" value="badfoo" /> </form>
일반적으로 PHP에서 반환되는 오류 메시지는 개발자가 프로그램을 디버깅하는 데 도움이 될 수 있습니다. 이는 어떤 파일의 어떤 함수나 코드에 오류가 있는지 지적하고, 오류가 발생한 파일의 줄을 나타내는 정보입니다. 주다 . 많은 PHP 개발자는 show_source(), 하이라이트_문자열() 또는 하이라이트_파일() 함수를 사용하여 코드를 디버깅하지만, 라이브 웹사이트에서 이 접근 방식은 숨겨진 변수, 확인되지 않은 구문 및 기타 잠재적으로 위험한 시스템 보안 정보를 노출할 수 있습니다. 내부 디버깅 핸들러가 있거나 일반적인 디버깅 기술을 사용하는 프로그램을 실행하는 것은 위험합니다. 공격자가 프로그램에서 어떤 특정 디버깅 기술을 사용하는지 확인하면 디버깅 기능을 켜기 위해 변수를 보내려고 합니다.
예제 #2 변수를 사용하여 디버깅 기능 켜기
<form method="post" action="attacktarget?errors=Y&showerrors=1&debug=1"> <input type="hidden" name="errors" value="Y" /> <input type="hidden" name="showerrors" value="1" /> <input type="hidden" name="debug" value="1" /> </form>
오류 처리 메커니즘에 관계없이 시스템 오류를 감지하는 기능은 공격자에게 더 많은 정보를 제공합니다.
예를 들어, PHP의 고유한 오류 프롬프트 스타일은 시스템이 PHP를 실행 중임을 나타낼 수 있습니다. 공격자가 .html 페이지를 찾고 그 뒤에 숨은 기술을 알고 싶어하는 경우(시스템 약점을 찾기 위해) 잘못된 데이터를 제출한 다음 시스템이 PHP를 기반으로 한다는 것을 알게 됩니다.
단일 기능 오류로 인해 시스템에서 사용 중인 데이터베이스가 노출되거나 공격자에게 웹 페이지, 프로그램 또는 디자인에 대한 유용한 정보가 제공될 수 있습니다. 공격자는 종종 단서를 따라 열려 있는 데이터베이스 포트는 물론 페이지의 특정 버그나 약점을 찾습니다. 예를 들어, 공격자는 일부 비정상적인 데이터를 사용하여 프로그램 오류가 스크립트의 인증 순서(오류 프롬프트의 줄 번호를 통해)를 감지하도록 하고 스크립트의 다른 곳에서 유출될 수 있는 기타 정보를 유발할 수 있습니다.
파일 시스템이나 PHP 오류로 인해 웹 서버에 어떤 권한이 있는지, 서버에서 파일이 어떻게 구성되어 있는지가 드러날 수 있습니다. 이 문제는 개발자가 직접 작성한 잘못된 코드로 인해 악화될 수 있으며, 이로 인해 숨겨진 정보가 유출될 수 있습니다.
이러한 문제를 해결하는 일반적인 방법에는 세 가지가 있습니다. 첫 번째는 모든 기능을 철저하게 확인하고 대부분의 오류를 수정하도록 노력하는 것입니다. 두 번째는 온라인 시스템에 대한 오류 보고를 완전히 끄는 것입니다. 세 번째는 PHP의 사용자 정의 오류 처리 기능을 사용하여 자신만의 오류 처리 메커니즘을 만드는 것입니다. 보안 정책에 따라 세 가지 방법이 모두 적합할 수 있습니다.
이 문제가 발생하기 전에 예방하는 한 가지 방법은 error_reporting()을 사용하여 코드를 더 안전하게 만들고 위험한 변수 사용을 찾는 것입니다. 프로그램을 게시하기 전에 먼저 E_ALL 테스트 코드를 열어보세요. 그러면 부적절한 변수 사용을 빠르게 찾는 데 도움이 됩니다. 릴리스할 준비가 되면 error_reporting() 매개변수를 0으로 설정하여 오류 보고를 완전히 꺼야 합니다. 또는 php.ini의 display_errors를 off로 설정하여 모든 오류 표시를 꺼서 코드가 감지되지 않도록 해야 합니다. 물론 나중에 이 작업을 하고 싶다면 ini 파일에서 log_errors 옵션을 켜고 error_log를 통해 오류 정보를 기록하는 데 사용할 파일을 지정하는 것을 잊지 마세요.
예제 3 E_ALL을 사용하여 위험한 변수 찾기
<?php if ($username) { // Not initialized or checked before usage $good_login = 1; } if ($good_login == 1) { // If above test fails, not initialized or checked before usage readfile ("/highly/sensitive/data/index.html"); } ?>