> 백엔드 개발 > PHP 튜토리얼 > PHP의 SQL 주입 공격에 대한 완전한 금지 중 하나

PHP의 SQL 주입 공격에 대한 완전한 금지 중 하나

黄舟
풀어 주다: 2023-03-04 08:34:01
원래의
905명이 탐색했습니다.

이번 시리즈에서는 PHP 개발 환경에서 SQL 인젝션 공격을 완전히 금지하는 방법을 종합적으로 논의하고 구체적인 개발 사례를 제시하겠습니다.

1. 소개

PHP는 강력하지만 배우기 쉬운 서버 측 스크립팅 언어입니다. 경험이 부족한 프로그래머라도 이를 사용하여 복잡하고 동적인 웹 사이트를 만들 수 있습니다. 그러나 인터넷 서비스의 기밀성 및 보안을 달성하는 데 많은 어려움을 겪는 경우가 많습니다. 이 기사 시리즈에서는 웹 개발에 필요한 보안 배경은 물론 PHP 관련 지식 및 코드를 소개합니다. 이를 사용하여 웹 애플리케이션의 보안과 일관성을 보호할 수 있습니다. 먼저, 서버 보안 문제를 간략하게 검토하여 공유 호스팅 환경에서 개인 정보에 액세스하고, 개발자가 프로덕션 서버에 접근하지 못하게 하고, 소프트웨어를 최신 상태로 유지하고, 암호화된 채널을 제공하고, 시스템 액세스에 대한 액세스를 제어하는 ​​방법을 보여줍니다.

그런 다음 PHP 스크립트 구현에 널리 퍼져 있는 취약점에 대해 논의합니다. SQL 주입으로부터 스크립트를 보호하고, 사이트 간 스크립팅 및 원격 실행을 방지하고, 임시 파일 및 세션의 '하이재킹'을 비활성화하는 방법을 설명합니다.

지난 글에서는 보안 웹 익스플로잇을 구현해보겠습니다. 사용자를 인증하고, 애플리케이션을 승인 및 추적하고, 데이터 손실을 방지하고, 고위험 시스템 명령을 안전하게 실행하고, 웹 서비스를 안전하게 사용하는 방법을 배우게 됩니다. PHP 보안 개발에 대한 충분한 경험이 있는지 여부에 관계없이 이 기사 시리즈는 보다 안전한 온라인 애플리케이션을 구축하는 데 도움이 되는 풍부한 정보를 제공합니다.

2. SQL 주입이란

특정 데이터를 절대 사용하지 않을 계획이라면 데이터베이스에 쉽게 접근하고 조작할 수 있도록 설계되어 있으므로 데이터베이스에 저장할 의미가 없습니다. 데이터베이스에서. 하지만 이렇게만 하면 잠재적인 재난으로 이어질 수도 있습니다. 이 상황은 중요하지 않습니다. 실수로 데이터베이스의 모든 항목을 삭제할 수 있기 때문입니다. 일부 '순진한' 작업을 완료하려고 하는 동안 누군가에 의해 '탈취'될 수 있기 때문입니다. 즉, 애플리케이션 자체가 자신의 데이터를 대체하기 위해 손상되었습니다. 데이터. 우리는 이것을 '주입'이라고 부릅니다.

실제로 데이터베이스 쿼리를 구성하기 위해 사용자에게 입력을 요청할 때마다 사용자가 데이터베이스 서버에 액세스하는 명령 구성에 참여하도록 허용하는 것입니다. 친숙한 사용자는 그러한 제어를 달성하는 데 만족할 수 있지만, 악의적인 사용자는 명령을 왜곡하는 방법을 고안하여 왜곡된 명령이 데이터를 삭제하거나 심지어 더 위험한 작업을 수행하도록 할 것입니다. 프로그래머로서 귀하의 임무는 그러한 악의적인 공격을 피할 수 있는 방법을 찾는 것입니다.

3. SQL 삽입 작동 방식

데이터베이스 쿼리를 구성하는 과정은 매우 간단합니다. 일반적으로 다음 라인을 따라 구현됩니다. 제목을 명확히 하기 위해 'variety'(예: 와인 유형) 필드가 포함된 와인 데이터베이스 테이블 'wines'가 있다고 가정합니다.

1. 양식 제공 - 허용 사용자는 검색할 특정 콘텐츠를 제출합니다. 사용자가 'lagrein' 유형의 와인을 검색하기로 선택했다고 가정해 보겠습니다.


