주의: 사이트를 안전하지 않게 만들 수 있는 PHP 및 WordPress 기능

게시 됨: 2022-03-10
빠른 요약 ↬ WordPress에 새 플러그인을 배포하기 전에 오용하기 쉬운 기능 목록을 옆에 두는 것이 좋습니다. 보다 광범위한 보안 전략의 일부로 사용할 수 있고 사용해야 하는 몇 가지 기능을 자세히 살펴보겠습니다.

WordPress(또는 모든) 웹사이트의 보안은 다면적인 문제입니다. 사이트가 안전한지 확인하기 위해 누구나 취할 수 있는 가장 중요한 단계는 나쁜 일이 발생하지 않도록 하는 데 단일 프로세스나 방법만으로는 충분하지 않다는 점을 명심하는 것입니다. 하지만 당신이 도울 수 있는 일이 있습니다. 그 중 하나는 부정적인 결과를 초래할 수 있는 기능에 대해 귀하가 작성한 코드와 귀하가 배포한 다른 사람의 코드를 감시하는 것입니다. 이 기사에서는 WordPress 개발자가 사용하기 전에 명확하게 생각해야 하는 기능을 정확히 다룰 것입니다.

WordPress 자체는 상당한 수준의 기능 라이브러리를 제공하며 그 중 일부는 위험할 수 있습니다. 그 외에도 WordPress(PHP) 개발자가 사용할 때 위험할 수 있는 빈도로 사용하는 PHP 기능이 많이 있습니다.

이러한 모든 기능은 합법적이고 안전한 용도로 사용되지만 코드가 나쁜 목적으로 남용되기 쉽도록 만드는 기능이기도 합니다. 보안 취약점의 원인일 가능성이 가장 높은 항목과 이를 주의해야 하는 이유에 대해 설명합니다. 먼저 악의적인 행위자가 악의에 사용할 수 있는 코드의 PHP 함수를 실행한 다음 두통을 유발할 수 있는 WordPress 전용 PHP 함수에 대해 설명합니다.

주의해야 할 PHP 함수

우리가 말했듯이 PHP에는 사용하기 쉬운 많은 기능이 포함되어 있습니다. 이러한 기능 중 일부는 사람들이 쉽게 나쁜 일을 할 수 있는 것으로 악명이 높습니다. 이러한 모든 기능은 적절하게 사용되지만 사용 방법과 프로젝트에 끌어오는 다른 코드의 사용 방법에 대해 주의하십시오.

우리는 당신이 이미 마법의 따옴표를 가지고 있고 PHP 버전이 지원한다면 레지스터 전역이 꺼져 있다고 가정할 것입니다. PHP 5 이상에서는 기본적으로 꺼져 있지만 5.4 미만 버전에서는 켤 수 있습니다. 허용하는 호스트는 거의 없지만 PHP 보안 기사가 포함하지 않고는 진정으로 완전하다고 생각하지 않습니다.

점프 후 더! 아래에서 계속 읽기 ↓

또는 PHP 5.6이 보안 지원이 계속되는 마지막 5.x 버전이라는 언급도 있습니다. 당신은 적어도 그것에 있어야합니다. 그리고 2018년 말에 5.6 지원이 종료되기 전에 PHP 7로 이동할 계획이 있어야 합니다.

그 후에는 처리해야 할 몇 가지 위험한 기능만 갖게 됩니다. 로 시작…

extract 은 특히 $_POST 또는 이와 유사한 경우에 나쁜 소식입니다.

다행스럽게도 PHP의 extract 기능 사용은 대부분 인기가 떨어졌습니다. 사용의 핵심은 데이터 배열에서 실행할 수 있고 키-값 쌍이 코드에서 살아있는 변수가 된다는 것입니다. 그래서

 $arr = array( 'red' => 5 ); extract($arr); echo $red; // 5

