DjangoORM注入分享
DjangoORM注入
简介
这篇文章中,分享一些关于django orm相关的技术积累和如果orm注入相关的安全问题讨论。
攻击效果同数据库注入
从Django-Orm开始
开发角度
Django ORM(Object-Relational Mapping)是Django框架中用于处理数据库操作的一种机制。它允许开发者使用Python代码来描述数据库模式和执行数据库查询,进行数据库操作,如创建、读取、更新和删除数据等操作,而不需要直接编写SQL语句。通过ORM,开发者可以更直观和方便地进行数据库操作,同时保持代码的可读性和可维护性。
- 如果没有ORM,作为后端开发的需要写如下代码
# 假设需求背景 Python 开发人员想要编写一个博客网站,供人们发布文章,并希望向其应用程序添加搜索功能
def search_articles(search_term: str) -> list[dict]:results = []with get_db_connection() as conn:with conn.cursor() as cursor:cursor.execute("SELECT title, body FROM articles WHERE title LIKE %s", (f"%{search_term}%",))rows = cursor.fetchall()for row in rows:results.append({"title": row[0],"body": row[1]})return results
- 换成ORM模式开发如下
# models/article.py
from django.db import modelsclass Article(models.Model):"""The data model for Articles"""title = models.CharField(max_length=255)body = models.TextField()class Meta:ordering = ["title"]# serializers/article.py
class ArticleSerializer(serializers.ModelSerializer):"""How objects of the Article model are serialized into other data types (e.g. JSON)"""class Meta:model = Articlefields = ('title', 'body')# views/article.py
class ArticleView(APIView):"""Some basic API view that users send requests to for searching for articles"""def post(self, request: Request, format=None):# Returns the search URL parameter if present otherwise it is set to Nonesearch_term = request.data.get("search", None)if search_term is not None:articles = Article.objects.filter(title__contains=search_term)else:articles Article.objects.all()serializer = ArticleSerializer(articles, many=True)return Response(serializer.data)
安全角度
Django ORM通常可以防止SQL注入问题,因为它会自动对查询参数进行适当的转义和处理。不过,如果在使用Django ORM时不小心使用了原生的SQL查询或手动构建了SQL语句,也是有SQL注入的问题,不过这个不是这篇文章讨论的主要方向。仅作概述:
- 使用ORM的过滤器方法: 始终使用Django ORM的过滤器方法,而不是手动构建SQL查询。例如:
# 安全的查询方式
users = User.objects.filter(username=username)
- 避免使用raw()方法: raw()方法允许你编写原生SQL查询,但如果不正确处理输入,可能会导致SQL注入。
# 不安全的方式
users = User.objects.raw("SELECT * FROM auth_user WHERE username = '%s'" % username)# 安全的方式
users = User.objects.raw("SELECT * FROM auth_user WHERE username = %s", [username])
- 使用Django的QuerySet API: 尽量避免使用低级别的数据库API,Django的QuerySet API提供了足够的功能来执行大多数查询,而不需要直接编写SQL
# 安全的方式
users = User.objects.filter(email__icontains='example.com')
- 使用参数化查询: 如果必须使用自定义的SQL查询,确保使用参数化查询。
from django.db import connectiondef get_user_by_username(username):with connection.cursor() as cursor:cursor.execute("SELECT * FROM auth_user WHERE username = %s", [username])row = cursor.fetchone()return row
- 变量效验: 在处理用户输入时,始终进行变量效验,以确保输入数据的安全和有效性。
from django.db import connectiondef get_user_by_username(username):with connection.cursor() as cursor:# 使用参数化查询防止SQL注入cursor.execute("SELECT * FROM auth_user WHERE username = %s", [username])user = cursor.fetchone()return user
Django-Orm注入
首先创建一个django应用,能够获取book信息
- 此时的view逻辑为:
- 假设此时后端开发的领导有了如下的要求:
- 需要一个强大的 API 来允许用户按
book
模型中的任何字段进行过滤 - 后续会不断新增表中的字段,并且希望 API 无需修改任何代码即可兼容这些更改
- 任务十分紧急
- ....
- 需要一个强大的 API 来允许用户按
- 这个时候开发十分容易写出如下代码
盲注获取敏感字段
写在前面,修改部分代码模拟一个靶场环境:
- 新增flagbook,其中isbn为敏感字段flag,真是环境flag可能为密码、手机号、token等敏感字段
Book.objects.create(title='flagbook', author='flag book', published_date=date(2020, 4, 15), isbn='flag{secret}')
- 修改后端view代码,不返回isbn字段&调整下代码
- 通过
django filter startwith
进行注入获取flag
具体 django filter
语法可参考 https://docs.djangoproject.com/en/5.0/ref/models/querysets/#id4
- 基础语法,查询
flagbook
数据
- 盲注获取
flag poc
startswith
正确时如下
startswith
错误时如下
- 至此,我们就可以写脚本获取完整的
flag
泄露的条件总结
- 可以控制
filter
过滤列 - ORM支持正则、
startswith
类似操作 - 表中存在一个隐藏的敏感字段
多表关联的情况
在 Django 中,OneToOneField
、ManyToManyField
和 ForeignKey
是用来定义模型之间关系的字段类型。每种字段类型表示不同的数据库关系。
OneToOneField
OneToOneField
表示一对一关系。一个模型实例与另一个模型实例之间有且仅有一个关联。
from django.db import modelsclass UserProfile(models.Model):user = models.OneToOneField(User, on_delete=models.CASCADE)bio = models.TextField()
在这个例子中,每个 UserProfile
实例与一个 User
实例有且只有一个关联。
ManyToManyField
ManyToManyField
表示多对多关系。一个模型实例可以与多个另一个模型实例关联,反之亦然。
class Author(models.Model):name = models.CharField(max_length=100)class Book(models.Model):title = models.CharField(max_length=100)authors = models.ManyToManyField(Author)
在这个例子中,一本书可以有多个作者,一个作者也可以写多本书。
ForeignKey
ForeignKey
表示多对一关系。一个模型实例可以与多个另一个模型实例关联,但反过来每个模型实例只能与一个实例关联。
class Publisher(models.Model):name = models.CharField(max_length=100)class Book(models.Model):title = models.CharField(max_length=100)publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
在这个例子中,一本书只能有一个出版社,但一个出版社可以出版多本书。
关系总结
- OneToOneField: 一对一关系
- ManyToManyField: 多对多关系
- ForeignKey: 多对一关系
demo演示
我们修改model代码如下
from django.db import modelsclass Publisher(models.Model):name = models.CharField(max_length=100)address = models.TextField()def __str__(self):return self.nameclass Category(models.Model):name = models.CharField(max_length=100)def __str__(self):return self.nameclass Book(models.Model):title = models.CharField(max_length=200)author = models.CharField(max_length=100)published_date = models.DateField()isbn = models.CharField(max_length=13, unique=True)publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)categories = models.ManyToManyField(Category)def __str__(self):return self.titleclass BookDetail(models.Model):book = models.OneToOneField(Book, on_delete=models.CASCADE)summary = models.TextField()number_of_pages = models.IntegerField()def __str__(self):return self.book.title
- demo数据如下
import os
import django
import datetime
import randomos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyProject.settings')
django.setup()from BookStore.models import Book, Publisher, Category, BookDetail# 清空旧数据
Publisher.objects.all().delete()
Category.objects.all().delete()
Book.objects.all().delete()
BookDetail.objects.all().delete()# 创建 Publisher 示例数据
publishers = [Publisher.objects.create(name=f'Publisher {i}', address=f'{i} Main St') for i in range(1, 6)
]# 创建 Category 示例数据
categories = [Category.objects.create(name=f'Category {i}') for i in range(1, 6)
]# 创建 Book 示例数据
books = [Book.objects.create(title=f'Book {i}',author=f'Author {i}',published_date=datetime.date(2021, 1, i),isbn=f'{1234567890123 + i}',publisher=random.choice(publishers)) for i in range(1, 6)
]# 添加 Book 到 Category
for book in books:book.categories.add(*random.sample(categories, k=2)) # 随机选择两个分类# 创建 BookDetail 示例数据
for book in books:BookDetail.objects.create(book=book,summary=f'This is the summary for {book.title}.',number_of_pages=random.randint(100, 500))print("Demo data created successfully.")
- 依旧是这个接口逻辑不变
- 一对一的方式,通过bookdetail关联 book 的isbn列数据包
- 多对一的方式,通过book 关联 publishers 的address地址列数据包
- 多对多的方式,通过book 关联 Category的name列数据包
写在最后
其余的一点思考:created_by__user__password__regex
类似这种会不会造成数据库redos攻击!因为之前学习过redos,答案很明显:几乎不大可能会。数据库的正则引擎为有限状态向量机。https://xz.aliyun.com/t/14653?
相关文章:

