2011-08-31 3 views
1
  1. MATCH은 또한 공격에 취약합니다. 예를 들어 :MySQL의 Python, MATCH 및 인젝션 공격

    """SELECT * 
        FROM myTable 
        WHERE MATCH(myColumnName) AGAINST(%s) 
        ORDER BY id 
        LIMIT 20""" % query 
    

    나쁜 보이는 임의의 문자열을 허용 할 것으로 보인다. 파이썬 문서의 예는 다음 - -

    t = (query,) 
    statement = """SELECT * 
           FROM myTable 
           WHERE MATCH(myColumnName) AGAINST(?) 
           ORDER BY id 
           LIMIT 20""" 
    cursor.execute(statement, t) 
    

    을하지만 아무 것도 반환하지 않습니다 -

  2. 는 그렇다면, 내가 대신 해봤 문자열 query (1) 호에 안타를 반환하는 경우에도. 왜 그런가요?

  3. )에서 대신 자리 표시 자 %s을 사용하면 결과가 반환됩니다. 이것은 1)보다 안전합니다 (전혀 없다면)? 예 : 쿼리 문자열을 사용하면 항상 query=')...'이라는 문자열과 괄호를 닫고 query=') OR otherColumnName LIKE '%hello%' --을 계속 사용할 수 있습니다.

따라서 로마 문자 또는 숫자를 제외하고 모든 쿼리 문자열을 제거하는 것으로 충분합니까?

+0

위와 같이 준비된 쿼리를 '?'와 함께 사용하면 문자열이 필요할 때 인용/이스케이프 처리됩니다. – viraptor

+0

[샘플] (http://sscce.org/)이 완전하지 않습니다. 2.에서'query'의 값은 무엇입니까? 일치하는 행이 무엇입니까? 샘플에서는 중요하지 않지만 ['SELECT *'] (http://stackoverflow.com/questions/321299/what-is-the-reason-not-to-use-select)는 사용하지 마십시오. 생산 코드에서; 필요한 열만 선택하십시오. – outis

+0

그런데 테이블의 모든 열이 필요합니다. 필자는 모든 컬럼의 이름을 지정하여 이와 동일한 철자를 지정할 수 있습니다. – SK9

답변

4

주입과 관련하여 어떤 연산자, 기능, 절 또는 기타 host-language 조항이 중요하지 않습니다. 삽입은 데이터와 언어 문을 혼합하는 문제입니다. 이는 데이터를 명령문에 삽입 할 때 발생합니다. 준비된 문 매개 변수는 데이터와 명령문을 별도로 유지하므로 주입에 취약하지 않습니다.

 execute(self, query, args=None)

[...]

주 : 인수는 시퀀스 인 경우, % S 파라미터 %s?로서는

Cursor.execute 대한 MySQLdb 문서는 다음 말한다 쿼리의 매개 변수 자리 표시 자로 사용해야합니다. 매핑을 사용하는 경우 % (key)를 자리 표시 자로 사용해야합니다.

1

인수가있는 매개 변수가있는 명령문을 사용하면 MySQLdb는 인수를 이스케이프 처리하고 파이썬 문자열 형식을 사용하여 해당 인수를 매개 변수화 된 문에 다시 삽입합니다. 그런 다음 단일 문자열 문이 서버로 전송됩니다. 당신은 제대로 SQL 주입을 방지하기 위해 인수를 탈출 MySQLdb의 능력에 의존하고 있습니다 :

MySQLdb/cursors.py : 대조적으로

def execute(self, query, args=None): 
    ... 
    if args is not None: 
     query = query % db.literal(args) 

, oursql sends queries and data to the server completely separately을. 데이터 이스케이프에 의존하지 않습니다. 이것은 더욱 안전해야합니다.

1

첫 번째 방법은 기본 파이썬 문자열 형식을 사용하기 때문에 올바르지 않습니다. 첫 번째 방법은 쿼리 문자열을 이스케이프 처리하지 않기 때문에 올바르지 않습니다.

두 번째 방법은 간단한 쿼리를 서버에 보내는 기본 방법이며 쿼리를 올바르게 이스케이프 처리합니다.

방금 ​​간단한 버그가 있습니다.당신은 또한이 query 문자열을 소독 할만큼의 파이썬에서 내 목적을 위해 DbApi FAQ

+0

Python MySQL은 '?'를 문자열에 대한 자리 표시 자로 받아들이지 않습니다. – SK9

+1

'connect'의'paramstyle' 매개 변수는 형식화가 기대하는 것을 설정할 수 있어야합니다 –

0

을 발견 AGAINST(%s)

정보와 AGAINST(?)를 교체해야 - 스트립을 경우 모든 영숫자가 아닌 문자 (특히 ')에서) .