源码审计是否存在sql注入,安全和危险的sql操作代码

admin 2024年10月13日00:52:43评论24 views字数 5341阅读17分48秒阅读模式

得到源代码

获得源代码后,使用搜索工具,例如PowerGREP搜索源码

源码审计是否存在sql注入,安全和危险的sql操作代码

搜索关键词如下

selectupdatedeleteinsertsqlfromdatabase

搜索后,可以看到结果中出现了很多条sql语句。

这时候,我们想要查看代码,判断这些操纵sql的代码片段是否存在sql注入。

我们需要知道那种代码看起来就有sql注入漏洞,哪种代码看起来就是安全的没有漏洞。

存在sql注入的错误写法如下,如果你看到代码中传入参数的格式如下,那么只要此处的代码被调用,就一定存在sql注入。

cursor.execute("SELECT admin FROM users WHERE username = '" + username + '");cursor.execute("SELECT admin FROM users WHERE username = '%s' % username);cursor.execute("SELECT spam, eggs, sausage FROM breakfast WHERE price < %s" % (max_price,))cursor.execute("SELECT admin FROM users WHERE username = '{}'".format(username));cursor.execute(f"SELECT admin FROM users WHERE username = '{username}'");

安全的sql操作代码

那么什么情况下,能识别到当前的代码没有sql注入漏洞呢。

下面的代码均为安全的代码,可以防止sql注入,如果你搜索出的代码如下,那就证明代码没有sql注入漏洞。

下面的内容也可以被开发借鉴,写出安全的sql操作代码

# 防止sql注入的安全写法cursor.execute("SELECT admin FROM users WHERE username = %s", (username, ));cursor.execute("SELECT spam, eggs, sausage FROM breakfast  WHERE price < %s", (max_price,))cursor.execute("SELECT spam FROM eggs WHERE lumberjack = :1", (lumberjack,))cursor.execute("SELECT spam FROM eggs WHERE lumberjack = :jack", {'jack': lumberjack})cursor.execute("SELECT admin FROM users WHERE username = %(username)s", {'username': jack});cursor.execute("SELECT spam FROM eggs WHERE lumberjack = ?", (lumberjack,))

参数化查询

mysql.connector和pymysql使用%s作为占位符,防范 SQL 注入的最佳方法是使用参数化查询,可以防止sql注入

import pymysqlconn = pymysql.connect(host="localhost",                           port=3306,                           user="root",                           password="mysql123456",                           database="python",                           charset="utf8")# 定义查询和参数,下面可以防止sql注入query = "SELECT * FROM t_oauth_users WHERE username=%s AND email=%s"params = ('user1', '[email protected]')# 执行查询cursor.execute(query, params)
import mysql.connector# 创建数据库连接conn = mysql.connector.connect(user='your_username', password='your_password', host='localhost', database='your_database')cursor = conn.cursor()# 定义查询和参数,下面可以防止sql注入query = "SELECT * FROM t_oauth_users WHERE username=%s AND email=%s"params = ('user1', '[email protected]')# 执行查询cursor.execute(query, params)
使用 %(name)s 命名占位符可以防止sql注入query = "SELECT * FROM t_oauth_users WHERE username=%(username)s AND email=%(email)s"params = {'username': 'user1', 'email': '[email protected]'}

Python 库提供了 API 来对大多数可用的数据库技术执行参数化查询,每个代码片段中的代码都展示了使用一些最常见的 Python 数据库库的参数化查询来调用方法的推荐方法。

PyMySQL,MySQL-python

MySQL connectorPyGreSQLPsycopgpymssql 可以防止sql注入

cursor.execute("SELECT * FROM users WHERE username = %s AND password = %s", (username, password))

SQLAlchemy 可以防止sql注入

stmt = sqlalchemy.sql.text("SELECT * FROM users WHERE username = :username and password = :password")conn.execute(stmt, {"username": username, "password": password })

sqlite3pyodbc  可以防止sql注入

cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, password))c.execute('select * from stocks where name=?', t)?会把参数当做值来处理,它会转义特殊字符,并且在输入前后加上’’select * from user where id = ?语句为例,传入1 or 1=1select * from user where id = '1 or 1 = 1'

转义用户输入防止sql注入

在某些情况下,需要将用户提供的数据直接包含在 SQL 查询中。

