중지!
당신은 여기서 실수를하고 있습니다. 아뇨, 데이터를 좀 더 안전하게 만들기 위해 올바른 PHP 기능을 선택했습니다. 괜찮아. 실수는 작업 순서 와 이러한 기능을 사용하는 방법 및 위치입니다.
사용자 데이터 삭제 및 유효성 검사, 스토리지 데이터 이스케이프 및 프리젠 테이션 데이터 이스케이프의 차이점을 이해하는 것이 중요합니다.
사용자 데이터 삭제 및 확인
사용자가 데이터를 제출할 때 원하는 것을 제공했는지 확인해야합니다.
살균 및 필터링
예를 들어 숫자 가 필요한 경우 제출 된 데이터가 숫자인지 확인하십시오 . 사용자 데이터 를 다른 유형으로 캐스트 할 수도 있습니다. 제출 된 모든 것은 처음에 문자열처럼 취급되므로 알려진 숫자 데이터를 정수 또는 부동 소수점으로 강제 설정하면 소독이 빠르고 고통스럽지 않습니다.
자유형 텍스트 필드와 텍스트 영역은 어떻습니까? 해당 필드에 예상치 못한 것이 없는지 확인해야합니다. 주로 HTML 내용이 없어야하는 필드에 실제로 HTML이 포함되어 있지 않은지 확인해야합니다. 이 문제를 처리 할 수있는 두 가지 방법이 있습니다.
먼저 HTML 입력을 빠져 나갈 수 있습니다.htmlspecialchars
. htmlentities
HTML을 중화 하는 데 사용해서는 안됩니다. HTML은 인코딩해야 할 것으로 생각되는 악센트 및 기타 문자의 인코딩도 수행합니다.
둘째, 가능한 HTML을 제거 할 수 있습니다 . strip_tags
빠르고 쉽고 빠르지 않습니다. HTML Purifier 는 모든 HTML을 제거하고 태그 및 속성의 선택적 화이트리스트를 허용하는 훨씬 철저한 작업을 수행합니다.
최신 PHP 버전은 에는 필터 확장 기능이 포함 되어있어 사용자 입력을 위생적으로 처리 할 수 있습니다.
확인
제출 된 데이터에 예기치 않은 컨텐츠가 없는지 확인하는 것은 작업의 절반에 불과합니다. 제출 된 데이터에 실제로 작업 할 수있는 값이 포함되어 있는지 확인해야합니다.
1에서 10 사이의 숫자를 예상하면 해당 값을 확인해야합니다. 스피너 및 단계와 함께 새로운 멋진 HTML5 시대 숫자 입력 중 하나를 사용하는 경우 제출 된 데이터가 단계와 일치하는지 확인하십시오.
해당 데이터가 드롭 다운 메뉴에서 가져온 것이면 제출 된 값이 메뉴에 나타나는 값인지 확인하십시오.
다른 요구를 충족시키는 텍스트 입력은 어떻습니까? 예를 들어 날짜 입력은 strtotime
또는 DateTime 클래스를 통해 확인해야합니다 . 주어진 날짜는 예상 범위 사이 여야합니다. 이메일 주소는 어떻습니까? 앞에서 언급 한 필터 확장 은 is_email 라이브러리 의 팬이지만 주소의 형식 이 올바른지 확인할 수 있습니다 .
다른 모든 폼 컨트롤에 대해서도 마찬가지입니다 . 라디오 버튼이 있습니까? 목록을 확인하십시오. 확인란이 있습니까? 목록을 확인하십시오. 파일 업로드가 있습니까? 파일이 예상 한 유형인지 확인하고 파일 이름을 필터링되지 않은 사용자 데이터처럼 취급하십시오.
모든 최신 브라우저에는 완벽한 개발자 도구 세트가 내장되어있어 누구나 양식을 조작하기가 쉽지 않습니다. 코드는 사용자가 양식 내용에 대한 모든 클라이언트 측 제한을 완전히 제거했다고 가정해야합니다 !
스토리지를위한 데이터 이스케이프
이제 데이터가 예상 형식으로되어 있고 예상 값만 포함되었으므로 해당 데이터를 스토리지에 유지하는 것에 대해 걱정할 필요가 있습니다.
모든 단일 데이터 저장 메커니즘에는 데이터가 올바르게 이스케이프 및 인코딩되도록하는 특정 방법이 있습니다. SQL을 작성하는 경우 쿼리에서 데이터를 전달하는 방법은 자리 표시자가있는 준비된 명령문을 사용하는 것 입니다.
PHP에서 대부분의 SQL 데이터베이스를 사용하는 더 좋은 방법 중 하나는 PDO 확장 입니다. 명령문 을 준비하고 , 변수를 명령문 에 바인딩 한 다음 , 명령문과 변수를 서버 로 보내는 일반적인 패턴을 따릅니다 . PDO로 작업하지 않은 경우 여기에 꽤 좋은 MySQL 지향 자습서가 있습니다. 있습니다.
일부 SQL 데이터베이스에는 SQL Server , PostgreSQL 및 SQLite 3 등 PHP에서 자체 특수 확장 기능이 있습니다. 이러한 각 확장은 PDO와 동일한 준비 결합 실행 방식으로 작동하는 명령문 지원을 준비했습니다. 비표준 기능이나 동작을 지원하기 위해 PDO 대신 이러한 확장을 사용해야 할 수도 있습니다.
MySQL에는 자체 PHP 확장이 있습니다. 사실 그 중 두 개입니다. mysqli 라는 것을 사용하고 싶습니다 . 이전 "mysql"확장은 더 이상 사용되지 않으며 현대에 사용하기에 안전하거나 제정신이 아닙니다.
나는 개인적으로 mysqli의 팬이 아니다. 준비된 명령문에서 변수 바인딩을 수행하는 방식은 융통성이 없으며 사용하기가 어려울 수 있습니다. 의심스러운 경우 대신 PDO를 사용하십시오.
SQL 데이터베이스를 사용하여 데이터를 저장하지 않는 경우 사용중인 데이터베이스 인터페이스의 설명서를 확인하여 데이터를 안전하게 전달하는 방법을 결정하십시오.
가능하면 데이터베이스가 데이터를 적절한 형식으로 저장해야합니다. 숫자를 숫자 필드에 저장하십시오. 날짜 필드에 날짜를 저장하십시오. 부동 소수점 필드가 아닌 10 진수 필드에 돈을 저장하십시오. 다른 데이터 유형을 올바르게 저장하는 방법에 대해서는 데이터베이스에서 제공 한 문서를 검토하십시오.
프리젠 테이션을위한 데이터 이스케이프
사용자에게 데이터를 표시 할 때마다 데이터가 이스케이프 되어서는 안된다는 것을 알지 않는 한 데이터가 안전하게 이스케이프 되어야합니다.
HTML을 생성 할 때는 거의 항상 원래 사용자가 제공 한 모든 데이터를 전달해야합니다. htmlspecialchars
. 사실, 당신이 때 당신이하지 말아야 할 유일한 시간입니다 알고 사용자가 HTML을 한 것으로, 당신은 것을 알고 이미 화이트리스트를 사용하여 소독하고 있다고.
때로는 PHP를 사용하여 자바 스크립트를 생성해야합니다. Javascript에는 HTML과 동일한 이스케이프 규칙이 없습니다! PHP를 통해 Javascript에 사용자 제공 값을 제공하는 안전한 방법은 json_encode
입니다.
그리고 더
데이터 유효성 검사에는 더 많은 뉘앙스가 있습니다.
예를 들어, 문자 세트 인코딩은 큰 함정일 수 있습니다 . 귀하의 신청서는 " UTF-8 전체 . 문자열 데이터를 잘못된 문자 세트로 취급 할 때 발생할 수있는 가상 공격이 있습니다.
이전에는 브라우저 디버그 도구에 대해 언급했습니다. 이 도구를 사용하여 쿠키 데이터를 조작 할 수도 있습니다. 쿠키는 신뢰할 수없는 사용자 입력으로 취급해야합니다 .
데이터 유효성 검사 및 이스케이프는 웹 응용 프로그램 보안의 한 측면 일뿐입니다. 웹 애플리케이션 공격 방법론을 숙지하여 이에 대한 방어 수단을 구축해야합니다.