작동 할 것이다. 이것은 멋지지만 $_GET , $_POST 등을 추출하는 경우에는 정말 위험합니다. 이 경우 본질적으로 register_globals 문제를 직접 재현하는 것입니다. 외부 공격자는 쿼리 문자열을 추가하여 변수 값을 쉽게 변경할 수 있습니다. 또는 양식 필드. 가장 좋은 해결책은 간단합니다. extract 를 사용하지 마십시오.

직접 추출한 배열을 생성하는 경우 extract 를 사용하는 것은 특별히 보안 문제가 아니며 경우에 따라 유용할 수 있습니다. 그러나 그것의 모든 사용은 미래의 독자들을 혼란스럽게 하는 문제를 가지고 있습니다. 배열을 만들고 extract 을 호출하는 것은 변수를 선언하는 것보다 더 혼란스럽습니다. 따라서 완전히 실행 불가능한 경우가 아니면 대신 수동 선언을 수행하는 것이 좋습니다.

사용자 입력에 대해 extract 을 사용해야 하는 경우 항상 EXTR_SKIP 플래그를 사용해야 합니다. 이것은 여전히 ​​혼란 문제가 있지만 간단한 쿼리 문자열이나 웹 양식 수정을 통해 악의적인 외부인이 미리 설정한 값을 변경할 수 있는 가능성을 제거합니다. (이미 설정된 값을 "건너뛰기" 때문입니다.)

임의의 코드가 무섭기 때문에 " eval 은 사악하다"

PHP의 eval 과 그것을 포함하는 거의 모든 다른 언어는 항상 이와 같은 목록에서 상위에 있습니다. 그리고 그럴만한 이유가 있습니다. PHP.net에 대한 PHP의 공식 문서는 매우 솔직하게 다음과 같이 말합니다.

주의 : eval() 언어 구조는 임의의 PHP 코드를 실행할 수 있기 때문에 매우 위험합니다. 따라서 사용을 권장하지 않습니다. 이 구성을 사용하는 것 외에 다른 옵션이 없음을 주의 깊게 확인한 경우 사용자가 제공한 데이터를 사전에 적절하게 검증하지 않고 전달하지 않도록 특히 주의하십시오.

eval 을 사용하면 프로그램의 임의의 문자열이 PHP 코드인 것처럼 실행할 수 있습니다. 즉, 스스로 프로그램을 빌드할 수 있는 프로그램을 빌드하는 "메타 프로그래밍"에 유용합니다. 또한 임의의 소스(웹 페이지의 텍스트 상자와 같은)가 eval 문자열 평가자에게 즉시 전달되도록 허용하면 갑자기 악의적인 공격자가 PHP가 할 수 있는 거의 모든 작업을 아주 쉽게 수행할 수 있기 때문에 매우 위험합니다. 서버에서 수행하십시오. 여기에는 분명히 데이터베이스 연결, 파일 삭제 및 SSH로 시스템에 연결할 때 다른 사람이 할 수 있는 모든 것이 포함됩니다. 이것은 나쁘다.

프로그램에서 eval 을 사용해야 하는 경우 임의의 사용자 입력이 프로그램에 전달되지 않도록 주의해야 합니다. 그리고 임의의 사용자가 eval 에 대한 입력에 액세스할 수 있도록 허용 해야 하는 경우 실행을 허용하지 않는 명령의 블랙리스트를 통해 수행할 수 있는 작업을 제한하거나 사용자가 실행할 수 있는 명령인 화이트리스트(구현하는 것이 더 낫지만 구현하기 훨씬 더 어렵습니다. 안전하다고 생각하십시오. 더 나은 방법은 검증된 정수와 같은 소수의 특정 매개변수 변경만 허용하는 것입니다.

그러나 PHP의 창시자인 Rasmus Lerdorf의 다음 구절을 항상 염두에 두십시오.

"`eval()`이 답이라면 거의 틀림없이 잘못된 질문을 하고 있는 것입니다."

eval 시 변형

잘 알려진 eval 외에도 PHP가 역사적으로 코드로 평가된 문자열을 지원한 다양한 다른 방법이 있습니다. WordPress 개발자와 가장 관련이 있는 두 가지는 preg_replace /e 수정자와 create_function 입니다. 각각은 약간 다르게 작동하며 PHP 5.5.0 이후에는 preg_replace 가 전혀 작동하지 않습니다. (PHP 5.5 이하 버전은 더 이상 공식 보안 업데이트를 받지 않으므로 사용하지 않는 것이 좋습니다.)

/e 정규식의 수정자도 "악"입니다.

PHP 5.4.x 이하를 실행하는 경우 e로 끝나는 PHP preg_replace 호출을 주시해야 합니다. 다음과 같이 보일 수 있습니다.

 $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );) $html = preg_replace( '( (.*?) )e', '" " . strtoupper("$2") . " "', $html );) // or $html = preg_replace( '~ (.*?) ~e', '" " . strtoupper("$2") . " "', $html );)

