> 백엔드 개발 > 파이썬 튜토리얼 > SQL 주입 방지를 위한 Python 방법에 대한 자세한 설명

SQL 주입 방지를 위한 Python 방법에 대한 자세한 설명

Y2J
풀어 주다: 2017-05-06 15:02:51
원래의
1377명이 탐색했습니다.

SQL 인젝션은 가장 흔한 네트워크 공격 방법 중 하나로 운영체제의 BUG를 이용해 공격을 가하는 것이 아니라, 프로그래밍 중 프로그래머의 과실을 겨냥해 계정이나 계정 없이 로그인할 수 있다. 심지어 데이터베이스를 조작할 수도 있습니다. 다음 글에서는 Python에서 SQL 주입을 방지하는 방법을 주로 소개합니다. 도움이 필요한 친구가 참고할 수 있습니다.

머리말

웹 백엔드 개발에 어떤 언어를 사용하든 이제 웹 취약점 1위는 SQL이라는 점을 누구나 알아야 합니다. , 관계형 데이터베이스를 사용하는 한 SQL 주입 공격에 직면할 수 있습니다. 그렇다면 Python 웹 개발 중에 SQL 주입은 어떻게 나타나고, 이 문제를 해결하는 방법은 무엇일까요?

물론, PHP에서 인젝션을 방지하는 방법은 여러 가지가 있지만 다른 언어에서는 어떻게 하는지 논의하고 싶지는 않습니다. (블로거의 메모: 세상에서 가장 멋진 언어라고 합니다. ) Python을 포함하여 인터넷에서 방법은 실제로 유사하므로 여기서는 예를 들어 보겠습니다.

원인

취약점의 가장 일반적인 원인은 문자열 스플라이싱입니다. 물론 sql 주입은 없습니다. 는 스플라이싱의 한 가지 사례일 뿐이지만 와이드 바이트 주입, 특수 문자 이스케이프 등 다른 유형도 많이 있습니다. 여기서는 가장 일반적인 문자열 스플라이싱에 대해 이야기하겠습니다. 주니어 프로그래머.

먼저 mysql

class Database:
 aurl = '127.0.0.1'
 user = 'root'
 password = 'root'
 db = 'testdb'
 charset = 'utf8'

 def init(self):
  self.connection = MySQLdb.connect(self.aurl, self.user, self.password, self.db, charset=self.charset)
  self.cursor = self.connection.cursor()

 def insert(self, query):
  try:
   self.cursor.execute(query)
   self.connection.commit()
  except Exception, e:
   print e
   self.connection.rollback()

 def query(self, query):
  cursor = self.connection.cursor(MySQLdb.cursors.DictCursor)
  cursor.execute(query)
  return cursor.fetchall()

 def del(self):
  self.connection.close()
로그인 후 복사

의 작업을 처리하는 클래스를 정의합니다. 이 코드는 mysql의 Python 작업과 관련된 많은 이전 스크립트에서 볼 수 있었습니다. 데이터베이스 의 모든 스크립트를 이 클래스에 작성할 텐데 이 클래스에 문제가 있나요?
답은: 그렇습니다!

이 클래스는 결함이 있어 SQL 인젝션이 쉽게 발생하는 이유에 대해 이야기해보겠습니다.

문제의 진위 여부를 확인하기 위해 위 클래스의 메서드를 호출하는 방법은 다음과 같습니다. 오류가 발생하면 직접 예외가 발생합니다.

def test_query(articleurl):
 mysql = Database()
 try:
  querySql = "SELECT * FROM `article` WHERE url='" + articleurl + "'"
  chanels = mysql.query(querySql)
  return chanels
 except Exception, e:
  print e
로그인 후 복사

이 방법은 매우 간단합니다. 가장 일반적인 select 쿼리 문 중 하나는 가장 간단한 문자열 접합을 사용하여 SQL 문을 형성하는 것으로 전달된 매개변수 articleurl을 제어할 수 있다는 점은 분명합니다. 인젝션 테스트를 수행하려면 Articleurl 값 뒤에 작은따옴표만 추가하면 SQL 인젝션 테스트를 수행할 수 있음은 물론입니다. 결과는

(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''t.tips''' at line 1")
로그인 후 복사
로그인 후 복사

Return 매우 익숙한 오류입니다. 여기에 전달한 테스트 매개변수는

t.tips'
로그인 후 복사

입니다. 약간 수정한 후 다른 상황에 대해 이야기해 보겠습니다. 위의 메소드인

def test_query(articleurl):
 mysql = Database()
 try:
  querySql = ("SELECT * FROM `article` WHERE url='%s'" % articleurl)
  chanels = mysql.query(querySql)
  return chanels
 except Exception, e:
  print e
로그인 후 복사

가 바로 문자열 스플라이싱을 사용하는 대신 전달되는 매개변수 대신 %s를 사용하는 방식입니다. 미리 컴파일된 SQL과 매우 흡사하지 않나요? 이런 방식으로 작성하면 SQL 삽입을 막을 수 있나요? 테스트해 보면 다음 echo

(1064, "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''t.tips''' at line 1")
로그인 후 복사
로그인 후 복사

는 위의 테스트 결과와 동일하므로 이 방법은 불가능하며, 이 방법은 미리 컴파일된 sql 문이 아니므로 이를 방지하려면 어떻게 해야 하는지 알 수 있습니다. SQL 주입?

해결 방법

두 가지 해결 방법

1> 입력 매개변수

2> Python의 MySQLdb 모듈과 함께 제공되는 방법을 사용하세요.

첫 번째 솔루션은 실제로 많은 PHP 방지 주입 방법에서 발견되며 특수 문자에 대한 특수 문자 조작을 수행합니다. 또는 필터.

두 번째 옵션은 PHP의 PDO와 유사한 내부 메서드를 사용하는 것입니다. 여기서는 위의 데이터베이스 클래스를 간단히 수정할 수 있습니다.

수정된 코드

class Database:
 aurl = '127.0.0.1'
 user = 'root'
 password = 'root'
 db = 'testdb'
 charset = 'utf8'

 def init(self):
  self.connection = MySQLdb.connect(self.aurl, self.user, self.password, self.db, charset=self.charset)
  self.cursor = self.connection.cursor()

 def insert(self, query, params):
  try:
   self.cursor.execute(query, params)
   self.connection.commit()
  except Exception, e:
   print e
   self.connection.rollback()

 def query(self, query, params):
  cursor = self.connection.cursor(MySQLdb.cursors.DictCursor)
  cursor.execute(query, params)
  return cursor.fetchall()

 def del(self):
  self.connection.close()
로그인 후 복사

여기서 실행이 실행될 때 두 개의 매개변수가 전달됩니다. 첫 번째는 매개변수화된 sql 문이고, 두 번째는 해당 실제 매개변수 값입니다. 함수. 에서는 들어오는 매개변수 값을 그에 따라 처리하여 SQL 주입을 방지합니다. 실제 사용되는 방법은 다음과 같습니다.

preUpdateSql = "UPDATE `article` SET title=%s,date=%s,mainbody=%s WHERE id=%s"
mysql.insert(preUpdateSql, [title, date, content, aid])
로그인 후 복사

이를 통해 MySQLdb 모듈 내부에 목록을 전달한 후 목록이 직렬화됩니다. 튜플에 넣은 다음 이스케이프했습니다.

[관련 추천]

1. Python 무료 동영상 튜토리얼

2. Python 기본 입문 튜토리얼

3.

Geek Academy Python 동영상 튜토리얼

위 내용은 SQL 주입 방지를 위한 Python 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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