2. 다음과 같은 변수에 할당하여 사용자의 검색어를 검색하고 유지합니다.

$variety = $_POST['variety' ];

따라서 변수 $variety의 값은 이제 다음과 같습니다.

lagrein

3. 그런 다음 WHERE 절에 변수를 적용합니다. 데이터베이스 쿼리 구성:

$query = 'SELECT * FROM wines WHEREvariety='$variety';

따라서 $query 변수의 값은 이제 다음과 같습니다.

SELECT * FROM wines WHERE 다양성='lagrein'

4. MySQL 서버에 쿼리를 제출합니다.

5. MySQL은 와인 테이블의 모든 레코드를 반환합니다. 그 중 필드 다양성의 값은 'lagrein'입니다.


이제 이 과정은 익숙하고 쉬울 것입니다. 불행하게도 때로는 우리가 익숙하고 편안하게 느끼는 프로세스가 쉽게 자부심으로 이어질 수 있습니다. 이제 방금 구성한 쿼리를 다시 분석해 보겠습니다.

1. 생성한 쿼리의 고정 부분은 변수 값의 시작 부분을 설명하는 데 사용할 작은따옴표로 끝납니다.

$query = ' SELECT * FROM wines WHERE Variant = '';

2. 원래 고정된 부분을 적용하고 사용자가 제출한 변수의 값을 포함합니다.

$query .= $variety

3 . 그런 다음 이 결과를 변수 값의 끝을 설명하는 또 다른 작은따옴표로 연결합니다.

