>  기사  >  백엔드 개발  >  PHP에서 SQL 주입 공격을 방지하는 방법 소개

PHP에서 SQL 주입 공격을 방지하는 방법 소개

不言
不言앞으로
2018-11-24 15:17:362332검색

이 글은 PHP에서 SQL 인젝션 공격을 종합적으로 차단하는 방법을 소개한 글입니다. 도움이 필요한 친구들이 참고하시면 좋겠습니다.

공격 동기의 종류는 다양할 수 있지만 얼핏 보면 더 많은 종류가 있는 것 같습니다. 이는 매우 사실입니다. 악의적인 사용자가 여러 쿼리를 수행하는 방법을 찾는 경우입니다.

스크립트가 SELECT 명령을 실행하는 경우 공격자는 아래와 같이 WHERE 절에 "1=1"과 같은 조건을 삽입하여 테이블의 각 레코드 행을 강제로 표시할 수 있습니다. 굵게 표시됨):

SELECT * FROM wines WHERE variety = 'lagrein' OR 1=1;'

앞서 설명했듯이 이는 테이블의 일반적인 구조(일반 레코드에서는 할 수 없는)를 공개하고 잠재적으로 기밀 정보가 포함된 레코드를 공개하므로 그 자체로 유용한 정보일 수 있습니다.

업데이트 명령은 잠재적으로 더 직접적인 위협을 가할 수 있습니다. SET 절에 다른 특성을 입력함으로써 공격자는 다음 예(주입된 부분이 굵게 표시됨)와 같이 업데이트되는 레코드의 모든 필드를 수정할 수 있습니다.

UPDATE wines SET type='red','vintage'='9999' WHERE variety = 'lagrein'

예제 변경 1 상수 업데이트 명령의 WHERE 절에 =1과 같은 진실 조건이 추가됩니다. 이 수정 범위는 다음 예(주입된 부분이 굵게 표시됨)와 같이 모든 레코드로 확장될 수 있습니다.

UPDATE wines SET type='red','vintage'='9999 WHERE variety = 'lagrein' OR 1=1;'

가장 위험한 명령은 DELETE일 수 있습니다. 상상하기 어렵지 않습니다. 주입 기술은 우리가 이미 본 것과 동일합니다. 아래 예(삽입된 부분은 굵게 표시됨)와 같이 WHERE 절을 수정하여 영향을 받는 레코드의 범위를 확장합니다.

DELETE FROM wines WHERE variety = 'lagrein' OR 1=1;'

다중 쿼리 주입

다중 쿼리 주입은 단일 쿼리에 여러 개의 파괴적인 명령을 포함할 수 있도록 하여 공격자가 초래할 수 있는 잠재적 피해를 줄입니다. MySQL 데이터베이스를 사용할 때 공격자는 쿼리에 예기치 않은 중지 문자를 삽입하여 이를 쉽게 수행할 수 있습니다. 이제 삽입된 따옴표(단일 또는 이중)는 원하는 변수의 끝을 표시합니다. 그런 다음 명령을 세미콜론으로 종료합니다. 이제 중지된 원래 명령 뒤에 추가 공격 명령이 추가될 수 있습니다. 최종 파괴적인 쿼리는 다음과 같습니다.

SELECT 
 FROM wines WHERE variety = 'lagrein';GRANT ALL ON 
.* TO 'BadGuy@%' IDENTIFIED BY 'gotcha';'

이 주입은 새로운 사용자 BadGuy를 생성하고 이 사용자에게 네트워크 권한(모든 테이블에 대한 모든 권한)을 부여합니다. 또한 "불길한" 암호가 이 간단한 SELECT에 추가됩니다. 문장. 이전 기사의 조언을 따르고 프로세스 사용자의 권한을 엄격하게 제한한 경우 웹 서버 데몬에는 취소한 GRANT 권한이 더 이상 없기 때문에 이 방법은 작동하지 않습니다. 그러나 이론적으로 이러한 공격을 통해 BadGuy는 데이터베이스를 사용하여 원하는 모든 작업을 자유롭게 수행할 수 있습니다.

