최신 웹 개발 튜토리얼
 

SQL주입


는 SQL 주입 데이터베이스를 파괴 할 수 있습니다.


웹 페이지에서 SQL

이전 장에서는 SQL을 사용하여 (업데이트) 데이터베이스의 데이터를 검색 할 수 배웠습니다.

SQL이 웹 페이지 데이터를 표시하는 데 사용되는 경우, 웹 사용자의 입력을 자신의 검색 값을 허용하는 것이 일반적이다.

SQL 문 텍스트 때문에 아니라, 동적으로 선택된 데이터를 사용자에게 제공하는 SQL 문을 변경하는, 컴퓨터 코드의 작은 조각으로, 용이 :

서버 코드

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

위의 예는, 선별 된 문자열에 변수 (txtUserId)을 추가하여 선택 문을 작성합니다. 변수는 페이지에 대한 사용자의 입력 (요청)로부터 페치된다.

이 장의 나머지 부분은 SQL 문에서 사용자의 입력을 사용하는 잠재적 인 위험에 대해 설명합니다.


SQL 주입

SQL 주입은 악의적 인 사용자가 웹 페이지에 입력을 통해, SQL은 SQL 문에 명령을 주입 할 수있는 기술이다.

주입 SQL 명령 SQL 문을 변경하고, 웹 애플리케이션의 보안을 손상시킬 수있다.


1 = 1을 기준으로 SQL 주입 항상 True입니다

위의 예에서 한 번 더 봐.

의 코드의 원래 목적은 주어진 사용자 ID를 가진 사용자를 선택하는 SQL 문을 작성하는 것을 가정 해 봅시다.

입력에서 사용자를 방지하기 위해 아무것도 존재하지 않는 경우 "wrong" 입력, 사용자는 어떤 입력 할 수있는 "smart" 이 같은 입력 :

사용자 아이디 :

서버 결과

SELECT * FROM Users WHERE UserId = 105 or 1=1

는 SQL 위 유효합니다. 1 = 1은 항상 true입니다 WHERE 이후는, 테이블 사용자에서 모든 행을 반환합니다.

예 위합니까 위험한 것? 어떤 사용자 테이블 이름과 암호를 포함하는 경우?

위의 SQL 문은 많은이와 동일합니다 :

SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1

스마트 해커는 단순히 입력 상자에 105 또는 1 = 1을 삽입하여 데이터베이스의 모든 사용자 이름 및 패스워드에 대한 액세스를 얻을 수있다.


를 기반으로 SQL 인젝션은 ""="" 항상 True입니다

여기서 웹 사이트에 대한 사용자의 로그인 정보를 확인하기 위해 사용되는 일반적인 구조이다 :

사용자 이름:

암호:

서버 코드

uName = getRequestString("UserName");
uPass = getRequestString("UserPass");

sql = "SELECT * FROM Users WHERE Name ='" + uName + "' AND Pass ='" + uPass + "'"

스마트 해커는 단순히 삽입 "또는하여 데이터베이스에서 사용자 이름과 암호에 대한 액세스 권한을 얻을 수 있습니다 ""=" 에 사용자 이름이나 암호 텍스트 상자.

서버에있는 코드는 다음과 같은 유효한 SQL 문을 생성합니다 :

결과

SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""

결과 SQL은 유효합니다. ""= "가"항상 true입니다 WHERE 이후는, 테이블 사용자에서 모든 행을 반환합니다.


일괄 SQL 문을 기반으로 SQL 주입

대부분의 데이터베이스는 세미콜론으로 구분 일괄 SQL 문을 지원합니다.

SELECT * FROM Users; DROP TABLE Suppliers

는 SQL 위의 사용자 테이블의 모든 행을 반환 한 다음 테이블을 호출 공급자를 삭제합니다.

우리는 다음과 같은 서버 코드를 가지고 있다면 :

서버 코드

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

다음의 입력 :

사용자 ID :

서버에있는 코드는 다음과 같은 유효한 SQL 문을 만들 것입니다 :

결과

SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers

보호를위한 매개 변수

일부 웹 개발자가 사용하는 "blacklist" SQL 주입 공격을 방지하기 위해, SQL 입력에 검색 할 단어 또는 문자입니다.

이것은 아주 좋은 생각이 아니다. 이 단어의 대부분 (등의 삭제 또는 드롭) 및 (세미콜론 및 인용 부호 등) 문자는 공통 언어로 사용되며, 입력의 많은 유형에서 허용되어야한다.

(실제로는 입력 데이터베이스 필드에 SQL 문에 완벽하게 합법적이어야한다.)

SQL 인젝션 공격으로부터 웹 사이트를 보호하기 만 검증 방법은 SQL 매개 변수를 사용하는 것이다.

SQL 파라미터가 제어 된 방식으로, 실행시에 SQL 쿼리에 추가되는 값이다.

ASP.NET 면도기 예

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);

매개 변수는 @ 마커에 의해 SQL 문에 표시되어 있습니다.

는 SQL 엔진은 그 컬럼에 대한 정확하고 그대로 처리되고, SQL의 일부가 실행될하지 않도록 각각의 매개 변수를 체크한다.

또 다른 예

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
db.Execute(txtSQL,txtNam,txtAdd,txtCit);

당신은 SQL 주입을 방지하기 위해 배웠습니다. 상단 웹 사이트 취약점 중 하나입니다.


다음 예는 일반적인 웹 언어로 매개 변수가있는 쿼리를 작성하는 방법을 보여줍니다.

ASP.NET IN SELECT STATEMENT :

txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = @0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("@0",txtUserID);
command.ExecuteReader();

ASP.NET IN INTO 문 INSERT :

txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
command = new SqlCommand(txtSQL);
command.Parameters.AddWithValue("@0",txtNam);
command.Parameters.AddWithValue("@1",txtAdd);
command.Parameters.AddWithValue("@2",txtCit);
command.ExecuteNonQuery();

PHP IN INTO 문 INSERT :

$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City)
VALUES (:nam, :add, :cit)");
$stmt->bindParam(':nam', $txtNam);
$stmt->bindParam(':add', $txtAdd);
$stmt->bindParam(':cit', $txtCit);
$stmt->execute();