SQL Injection 인젝션 방지
SQL Injection(SQL 인젝션)은 우리의 DB를 망칠 수 있는 방법이다.
웹에서 SQL문을 사용해서 DB에 있는 정보를 빼오거나 지우거나 수정할 수 있다.
기본으로 SQL 인젝션이라고 하는데, 웹에서 DB를 검색하거나 작업할 때 SQL명령어를 함께 넣어주는 작업을 말한다.
사용자가 악성적인 SQL명령어를 웹페이지의 inputbox 같은 곳에 넣아주는 것이다. 삽입된 SQL명령어는 웹홈페이지를 손상시킬 수 있는 가능성이 있다.
예를 들어
txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;
서버에서 위와 같은 코드가 있다고 하자.
사용자의 ID값을 받아서 DB의 Users테이블에서 아이디와 같은 값을 찾는 코드이다.
여기에 id를 넣어야 하지만 만약에 "tester or 1=1" 값을 넣게 된다면 서버에서 받는 SQL 명령어는 다음과 같을 것이다.
SELECT * FROM Users WHERE UserId = tester or 1=1
SQL문법을 봤을 때 유효한 형식이다. 그렇기 때문에 먼저 ID가 tester인 값과 or 연산자로 인해 WHERE 1=1 이 참이기 때문에 모든 결과를 다 보여주게 된다.
그렇게 되면 다른 사용자의 ID값과 패스워드 등 개인적인 정보까지 유출될 수 있다.
조금 더 실질적인 예로 서버에 다음과 같은 코드가 있다고 하자.
User Name:
Password:
uName = getRequestString("UserName");
uPass = getRequestString("UserPass");
sql = "SELECT * FROM Users WHERE Name ='" + uName + "' AND Pass ='" + uPass + "'"
사용자로 부터 ID와 PW(패스워드)를 받아서 SQL문을 실행하는 형식이다.
위와 같은 경우는 name과 password 칸에 "or ""="를 넣어서 인젝션 할 수 있다.
SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""
SQL문법적으로 봤을 때 유효한 문법이다. 여기서 모든 User테이블의 레코드를 돌려주게 되는데, WHERE ""="" 가 참 값을 갖기 때문이다.
DB의 레코드 값만 불러오는 것이 아니라 직접 명령어를 넣을 수 있다.
만약 서버에 다음과 같은 코드가 있다고 할 때,
txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;
아래와 같이
User id:
tester; DROP TABLE Suppliers |
이렇게 SQL 문이 실행하게 된다.
SELECT * FROM Users WHERE UserId = tester; DROP TABLE Suppliers
곧 ID값을 불러오고 Suppliers의 테이블은 날려버리게 되는 것이다 .
이러한 인젝션 공격을 방지하기 위해 ;, = 같은 문자를 못 넣게 하는 방법이 있다.
하지만 그렇게 되면 사용자에게 제약이 되므로 SQL parameter 값을 넣고 SQL query를 실행하게 해주는 것이다.
게시판을 만들거나 SQL 쿼리를 사용하게 될 때 봤었던 방법이다.
ASP.NET 의 예를 보면
txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);
과 같은 코드로 @ SQL parameter를 사용해서 값을 넣고 db를 실행한다.
꼭 @ 가 사용되는 것이 아니라 다른 언어마다 다른 parameters를 사용한다.
PHP 같은 경우에는 : 를 사용한다.
$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();
ASP.NET INSERT INTO 문:
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();
위의 예들과 같이 Parmeters를 사용해서 SQL 인젝션을 방지할 수 있다.
웹의 기본~!
'my_lesson > _SQL' 카테고리의 다른 글
SQL - UPDATE (1) | 2016.02.25 |
---|---|
SQL - DELETE (0) | 2016.02.25 |
SQL - LIKE (0) | 2016.02.25 |
SQL - IN (0) | 2016.02.25 |
SQL - BETWEEN (0) | 2016.02.25 |
댓글