PHP는 정규식에서 "펜스"하는 다양한 방법을 제공하지만, 주의해야 할 핵심은 preg_replace 의 첫 번째 인수에 대한 마지막 문자인 "e"입니다. 그것이 있다면 실제로 발견된 전체 세그먼트를 인라인 PHP에 대한 인수로 전달한 다음 eval 하는 것입니다. 사용자 입력이 함수에 들어가도록 허용하는 경우 eval 과 똑같은 문제가 있습니다. 예제 코드는 대신 preg_replace_callback 을 사용하여 대체할 수 있습니다. 이것의 장점은 함수를 작성했기 때문에 공격자가 평가 대상을 변경하기가 더 어렵다는 것입니다. 따라서 위와 같이 작성하면 됩니다.

 // uppercase headings $html = preg_replace_callback( '( (.*?) )', function ($m) { return " " . strtoupper($m[2]) . " "; }, $html ); // uppercase headings $html = preg_replace_callback( '( (.*?) )', function ($m) { return " " . strtoupper($m[2]) . " "; }, $html ); // uppercase headings $html = preg_replace_callback( '( (.*?) )', function ($m) { return " " . strtoupper($m[2]) . " "; }, $html ); // uppercase headings $html = preg_replace_callback( '( (.*?) )', function ($m) { return " " . strtoupper($m[2]) . " "; }, $html ); // uppercase headings $html = preg_replace_callback( '( (.*?) )', function ($m) { return " " . strtoupper($m[2]) . " "; }, $html );

사용자 입력 create_function s도 나쁘다…

PHP에는 create_function 함수도 있습니다. 이것은 이제 PHP 7.2에서 더 이상 사용되지 않지만 eval 과 매우 유사하고 동일한 기본 단점이 있습니다. 문자열(두 번째 인수)을 실행 가능한 PHP로 변환할 수 있습니다. 그리고 동일한 위험이 있었습니다. 주의하지 않으면 실수로 스마트 크래커에게 서버에서 모든 작업을 수행할 수 있는 기능을 부여하기가 너무 쉽습니다.

이것은 PHP 5.3 이상을 사용하는 경우 preg_replace 보다 수정하기가 훨씬 쉽습니다. 문자열을 중개자로 사용하지 않고 고유한 익명 함수를 만들 수 있습니다. 이것은 적어도 내 눈에는 더 안전하고 읽기 쉽습니다.

assert is also eval -like

assert 는 WordPress 안팎에서 많은 PHP 개발자가 사용하는 기능이 아닙니다. 그 의도는 코드의 전제 조건에 대한 매우 가벼운 주장을 위한 것입니다. 그러나 eval 유형 작업도 지원합니다. 그렇기 때문에 eval 만큼이나 조심해야 합니다. 문자열 기반 주장(이것이 나쁜 이유의 핵심)도 PHP 7.2에서 더 이상 사용되지 않습니다.

변수 파일을 포함하는 것은 제어되지 않은 PHP 실행을 가능하게 하는 방법입니다