DjangoORM注入分享
DjangoORM注入 简介 这篇文章中,分享一些关于django orm相关的技术积累和如果orm注入相关的安全问题讨论。 攻击效果同数据库注入 从Django-Orm开始 开发角度 Django ORM(Object-Relational Mapping)是Django框架中用于处理数…...
【HBZ分享】Redis各种类型的数据结构应用场景
String(字符串类型) 计数器: incr / decr, 比如商品库存,业务号的发号器业务数据key-value缓存, 缓存结果数据,提高网站性能,缓解DB压力分布式session会话, 集群环境下存储token鉴权信息分布式锁ÿ…...

anaconda创建并且配置pytorch(完整版)
📚博客主页:knighthood2001 ✨公众号:认知up吧 ** 🎃知识星球:【认知up吧|成长|副业】介绍** ❤️如遇文章付费,可先看看我公众号中是否发布免费文章❤️ 🙏笔者水平有限,欢迎各位大…...
高级java每日一道面试题-2024年8月10日-网络篇-你对跨域了解多少?
如果有遗漏,评论区告诉我进行补充 面试官: 你对跨域了解多少? 我回答: 跨域问题,即Cross-Origin Resource Sharing(CORS),是现代Web开发中一个非常重要的概念,涉及到浏览器的安全策略——同源策略(Same…...

AtCoder Beginner Contest 365 A~E
A.Leap Year(思维) 题意: 给你一个介于 1583 1583 1583和 2023 2023 2023之间的整数 Y Y Y。 求公历 Y Y Y年的天数。 在给定的范围内, Y Y Y年的天数如下: 如果 Y Y Y不是 4 4 4的倍数,则为 365 365 …...

多机部署, 负载均衡-LoadBalance
目录 1.负载均衡介绍 1.1问题描述 1.2什么是负载均衡 1.3负载均衡的一些实现 服务端负载均衡 客户端负载均衡 2.Spring Cloud LoadBalancer 2.1快速上手实现负载均衡 2.2负载均衡策略 自定义负载均衡策略 3.服务部署(Linux) 3.1服务构建打包…...
(回溯) LeetCode 78. 子集
原题链接 一. 题目描述 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的 子集 (幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入:nums [1,2,3] 输出&…...

DQL数据查询语言(多表处理)—/—<7>
一、多表处理 当前有两个表,一个是学生表student,一个是分数表score student表字段名表示如下(共1000条数据): score表字段表示如下(共6000条数据): 1、求每个学生的总分 SELECT …...

力扣刷题总结
去年有段时间一直在刷题,进步神速,解决了以往刷完就忘的问题,这里总结下经验,给有需要的人参考下,核心观点就仨: 1. 打好数据结构与算法基础 2. 多刷题多练习 3. 形成自己的知识体系 下图是我梳理的知识体…...

BLDC ESC 无刷直流电子调速器驱动方式
BLDC ESC 无刷直流电子调速器驱动方式 1. 源由2. 驱动方法2.1 Trapezoidal 1202.2 Trapezoidal 1502.3 Sinusoidal 1802.4 Field-Orientated Control (FOC) 3. FOC(Field-Oriented Control)3.1 引入坐标系3.2 Clarke and Park变换Clarke 变换(…...
解决 IntelliJ IDEA 编译错误 “Groovyc: Internal groovyc error: code 1” 及 JVM 内存配置问题
在使用 IntelliJ IDEA 进行开发时,我们可能会遇到各种编译和运行错误,其中之一就是 Groovy 编译器错误(Groovyc: Internal groovyc error: code 1)或 JVM 内存不足错误。这类错误可能会影响开发效率,但通过调整 JVM 内…...

LeetCode.2940.找到Alice和Bob可以相遇的建筑
友情提示:这个方法并没有通过案例,只通过了944个案例(很难受),超时了,但是想着还是分享出来吧 题目描述: 给你一个下标从 0 开始的正整数数组 heights ,其中 heights[i] 表示第 i …...

OFD板式文件创建JAVA工具-EASYOFD 四、文字 Text
JAVA版本的OFD板式文件创建工具easyofd. 功能包含了图像、 图像、 文字、和模版页功能。同时也支持OFD文件的数字签名及验签,电子签章及验签。 本JAVA版本的easyofd使用原生方式创建板式文件,不依赖JAVA的SWT库。 项目地址:http://…...

【概念速通】李群 lie group
李群 lie group 概念速通 快速示例介绍:【引入】单位复数 (The unit complex numbers) 是李群 (lie group) 最简单的例子之一【进一步】SO(2): The 2D rotation matrices【Typical uses】SE(2): Pose of a robot in the plane Group & Lie Group 定义࿱…...
day_39
198. 打家劫舍 class Solution:def rob(self, nums: List[int]) -> int:if len(nums) 1:return nums[0]dp [0] * len(nums)dp[0], dp[1] nums[0], max(nums[0], nums[1])for i in range(2, len(nums)):dp[i] max(dp[i - 1], dp[i - 2] nums[i])return dp[len(nums) - …...

计算机系统层次结构
1.计算机系统的组成 计算机系统的组成硬件系统软件系统 2.计算机的硬件部分 2.1冯诺依曼机的结构特点: 图示: 1.五大部分由运算器(ALU),控制器(CU),存储器(主存辅存),输入设备,输出设备五大部分组成2.指…...

java语言特点
Java语言是一种广泛使用的编程语言,它具有以下几个显著的特点: 面向对象:Java是一种纯面向对象的语言,它支持类的封装、继承和多态等特性。面向对象的设计使得Java程序更加模块化,易于维护和扩展。 平台无关性…...

单元测试注解:@ContextConfiguration
ContextConfiguration注解 ContextConfiguration注解主要用于在Spring框架中加载和配置Spring上下文,特别是在测试场景中。 它允许开发者指定要加载的配置文件或配置类的位置,以便在运行时或测试时能够正确地构建和初始化Spring上下文。 基本用途和工…...

大数据-72 Kafka 高级特性 稳定性-事务 (概念多枯燥) 定义、概览、组、协调器、流程、中止、失败
点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…...

MySQl 中对数据表的增删改查(基础)
MySQl 中对数据表的增删改查(基础) 新增演示插入一条数据插入多条数据 查询全列查询部分列查询查询关于列名的表达式查询时用别名查询去重后的结果查询排序后的结果条件查询比较运算符和逻辑运算符 分页查询 修改删除 黑白图是在命令行里的,彩…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...

五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...