데이터베이스 쿼리는 인젝션 공격에 취약하지 않아야 합니다.

 

URL 매개변수와 같이 사용자가 제공한 데이터는 항상 신뢰할 수 없고 오염된 것으로 간주해야 합니다. 공격자는 오염된 데이터에서 직접 SQL 쿼리를 생성하면 쿼리 자체의 초기 의미를 변경하는 특수하게 조작된 값을 삽입할 수 있습니다. 데이터베이스 쿼리 인젝션 공격이 성공하면 데이터베이스에서 중요한 정보를 읽거나 수정 또는 삭제할 수 있으며, 심지어 데이터베이스를 종료하거나 임의의 운영 체제 명령을 실행할 수도 있습니다.

일반적으로 해결책은 prepared statements를 사용하고 params와 같은 전용 메서드를 사용하여 변수를 SQL 쿼리 매개변수에 바인딩하여 사용자가 제공한 데이터가 올바르게 이스케이프되도록 하는 것입니다. 또 다른 해결책은 쿼리를 작성하는 데 사용되는 모든 매개변수의 유효성을 검사하는 것입니다. 이는 문자열 값을 기본 유형으로 변환하거나 허용되는 값의 화이트리스트에 대해 유효성을 검사하여 수행할 수 있습니다.

이 규칙은 sqlite3, mysql, pymysql, psycopg2, pgdb, Django ORM 및 Flask-SQLAlchemy를 지원합니다.

규칙을 어긴 코드

Flask application

from flask import request
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import text
from database.users import User

@app.route('hello')
def hello():
    id = request.args.get("id")
    stmt = text("SELECT * FROM users where id=%s" % id) # 쿼리가 사용자 입력을 기반으로 구성됩니다.
    query = SQLAlchemy().session.query(User).from_statement(stmt) # 규칙을 어긴 코드
    user = query.one()
    return "Hello %s" % user.username

Django application

from django.http import HttpResponse
from django.db import connection

def hello(request):
    id = request.GET.get("id", "")
    cursor = connection.cursor()
    cursor.execute("SELECT username FROM auth_user WHERE id=%s" % id) # 규칙을 어긴 코드; 쿼리가 사용자 입력을 기반으로 구성됩니다.
    row = cursor.fetchone()
    return HttpResponse("Hello %s" % row[0])

규칙을 준수한 해결책

Flask application

from flask import request
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import text
from database.users import User

@app.route('hello')
def hello():
    id = request.args.get("id")
    stmt = text("SELECT * FROM users where id=:id")
    query = SQLAlchemy().session.query(User).from_statement(stmt).params(id=id) # 규칙을 준수한 코드
    user = query.one()
    return "Hello %s" % user.username

Django application

from django.http import HttpResponse
from django.db import connection

def hello(request):
    id = request.GET.get("id", "")
    cursor = connection.cursor()
    cursor.execute("SELECT username FROM auth_user WHERE id=:id", {"id": id}) # 규칙을 준수한 코드
    row = cursor.fetchone()
    return HttpResponse("Hello %s" % row[0])

같이보면 좋은 자료

If you like SONARKUBE, don’t forget to give me a star. :star2:

원문으로 바로가기

Star This Project