웹 백엔드 개발에 어떤 언어를 사용하더라도 관계형 데이터베이스를 사용한다면 SQL은 다름 아닌 SQL입니다. 주입 공격이 발생할 수 있습니다. 그렇다면 Python 웹 개발 과정에서 SQL 인젝션은 어떻게 나타나고, 이 문제를 해결하는 방법은 무엇일까?
물론 다른 언어에서 sql 주입을 방지하는 방법에 대해 논의하고 싶지는 않습니다. 인터넷에는 Python의 방법이 있습니다. 실제로 비슷합니다. 여기 예를 들어 보겠습니다.
취약점의 가장 흔한 원인은 문자열 스플라이싱입니다. 물론 sql 인젝션은 스플라이싱뿐만 아니라 와이드 바이트 같은 것들도 많이 있습니다. 삽입 유형, 특수 문자 이스케이프 등 여기에서는 가장 일반적인 문자열 접합에 대해 이야기하겠습니다. 이는 주니어 프로그래머들이 가장 흔히 저지르는 실수이기도 합니다.
먼저 mysql
class Database: hostname = '127.0.0.1' user = 'root' password = 'root' db = 'pythontab' charset = 'utf8' def init(self): self.connection = MySQLdb.connect(self.hostname, 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()
의 작업을 처리하는 클래스를 정의합니다. 이 클래스에 문제가 있나요?
답은: 그렇습니다!
이 클래스는 결함이 있어 SQL 주입이 쉽게 발생하는 이유에 대해 이야기해 보겠습니다.
문제의 진위 여부를 확인하기 위해 위 클래스의 메소드를 호출하는 방법은 다음과 같습니다. 오류가 발생하면 바로 예외가 발생합니다. 🎜>.
def test_query(testUrl): mysql = Database() try: querySql = "SELECT * FROM `article` WHERE url='" + testUrl + "'" chanels = mysql.query(querySql) return chanels except Exception, e: print e이 방법은 매우 간단합니다. 가장 일반적인 select
올바른 구문을 MariaDB 서버 버전에 해당하는 설명서를 확인하세요. 1행의 ''t.tips'' 근처에서 사용하려면")
오류 메시지가 에코됩니다. 매우 친숙한 오류입니다. 여기에 전달한 테스트 매개변수는 t입니다. Tips'위 방법을 살짝 수정한 후def test_query(testUrl): mysql = Database() try: querySql = ("SELECT * FROM `article` WHERE url='%s'" % testUrl) chanels = mysql.query(querySql) return chanels except Exception, e: print e이 방법은 문자열 접합을 직접 사용하지 않고 %s를 사용하여 매개변수를 대체하여 주입이 발생하는 경우에 대해 이야기해 보겠습니다. 전달되었습니다. 미리 컴파일된 SQL과 매우 유사합니까?를 참조하세요. 이런 방식으로 작성하면 SQL 삽입을 막을 수 있나요? 테스트해 보면 응답은 다음과 같습니다. (1064, "SQL 구문에 오류가 있습니다. '' 근처에서 사용할 올바른 구문은 MariaDB 서버 버전에 해당하는 설명서를 확인하세요. t.tips' '' at line 1")결과는 위의 테스트와 동일하므로 이 방법은 불가능하며, 이 방법은 미리 컴파일된 sql 문이 아니므로 이를 방지하려면 어떻게 해야 합니까? SQL 주입? 솔루션두 가지 솔루션
PDO와 유사한 내부 메서드를 사용하는 것입니다. 여기서는 위의 데이터베이스 클래스를 간단히 수정할 수 있습니다.
class Database: hostname = '127.0.0.1' user = 'root' password = 'root' db = 'pythontab' charset = 'utf8' def init(self): self.connection = MySQLdb.connect(self.hostname, 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 주입을 방지하기 위해 들어오는 매개변수 값을 그에 맞게 처리합니다. 실제 사용되는 방법은
preUp
Sql = "UPDATE `article` SET title=%s,date=%s,mainbody=%s WHERE id=%s" mysql.insert(preUpdateSql , [제목, 날짜, 내용, 보조])
이렇게 하면 SQL 주입을 방지할 수 있습니다. 목록을 전달한 후 MySQLdb 모듈은 내부적으로 목록을 튜플로 직렬화한 다음 이스케이프 작업을 수행합니다.
위 내용은 Python을 사용하여 SQL 주입을 방지하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!