본문 바로가기
Python

[Python] SQL Injection 과 보호 방법

by 혀나Lee 2016. 10. 13.

SQL injection protection

장고의 queryset(ORM)을 사용할 경우, SQL injection을 막아준다. 하지만 raw queries를 사용하는 extra(), RawSQL를 사용하거나 실제로 connection을 통해 직접적인 쿼리를 통해 사용할 경우에는 SQL injection 처리를 따로 해줘야 한다.

Python SQL injection

http://bobby-tables.com/python.html 에서 Python SQL injection 방법에 대해 설명하고 있다.

Bad:

cmd = "update people set name='%s' where id='%s'" % (name, id)

curs.execute(cmd)

Good:

cmd = "update people set name=%s where id=%s"

curs.execute(cmd, (name, id))


Bad의 경우에 id 키 값에 'hyuna' and 1=1 라고 보낼 경우 injection에 걸린다. 하지만, Good의 경우에 똑같이 'hyuna' and 1=1을 보내면 파라미터 자체를 스트링으로 치환해서 사용하기 때문에 injection에 걸리지 않는다.


mark 종류

'qmark' Question mark style, e.g. '...WHERE name=?' 'numeric' Numeric, positional style, e.g. '...WHERE name=:1' 'named' Named style, e.g. '...WHERE name=:name' 'format' ANSI C printf format codes, e.g. '...WHERE name=%s' 'pyformat' Python extended format codes, 

e.g. '...WHERE name=%(name)s'




>>> import MySQLdb; print MySQLdb.paramstyle

format >>> import psycopg2; print psycopg2.paramstyle pyformat >>> import sqlite3; print sqlite3.paramstyle qmark


위의 사이트에서는 MySQL이나 PostgreSQL을 사용할 때는 %s를 사용하면 되고 SQLite는 ?를 사용하면 된다고 한다.

Named Arguments

위의 %s 를 사용하면 파라미터를 전달할 때, 순서를 알아야한다. 만약 전달해야 하는 파라미터의 개수가 많아지면 헷갈리게 되는데 이럴 때 named arguments 방식을 사용하면 된다.
named arguments 방식은 string 안에 파라미터가 필요한 위치에 %s를 사용하는 대신 %(파라미터명)s를 사용하는 것이다.

some_dictionary_with_the_data = {

    'name': 'awesome song',

    'artist': 'some band',

    etc...

}

cursor.execute ("""

            INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)

            VALUES

                (%(name)s, %(artist)s, %(album)s, %(genre)s, %(length)s, %(location)s)


        """, some_dictionary_with_the_data)

이처럼 dictionary 형태로 key, value 쌍을 만들어 전달해주면 string의 원하는 위치에 파라미터 값이 박힌다.
또한, execute의 % 대신 , 를 사용함으로써 SQL injection을 막을 수 있다.


'Python' 카테고리의 다른 글

[Python] Private PYPI  (0) 2016.11.09
[Python3] two list for loop  (0) 2016.11.08
[Python] 파이썬 정규식  (0) 2016.10.27
[Python] call by assignment (call by object, call by object reference)  (0) 2016.10.26
[Python] RabbitMQ Publish Subscribe  (0) 2016.10.26

댓글