우리는 eval 이 왜 나쁜지 꽤 잘 탐구했지만, include 또는 require($filename'.php') 와 같은 것이, 특히 $filename 이 사용자가 제어할 수 있는 값에서 설정되는 경우 비슷하게 나쁜 소식이 될 수 있습니다. 그 이유는 eval 과 미묘하게 다릅니다. 가변 파일 이름은 WordPress가 아닌 PHP 앱에서 간단한 URL-to-file 라우팅과 같은 용도로 자주 사용됩니다. 그러나 WordPress에서도 사용되는 것을 볼 수 있습니다.

문제의 핵심은 include 하거나 require 때(또는 include_once 또는 require_once ) 스크립트가 포함된 파일을 실행하게 한다는 것입니다. 우리가 그런 식으로 생각하는 경우는 거의 없지만 개념적으로 그 파일을 eval 하고 있습니다.

변수가 include 할 수 있는 모든 파일을 작성했고 그럴 때 어떤 일이 일어날지 고려했다면 문제가 없습니다. 그러나 password.php 또는 wp-config.phpinclude 하는 것이 무엇을 할 것인지 고려하지 않았다면 나쁜 소식입니다. 누군가가 악의적인 파일을 추가한 다음 include 을 실행할 수 있는 경우에도 나쁜 소식입니다.