$ query .= ''';

따라서 $query 값은 다음과 같습니다. :

SELECT * FROM wines WHERE 다양성 = 'lagrein'

이 구조의 성공 여부는 사용자의 입력에 달려 있습니다. 이 예에서는 와인 유형을 지정하기 위해 단일 단어(또는 단어 그룹)를 사용하고 있습니다. 따라서 쿼리는 헤더 없이 구성되며 결과는 예상한 대로 와인 유형이 'lagrein'인 와인 목록입니다. 이제 'lagrein'이라는 간단한 와인 유형을 입력하는 대신 사용자가 다음을 입력한다고 가정해 보겠습니다(구두점 두 개 포함):

lagrein ' 또는 1=1;

이제 이전에 수정된 부분을 사용하여 계속해서 쿼리를 구성합니다(여기서는 $query 변수의 결과 값만 표시합니다).

SELECT * FROM wines WHERE Variant = '

그런 다음 사용자 입력이 포함된 변수 값을 사용하여 연결합니다(여기서는 굵게 표시됨).

SELECT * FROM wines WHERE 다양성 = 'lagrein' 또는 1=1;

마지막으로, 아래쪽 및 위쪽 따옴표를 추가하세요.

SELECT * FROM wines WHEREvariety = 'lagrein' or 1=1;'

따라서 쿼리 결과는 예상과 상당히 다를 수 있습니다. 실제로 쿼리에는 이제 하나가 아닌 두 개의 명령이 포함됩니다. 사용자가 입력한 마지막 세미콜론이 첫 번째 명령(레코드 선택)을 끝내고 새 명령을 시작했기 때문입니다. 이 경우 두 번째 명령은 간단한 작은따옴표 외에는 의미가 없습니다. 그러나 첫 번째 명령도 구현하려는 명령이 아닙니다. 사용자가 입력 중간에 작은따옴표를 넣으면 결국 변수 값을 보고 다른 조건을 도입하게 됩니다. 따라서 다양성이 'lagrein'인 레코드를 검색하는 대신 두 가지 기준 중 하나를 만족하는 레코드를 검색합니다(첫 번째는 귀하의 것이고 두 번째는 그의 것입니다. 다양성은 'lagrein' 또는 1 즉 1의 레코드입니다). 1은 항상 1이므로 모든 레코드를 검색하게 됩니다!


이의가 있을 수 있습니다. 사용자가 제출한 변수를 설명할 때 작은따옴표 대신 큰따옴표를 사용해야 합니까? 예, 최소한 악의적인 사용자의 공격 속도를 늦출 수 있습니다. (이전 기사에서 사용자에게 보내는 모든 오류 알림 메시지는 비활성화되어야 함을 상기시켰습니다. 여기에서 오류 메시지가 생성되면 공격자에게 도움이 될 수 있습니다. 공격이 실패한 이유에 대한 설명을 제공하세요. 구체적인 지침)

실제로 사용자가 일부 기록이 아닌 모든 기록을 볼 수 있도록 하는 것이 처음에는 번거로워 보일 수 있지만 실제로는 모든 기록에 도달하면 내부 정보를 쉽게 제공할 수 있습니다. 테이블 구조를 통해 향후 더 악의적인 목표를 달성하는 데 중요한 참고 자료를 제공합니다. 방금 설명한 상황은 데이터베이스에 알코올에 대한 명백히 무해한 정보 대신 직원의 연간 수입 목록이 포함되어 있는 경우 특히 그렇습니다.

이론적 관점에서 볼 때 이런 종류의 공격은 참으로 끔찍한 일입니다. 쿼리에 예상치 못한 콘텐츠를 삽입함으로써 이 사용자는 데이터베이스 액세스를 자신의 목표 달성으로 전환할 수 있습니다. 이제 귀하의 데이터베이스는 귀하와 마찬가지로 그에게도 공개됩니다.


4. PHP 및 MySQL 삽입

앞서 설명했듯이 PHP는 자체 설계상 사용자 지침에 따라 작동하는 것 외에는 특별한 작업을 수행하지 않습니다. 따라서 악의적인 사용자가 사용하는 경우 앞서 설명한 것과 같이 요청 시 특별히 설계된 공격에만 '동의'합니다.

우리는 귀하가 의도적으로 또는 실수로 데이터베이스 쿼리를 구성하여 해로운 결과를 초래하지는 않을 것이라고 가정합니다. 따라서 문제는 사용자의 입력에 있다고 가정합니다. 이제 사용자가 스크립트에 정보를 제공할 수 있는 다양한 방법을 자세히 살펴보겠습니다.

5. 사용자 입력 유형

요즘에는 사용자가 스크립트에 영향을 주기 위해 취할 수 있는 작업이 점점 더 복잡해지고 있습니다.

사용자 입력의 가장 확실한 소스는 물론 양식의 텍스트 입력 필드입니다. 이러한 필드를 사용하면 말 그대로 사용자가 임의의 데이터를 입력하도록 장려하는 것입니다. 게다가 사용자에게 넓은 입력 범위를 제공합니다. 사용자가 입력할 수 있는 데이터 유형을 미리 제한할 수 있는 방법은 없습니다(길이를 제한하도록 선택할 수는 있음). 이것이 대부분의 주입 공격이 방어되지 않은 양식 필드에서 발생하는 이유입니다.

하지만 공격의 소스는 다른데, 잠시 생각해보면 폼의 배경에 숨겨진 기술, 바로 POST 방식이 떠오를 것이다! 주의 깊은 사용자는 브라우저의 탐색 도구 모음에 표시된 URI를 간략하게 분석하여 어떤 정보가 스크립트에 전달되는지 쉽게 확인할 수 있습니다. 이러한 URI는 일반적으로 프로그래밍 방식으로 생성되지만 악의적인 사용자가 단순히 부적절한 변수 값이 포함된 URI를 브라우저에 입력하여 잠재적으로 악용될 수 있는 데이터베이스를 열려고 하는 것을 방지할 수 있는 방법은 없습니다.

사용자 입력을 제한하는 일반적인 전략은 입력 상자 대신 양식에 선택 상자를 제공하는 것입니다. 이러한 종류의 제어는 사용자가 미리 정의된 값 집합에서 선택하도록 강제할 수 있으며 사용자가 어느 정도 표시되지 않는 콘텐츠를 입력하는 것을 방지할 수 있습니다. 그러나 공격자가 URI를 '스푸핑'할 수 있는 것처럼(예: 신뢰할 수 있지만 유효하지 않은 URI를 모방하는 URI 생성) 양식을 가장하고 자신만의 버전을 생성할 수도 있습니다. 옵션 상자에서 미리 정의된 안전 선택 대신 불법을 적용합니다. 이를 수행하는 것은 매우 간단합니다. 소스 코드를 본 다음 양식의 소스 코드를 잘라내어 붙여넣기만 하면 됩니다. 그러면 문이 열립니다.


선택 항목을 수정한 후 양식을 제출할 수 있으며 잘못된 명령은 원래 명령인 것처럼 허용됩니다. 따라서 사용자는 다양한 방법을 사용하여 스크립트에 악성 코드를 삽입할 수 있습니다.




위 내용은 PHP For에서 SQL 인젝션 공격을 전면 금지하는 내용 중 하나입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(m.sbmmt.com)를 주목해주세요!


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