例如,在构建动态搜索功能时,用户可能会输入搜索词,该搜索词需要直接包含在 SQL 查询中才能检索相关结果。

在这种情况下,正确转义用户输入以防止 SQL 注入攻击非常重要。

在 Python 中,我们可以使用psycopg2.sql.SQL类或mysql.connector.connector.escape_string方法来转义用户输入。

转义用户输入会将用户提供的数据中的任何特殊字符替换为转义字符,从而可以在 SQL 查询中安全使用。

在此示例中,该类sql.SQL用于创建带有名称占位符的 SQL 查询。

sql.Identifier然后使用该方法对名称的值进行转义,以防止 SQL 注入。

import psycopg2from psycopg2 import sqldef dynamic_search(search_term):    with psycopg2.connect(database="mydatabase", user="mydatabaseuser", password="mypassword", host="localhost", port="5432") as conn:        cursor = conn.cursor()        # Use psycopg2.sql to build and execute the query        query = sql.SQL("SELECT * FROM mytable WHERE name LIKE {};").format(sql.Identifier(search_term))        cursor.execute(query)        results = cursor.fetchall()    return results

以下是我们如何使用 MySQL 库转义用户输入。

通过使用该mysql.connector.connector.escape_string函数正确地转义用户输入,我们能够安全地将用户提供的数据包含在查询中。

import mysql.connector def  dynamic_search ( search_term ):     with mysql.connector.connect(user= 'mydatabaseuser' , password= 'mypassword' , host= 'localhost' , database= 'mydatabase' ) as conn:         cursor = conn.cursor()         # 使用 escape_string 函数正确转义用户输入        escaped_search_term = mysql.connector.connector.escape_string(search_term)         query = "SELECT * FROM mytable WHERE name LIKE '{}'".format (escaped_search_term)         cursor.execute(query)         results = cursor.fetchall()     return results

Django ORM—ORM 框架防止注入

如果你完全避免使用原生SQL查询,并且只使用Django ORM提供的高级查询方法(如 filter, get, exclude 等),那么你以避免SQL注入的风险。Django ORM在设计时已经考虑到了安全性,会自动对用户输入进行转义和参数化处理,从而防止SQL注入。

Django ORM 提供了多种安全机制来防止SQL注入,主要包括:

  1. 参数化查询

Django ORM 内部使用参数化查询来构建SQL语句。这意味着用户输入的数据会被作为参数传递给数据库驱动程序,而不是直接拼接到SQL字符串中。

2. 自动转义

Django ORM 会自动对用户输入的数据进行转义,确保数据不会被解释为SQL代码。

1. 简单查询

from django.http import JsonResponsefrom book.models import Bookdef search_books(request):    keyword = request.GET.get('keyword', '')    # 使用Django ORM进行查询    books = Book.objects.filter(title__icontains=keyword)    results = list(books.values())    return JsonResponse({'results': results})

2. 复合查询

from django.http import JsonResponsefrom book.models import Bookdef advanced_search(request):    keyword = request.GET.get('keyword', '')    author = request.GET.get('author', '')    # 使用Django ORM进行复合查询    books = Book.objects.filter(title__icontains=keyword, author__icontains=author)    results = list(books.values())    return JsonResponse({'results': results})

3. 排序和分页

from django.http import JsonResponsefrom book.models import Bookdef list_books(request):    page = int(request.GET.get('page', 1))    page_size = int(request.GET.get('page_size', 10))    # 使用Django ORM进行排序和分页    books = Book.objects.order_by('publication_date')[(page - 1) * page_size:page * page_size]    results = list(books.values())    return JsonResponse({'results': results})

防止sql注入的其它方法

不要在数据报文中显示具体的sql语句,防止被攻击者测试攻击。

把要执行的sql语句写死在代码里,而不是直接执行用户输入的数据

错误方法:系统和数据库管理员在安装数据库服务器时允许以roots SYSTEMAdministrator特权系统用户账户身份执行操作。

正确方法:应该始终以普通用户身份运行服务器上的服务,降低用户权限,将用户权限只限于本服务。

原文始发于微信公众号(SecurityBug):源码审计是否存在sql注入,安全和危险的sql操作代码

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年10月13日00:52:43
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   源码审计是否存在sql注入,安全和危险的sql操作代码https://cn-sec.com/archives/3259890.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息