PHP 보안 규칙
PHP Safe 검사기가 확인하는 18가지 규칙입니다. 규칙마다 취약한 예시, 안전한 해결 방법, CWE·OWASP 표준 번호를 함께 제공합니다.
인젝션 8
변수로 만든 SQL (SQL 인젝션)
입력값을 SQL에 직접 붙이면 공격자가 쿼리 자체를 바꿔서 DB의 모든 데이터를 읽거나 수정·삭제할 수 있습니다. prepared statement는 쿼리와 값을 따로 보내기 때문에 입력값이 SQL로 바뀔 수 없습니다.
자세히 →쉘 명령어 실행
쉘에 전달된 입력값에 ; 나 | 같은 문자를 넣으면 다른 명령어를 덧붙일 수 있어, 공격자가 서버를 장악하게 됩니다. 값을 엄격하게 검증하고 모든 인자를 escapeshellarg()로 감싸세요.
자세히 →eval()로 코드 실행
eval()은 받은 문자열을 PHP 코드로 그대로 실행합니다. 그 일부라도 요청에서 온 값이면 공격자가 서버에서 자기 코드를 실행할 수 있습니다.
자세히 →preg_replace의 /e 수정자
/e 수정자는 치환 문자열을 PHP 코드로 실행합니다. PHP 7에서 삭제되었기 때문에 아직 쓰고 있다면 오래된 서버에서는 위험하고 최신 서버에서는 동작하지 않습니다.
자세히 →사용자 입력으로 파일 include
요청 값으로 include 경로를 만들면 공격자가 시스템 파일, PHP가 숨겨진 업로드 이미지, 외부 코드를 불러올 수 있습니다. 서버 전체가 장악되는 가장 빠른 경로 중 하나입니다.
자세히 →변수로 만든 include 경로
변수로 만든 include 경로는 그 변수에 사용자 입력이 절대 들어가지 않을 때만 안전합니다. 위쪽 코드에서 요청 값이 흘러드는 경우가 많으니 꼭 확인하세요.
자세히 →신뢰할 수 없는 데이터에 unserialize()
unserialize()는 어떤 객체든 만들 수 있어서, 공격자가 기존 클래스들을 연결해(가젯 체인) 파일을 지우거나 코드를 실행할 수 있습니다. JSON은 단순한 데이터만 만듭니다.
자세히 →요청 데이터에 extract()
extract()는 요청의 모든 필드를 변수로 만들기 때문에, 공격자가 폼에 필드 하나만 추가해도 $is_admin 같은 변수를 덮어쓸 수 있습니다.
자세히 →출력·리다이렉트 2
파일·업로드 2
암호화·통신 3
md5() 또는 sha1() 사용
md5와 sha1은 계산이 빨라서 유출된 비밀번호 해시를 초당 수십억 번씩 대입해 풀 수 있습니다. password_hash()는 일부러 느리게 동작하고 솔트가 들어갑니다.
자세히 →예측 가능한 난수
rand(), mt_rand(), uniqid()는 예측할 수 있습니다. 비밀번호 재설정, 세션, CSRF 토큰은 반드시 암호학적으로 안전한 난수로 만들어야 합니다.
자세히 →SSL 인증서 검증 꺼짐
인증서 검증을 끄면 네트워크 중간에 있는 누구나 호출하는 API인 척하며 API 키를 포함한 데이터를 엿보거나 바꿀 수 있습니다.
자세히 →