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 中对数据表的增删改查(基础) 新增演示插入一条数据插入多条数据 查询全列查询部分列查询查询关于列名的表达式查询时用别名查询去重后的结果查询排序后的结果条件查询比较运算符和逻辑运算符 分页查询 修改删除 黑白图是在命令行里的,彩…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...