이에 대한 해결책은 그리 어렵지 않습니다. 하드 코드에는 가능한 경우가 포함됩니다. 할 수 없는 경우 포함할 수 있는 파일의 화이트리스트(더 나은) 또는 블랙리스트를 만드십시오. 화이트리스트에 있는 파일(즉, 추가 시 파일이 수행하는 작업을 감사한 경우)인 경우 안전하다는 것을 알 수 있습니다. 화이트리스트에 없으면 스크립트에 포함되지 않습니다. 그 간단한 조정으로, 당신은 꽤 안전합니다. 화이트리스트는 다음과 같습니다.

 $white_list = ['db.php', filter.php', 'condense.php'] If (in_array($white_list, $file_to_include)) { include($file_to_include); }

사용자 입력을 shell_exec 및 변형에 전달하지 마십시오.

이것은 큰 것입니다. PHP의 shell_exec , system , exec 및 백틱은 모두 실행 중인 코드가 기본(일반적으로 Unix) 셸과 통신할 수 있도록 합니다. 이것은 eval 을 위험하게 만드는 것과 유사하지만 두 배입니다. 여기에서 부주의하게 사용자 입력을 허용하면 공격자가 PHP의 제약 조건에 얽매이지 않기 때문에 두 배가 됩니다.

PHP에서 쉘 명령을 실행하는 기능은 개발자로서 매우 유용할 수 있습니다. 그러나 거기에 사용자의 입력을 허용하면 비밀리에 많은 위험한 힘을 얻을 수 있습니다. 그래서 나는 사용자 입력이 결코 shell_exec -type 함수에 전달되어서는 안된다고 말할 정도입니다.

이러한 유형의 상황을 처리하기 위해 생각할 수 있는 가장 좋은 방법은 구현하려는 경우 사용자에게 알려진 안전한 미리 정의된 셸 명령의 작은 집합에 대한 액세스를 제공하는 것입니다. 확보할 수 있는 것일 수 있습니다. 그러나 그때에도 나는 당신에게 매우 조심하라고 경고하고 싶습니다.

unserialize 를 확인하십시오. 코드를 자동으로 실행합니다.

살아있는 PHP 객체에 대해 serialize 를 호출하고 해당 데이터를 어딘가에 저장한 다음 나중에 저장된 값을 사용하여 해당 객체를 다시 unserialize 해제하는 핵심 작업은 훌륭합니다. 또한 합리적으로 일반적이지만 위험할 수 있습니다. 왜 위험한가? 해당 unserialize 호출에 대한 입력이 완전히 안전하지 않은 경우(데이터베이스가 아닌 쿠키로 저장된다고 가정해 보겠습니다...), 공격자는 unserialize 호출이 잘못된 작업을 수행하도록 하는 방식으로 개체의 내부 상태를 변경할 수 있습니다.

이 익스플로잇은 eval 문제보다 더 난해하고 눈에 띄지 않습니다. 그러나 직렬화된 데이터의 저장 메커니즘으로 쿠키를 사용하는 경우 해당 데이터에 대해 serialize 를 사용하지 마십시오. json_encodejson_decode 와 같은 것을 사용하십시오. 이 두 PHP를 사용하면 어떤 코드도 자동으로 실행되지 않습니다.

여기서 핵심 취약점은 PHP가 sa 문자열을 클래스로 unserialize 해제할 때 해당 클래스에서 매직 __wakeup 메서드를 호출한다는 것입니다. 검증되지 않은 사용자 입력이 unserialized 해제되도록 허용되면 __wakeup 메서드에서 데이터베이스 호출이나 파일 삭제와 같은 작업이 잠재적으로 위험하거나 바람직하지 않은 위치를 가리킬 수 있습니다.

unserialize 는 객체에 매직 메서드를 사용해야 하기 때문에 eval 취약점과 다릅니다. 공격자는 자신의 코드를 만드는 대신 개체에 대해 이미 작성된 메서드를 남용해야 합니다. 이 OWASP Wiki 페이지에서 설명하는 것처럼 객체에 대한 __destruct__toString 매직 메서드도 위험합니다.

일반적으로 클래스에서 __wakeup , __destruct 또는 __toString 메서드를 사용하지 않아도 괜찮습니다. 그러나 나중에 누군가가 클래스에 추가하는 것을 볼 수 있기 때문에 JSON( json_encodejson_decode )과 같은 것을 통해 serializeunserialize 및 모든 공개 데이터를 전달하는 호출 근처에 사용자를 허용하지 않는 것이 좋습니다. 자동 코드 실행이 아닙니다.

file_get_contents 로 URL을 가져오는 것은 위험합니다.

외부 URL을 호출해야 하는 일부 PHP 코드를 빠르게 작성할 때 일반적인 방법은 file_get_contents 에 도달하는 것입니다. 빠르고 쉽지만 보안이 매우 뛰어나지는 않습니다.

file_get_contents 의 문제는 미묘하지만 호스트가 때때로 외부 URL에 액세스하는 것을 허용하지 않도록 PHP를 구성하는 경우가 많습니다. 이것은 당신을 보호하기 위한 것입니다.

여기서 문제는 file_get_contents 가 원격 페이지를 가져올 것이라는 점입니다. 그러나 그렇게 할 때 HTTPS 프로토콜 연결의 무결성을 확인하지 않습니다. 이것이 의미하는 바는 공격자가 원하는 모든 것을 file_get_contents 페이지 결과에 넣을 수 있는 메시지 가로채기(man-in-the-middle) 공격의 희생자가 스크립트가 될 수 있다는 의미입니다.

이것은 더 난해한 공격입니다. 그러나 최신(컴포저 기반) PHP를 작성할 때 이를 방지하기 위해 거의 항상 Guzzle을 사용하여 보다 안전한 cURL API를 래핑합니다. WordPress에서는 훨씬 더 쉽습니다. wp_remote_get 을 사용하세요. file_get_contents 보다 훨씬 일관되게 작동하며 기본적으로 SSL 연결을 확인합니다. (그것을 끌 수는 있지만, 음, 아마도 하지 않을 수도 있습니다...) 더 나은 방법이지만 이야기하기에는 약간 더 짜증나는 wp_safe_remote_get 등이 있습니다. 이들은 이름에 safe_ 가 없는 함수와 동일하게 작동하지만, 안전하지 않은 리디렉션 및 전달이 도중에 발생하지 않도록 합니다.

filter_var URL 유효성 검사를 맹목적으로 신뢰하지 마십시오.

이것은 다소 모호하므로 이 WordCamp 강연에서 설명하기 위해 Chris Weigman에게 소품을 제공합니다. 일반적으로 PHP의 filter_var 는 데이터를 검증하거나 삭제하는 좋은 방법입니다. (하지만 무엇을 하려고 하는지 혼동하지 마세요...)

여기서 문제는 매우 구체적입니다. URL이 안전한지 확인하기 위해 사용하려는 경우 filter_var 는 프로토콜의 유효성을 검사하지 않습니다. 이것은 자주 문제가 되지는 않지만 유효성 검사를 위해 이 메서드에 사용자 입력을 전달하고 FILTER_VALIDATE_URL 을 사용하는 경우 javascript://comment%0aalert(1) 와 같은 것이 통과합니다. 즉, 이것은 예상하지 못한 곳에서 기본적인 XSS 공격을 위한 매우 좋은 벡터가 될 수 있습니다.

URL 유효성 검사를 위해 WordPress의 esc_url 기능은 유사한 영향을 미치지만 허용된 프로토콜을 통해서만 허용합니다. javascript 는 기본 목록에 없으므로 안전하게 유지됩니다. 그러나 filter_var 와 달리 허용되지 않는 프로토콜이 전달되면 빈 문자열(거짓 아님)을 반환합니다.

주목해야 할 WordPress 전용 기능

잠재적으로 취약한 핵심 PHP 기능 외에도 약간의 문제가 될 수 있는 일부 WordPress 관련 기능이 있습니다. 이들 중 일부는 위에 나열된 다양한 위험한 기능과 매우 유사하고 일부는 약간 다릅니다.

WordPress는 maybe_unserialize 를 사용하여 직렬화 해제합니다.

이것은 위의 내용을 읽어보면 분명합니다. 워드프레스에는 maybe_unserialize 라는 함수가 있으며, 짐작할 수 있듯이 필요한 경우 전달된 내용을 직렬화 해제합니다.

이것이 도입하는 새로운 취약점은 없습니다. 문제는 단순히 핵심 unserialize 기능과 마찬가지로 이 취약점으로 인해 직렬화 해제될 때 취약한 개체가 악용될 수 있다는 것입니다.

사용자가 관리자인 경우 is_admin 이 응답하지 않습니다!

이것은 매우 간단하지만 기능이 모호하기 때문에 사람들을 혼란스럽게 하거나 바쁠 경우 놓칠 수 있습니다. WordPress에서 작업을 수행하려는 사용자에게 해당 작업을 수행하는 데 필요한 권한이 있는지 항상 확인해야 합니다. 그러려면 current_user_can 함수를 사용해야 합니다.

그러나 현재 사용자가 관리자 수준 계정인지 여부를 is_admin 이 알려주고 따라서 플러그인이 사용하는 옵션을 설정할 수 있어야 한다고 잘못 생각할 수도 있습니다. 이것은 실수입니다. 워드프레스에서 is_admin 이 하는 일은 대신 현재 페이지 로드가 사이트의 관리 측에 있는지(프론트 측에 있는지) 알려주는 것입니다. 따라서 관리 페이지(예: "대시보드")에 액세스할 수 있는 모든 사용자는 잠재적으로 이 검사를 통과할 수 있습니다. is_admin 이 현재 사용자가 아니라 페이지 유형에 관한 것임을 기억하는 한 괜찮을 것입니다.

add_query_arg() 는 URL을 삭제하지 않습니다.

이것은 흔하지 않지만 이 기능에 대한 공개 문서가 올바르지 않았기 때문에 몇 년 전에 WordPress 생태계에 큰 업데이트 물결이 있었습니다. 핵심 문제는 add_query_arg 함수(및 그 역 remove_query_arg )가 URL이 전달되지 않은 경우 사이트 URL을 자동으로 삭제하지 않고 사람들이 그렇게 생각했다는 것입니다. 많은 플러그인이 Codex에 의해 잘못 인도되었고 결과적으로 이것을 안전하지 않게 사용하고 있었습니다.

그들이 다르게 해야 하는 핵심 사항은 이 함수를 사용하기 전에 호출 결과를 정리하는 것입니다. 그렇게 하면 생각했던 XSS 공격으로부터 정말 안전합니다. 그래서 다음과 같이 보입니다.

 echo esc_url( add_query_arg( 'foo', 'bar' ) );

$wpdb->query() 가 SQL 주입 공격에 노출됨

SQL 인젝션에 대해 알고 있다면 이것은 어리석게 보일 수 있으며 나열하는 것은 불필요합니다. 문제는 SQL 주입 공격을 허용하는 데이터베이스 쿼리를 생성하기 위해 어떤 방식으로든 데이터베이스에 액세스하기 때문입니다(예: PHP의 mysqli 또는 PDO 데이터베이스 드라이버 사용).

내가 구체적으로 $wpdb->query 를 호출하는 이유는 $ $wpdb 에 대한 일부 다른 메소드(예: insert , delete 등)가 주입 공격을 처리하기 때문입니다. 또한 WP_Query 등을 사용하여 기본 WordPress 데이터베이스 쿼리를 만드는 데 익숙하다면 SQL 주입을 고려할 필요가 없습니다. 이것이 내가 이것을 부르는 이유입니다. $wpdb 를 사용하여 자신의 쿼리를 처음 만들려고 할 때 데이터베이스에 대한 주입 공격이 가능하다는 것을 이해했는지 확인하십시오.

무엇을 할까요? $wpdb->prepare() 를 사용한 다음 $wpdb->query() 를 사용하십시오. 또한 get_row()get_var() ) 와 같은 $wpdb 의 다른 "가져오기" 메서드보다 먼저 준비해야 합니다. 그렇지 않으면 Bobby Tables가 당신을 얻을 수 있습니다.