이러한 다중 쿼리가 MySQL 서버에서 처리되는지 여부에 대한 결론은 고유하지 않습니다. 일부 이유는 MySQL의 버전이 다르기 때문일 수 있지만 대부분은 여러 쿼리가 존재하는 방식 때문입니다. MySQL의 모니터링 프로그램은 이러한 쿼리를 완벽하게 허용합니다. 일반적으로 사용되는 MySQL GUI-phpMyAdmin은 최종 쿼리 이전의 모든 이전 내용을 복사하고 이 작업만 수행합니다.

그러나 주입 컨텍스트에서 대부분의 다중 쿼리는 PHP의 mysql 확장으로 관리됩니다. 다행스럽게도 기본적으로 쿼리에서 여러 명령을 실행하는 것을 허용하지 않습니다. 두 명령(예: 위에 표시된 주입)을 실행하려고 하면 오류가 발생하지 않으며 출력 정보도 생성되지 않습니다. 이 경우 PHP는 기본 동작을 "정기적으로"만 구현하지만 실제로 대부분의 간단한 주입 공격으로부터 사용자를 보호할 수 있습니다.

mysql과 마찬가지로 PHP5의 새로운 mysqli 확장(http://php.net/mysqli 참조)은 본질적으로 다중 쿼리를 지원하지 않지만 다중 쿼리 완료를 지원하는 mysqli_multi_query() 함수를 제공합니다. 당신은 정말로 그렇게 하고 싶어해요.
그러나 상황은 SQLite(PHP5와 함께 번들로 제공되는 내장형 SQL 데이터베이스 엔진(http://sqlite.org/ 및 http://php.net/sqlite 참조))의 사용 편의성으로 인해 더욱 심각합니다. 많은 유저들의 관심을 부탁드립니다. 어떤 경우에는 데이터베이스가 일괄 쿼리, 특히 일괄 INSERT 문 처리를 매우 효율적으로 최적화할 수 있기 때문에 SQLite는 기본적으로 이러한 다중 명령 쿼리를 허용합니다.

그러나 쿼리 결과가 스크립트에서 사용되는 경우(예: SELECT 문장을 사용하여 레코드를 검색하는 경우) sqlite_query() 함수는 여러 쿼리 실행을 허용하지 않습니다.

3. INVISION Power BOARD SQL 주입 취약점

Invision Power Board는 잘 알려진 포럼 시스템입니다. 2005년 5월 6일 로그인 코드에서 SQL 주입 취약점이 발견되었습니다. GulfTech Security Research의 James Bercegay가 발견했습니다.

이 로그인 쿼리는 다음과 같습니다.

$DB->query("SELECT * FROM ibf_members WHERE id=$mid AND password='$pid'");

한편, 회원 ID 변수 $mid와 비밀번호 ID 변수 $pid는 다음 두 줄의 코드를 사용하여 my_cookie() 함수에서 검색됩니다.

$mid = intval($std->my_getcookie('member_id'));$pid = $std->my_getcookie('pass_hash');

여기서는 my_cookie () 함수 다음 문장을 사용하여 쿠키에서 요청된 변수를 검색합니다.

return urldecode($_cookie[$ibforums->vars['cookie_id'].$name]);

【留意】从该cookie回来的值底子没有被处理。虽然$mid在运用于查询之前被强制转换成一个整数,可是$pid却保持不变。因而,它很容易遭受咱们前面所评论的注入类型的进犯。

因而,经过以如下方法修正my_cookie()函数,这种软弱性就会露出出来:

if ( ! in_array( $name,array('topicsread', 'forum_read','collapseprefs') ) )
{
return $this->
clean_value(urldecode($_cookie[$ibforums->vars['cookie_id'].$name]));
}
else
{
return urldecode($_cookie[$ibforums->vars['cookie_id'].$name]);
}

经过这样的改正之后,其间的要害变量在"经过"全局clean_value()函数后被回来,而其它变量却未进行检查。
现在,已然咱们大致了解了什么是SQL注入,它的注入原理以及这种注入的软弱程度,那么接下来,让咱们探讨如何有用地防备它。幸亏,PHP为咱们供给了丰厚的资源,因而咱们有充沛的信心预言,一个经细心地彻底地运用咱们所引荐的技能构建的应用程序将会从你的脚本中底子上消除任何或许性的SQL注入-经过在它或许形成任何损坏之前"整理"你的用户的数据来完成。

위 내용은 PHP에서 SQL 주입 공격을 방지하는 방법 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제