esc_sql 은 SQL 주입으로부터 당신을 보호하지 않습니다

대부분의 WordPress 개발자의 경우 esc_sql 이 어떤 의미로도 등록되지 않지만 등록해야 합니다. 방금 언급했듯이 데이터베이스 쿼리를 작성하기 전에 wpdb->prepare() 를 사용해야 합니다. 이것은 당신을 안전하게 유지합니다. 그러나 개발자가 대신 esc_sql 에 접근할 수 있다는 것은 매력적이며 이해할 수 있습니다. 그리고 그들은 그것이 안전할 것이라고 기대할 수도 있습니다.

문제는 esc_sql 이 SQL 주입에 대한 강력한 보호 기능을 갖고 있지 않다는 것입니다. 이것은 실제로 PHP의 add_slashes 함수의 영광스러운 버전으로, 수년 동안 데이터베이스를 보호하기 위해 사용하는 것을 꺼려왔습니다.

할 일이 더 있지만 이것은 큰 시작입니다

공격자가 오용할 수 있는 코드의 기능을 감시하는 것보다 보안에 더 많은 것이 있습니다. 예를 들어 우리는 사용자로부터 받은 모든 데이터를 검증 및 삭제하고 웹페이지에 넣기 전에 이스케이프해야 할 필요성에 대해 깊이 논의하지 않았습니다(최근에 "WordPress 보호 사이트 간 스크립팅 공격에 대한 사이트”). 그러나 이를 보다 광범위한 보안 전략의 일부로 사용할 수 있고 사용해야 합니다.

WordPress에 새 플러그인을 배포하기 전에 최종 검사를 할 때 오용하기 쉬운 기능 목록을 옆에 두는 것이 좋습니다. 그러나 호스팅의 보안을 신뢰하고 사용자에게 좋은 암호가 있는지 확인하는 등의 작업도 원할 것입니다.

보안에 대해 기억해야 할 핵심은 가장 약한 링크가 중요한 링크라는 것입니다. 한 분야의 좋은 관행은 다른 곳의 가능한 약점을 강화하지만 완전히 고칠 수는 없습니다. 그러나 이러한 기능에 주의하면 대부분의 기능을 사용할 수 있습니다.