当前位置: 首页 > news >正文

PHP常见的SQL防注入方法

利用Mysqli和PDO

产生原因主要就是一些数据没有经过严格的验证,然后直接拼接 SQL 去查询。导致产生漏洞,比如:

$id = $_GET['id'];
$sql = "SELECT name FROM users WHERE id = $id";

因为没有对 $_GET[‘id’] 做数据类型验证,注入者可提交任何类型的数据,比如 " and 1= 1 or " 等不安全的数据。如果按照下面方式写,就安全一些。

$id = intval($_GET['id']);
$sql = "SELECT name FROM users WHERE id = $id";

把 id 转换成 int 类型,就可以去掉不安全的东西。

验证数据

防止注入的第一步就是验证数据,可以根据相应类型进行严格的验证。比如 int 类型直接通过 intval 进行转换就行:

$id = intval($_GET['id']);

字符处理起来比较复杂些,首先通过 sprintf 函数格式化输出,确保它是一个字符串。然后通过一些安全函数去掉一些不合法的字符,比如:

$str = addslashes(sprintf("%s",$str));

也可以用mysqli_real_escape_string 函数替代 addslashes 这样处理以后会比较安全。当然还可以进一步去判断字符串长度,去防止 [缓冲区溢出攻击] 比如:

$str = addslashes(sprintf("%s",$str));
$str = substr($str,0,40);	//最大长度为40

参数化绑定

参数化绑定,防止 SQL 注入的又一道屏障。php MySQLi 和 PDO 均能提供这样的功能。比如 MySQLi 可以这样去查询:

$mysqli = new mysqli('localhost','my_user','my_password','world');
$stmt = $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?,?,?,?)");
$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;
$stmt->bind_param('sssd',$code,$language,$official,$percent);

PDO 的更是方便,比如:

/* Execute a prepared statement by passing an array of values */
$sql = 'SELECT name,color,calories
FROM fruit
WHERE calories < :calories AND color = :colour';
$sth = $dbh->prepare($sql,array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':calories' => 150, ':colour' => 'red'));
$red = $sth->fetchAll();
$sth->execute(array(':calories' => 175, ':colour' => 'yellow'));
$yellow = $sth->fetchAll();

我们多数使用 php 的框架进行编程,所以最好不要自己拼写 SQL,按照框架给定参数绑定进行查询。遇到较为复杂的 SQL 语句,一定要自己拼写的时候,一定要注意严格的判断。没有用 PDO 或者 MySQLi 也可以自己写个 prepared,比如 wordpress db 查询语句,可以看出也是经过严格的类型验证。

function prepare( $query, $args ){if(is_null($query))return;// This is not meant to be foolproof --	// but it will catch obviously incorrect usage.if(strpos($query,'%') === false){_doing_it_wrong('wpdb::prepare',sprintf(__('The query argument of %s must have a placeholder.'),'wpdb::prepare()'),'3.9');}$args = fun_get_args();array_shift($args);// If args were passed as an array (as in vsprintf), move them upif(isset($args[0]) && is_array($args[0]))$args = $args[0];$query = str_replace("'%s'",'%s',$query);//in case someone mistakenly already singlequoted it$query = str_replace('"%s"','%s',$query);//doublequote unquoting$query = preg_replace('|(?<!%)%f|','%F',$query);	//Force floats to be locale unaware$query = pref_replace('|(?<!%)%s|',"'%s'",$query);//quote the strings,avoiding escaped strings like %%sarray_walk($args,array($this,'escape_by_ref'));return @ vsprintf($query,$args);
}

总结

安全性很重要,也可以看出一个人基本功,项目漏洞百出,扩展性和可维护性再好也没有用。平时多留意,树立安全意识,养成一种习惯,一些基本的安全当然也不会占用 coding 的时间。

养成这个习惯,即便在项目急,时间短的情况下,依然可以做的质量很高,不要等到自己以后负责的东西,数据库都被拿走了,造成损失才重视。

虽然国内很多PHP程序员仍在依靠addslashes防止SQL注入,还是建议大家加强中文防止SQL注入的检查。addslashes的问题在于黑客可以用0xbf27来代替单引号,而addslashes只是将0xbf27修改为0xbf5c27,成为一个有效的多字节字符,其中的0xbf5c仍会被看作是单引号,所以addslashes无法成功拦截。

当然addslashes也不是毫无用处,它是用于单字节字符串的处理,多字节字符还是用mysql_real_escape_string吧。

另外对于php手册中get_magic_quotes_gpc的举例:

if(!get_magic_quotes_gpc()){$lastname = addslashes($_POST[&lsquo;lastname&rsquo;]);
}else{$lastname = $_POST[&lsquo;lastname&rsquo;];
}

最好对magic_quotes_gpc已经开放的情况下,还是对$_POST[‘lastname’]进行检查一下。

再说下mysql_real_escape_string和mysql_escape_string这2个函数的区别:
mysql_real_escape_string 必须在(PHP >= 4.3.0,PHP5)的情况下才能使用。否则只能用mysql_escape_string,两者的区别是:mysql_real_escape_string 考虑到连接的当前字符集,而mysql_escape_string 不考虑。

总结一下:

addslashes() 是强行加;
mysql_real_escape_string() 会判断字符集,但是对PHP版本有要求;
mysql_escape_string不考虑连接的当前字符集。

参考文章链接:
https://mp.weixin.qq.com/s/X6q0xpbnJ9lojIIwNmDzdA

补充:

一:addslashes

php addslashes函数的作用是在预定义的字符前面加上反斜杠,这些预定义字符包括:

单引号(')
双引号(")
反斜杠(\)
NULL

$str="my name's wxp";
echo addslashes($str);//输出my name\'s wxp

然后在拼接mysql字符串:

$sql="insert into student(student_name)values('".addslashes($str)."')";
mysql_query($sql);

此时字符串被插入到数据库,那么大家是否知道插入的字符串是带反斜杠还是不带反斜杠呢?恐怕很多人都会认为肯定是带反斜杠的字符串。其实这个答案是错误的,插入的字符串是没有带反斜杠。至于为什么插入的字符串在数据库中是没有加反斜杠,请大家继续看下面讲解。

如果字符串$str="my name’s wxp"是使用POST和GET提交的数据,这个时候插入数据库中的数据是带反斜杠的,由此可知addslashes只是在POST和GET数据插入数据库时才会把反斜杠同时插入到数据库,其他情况下不会将反斜杠插入到数据库。

注释:默认地,PHP 对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。所以您不应对已转义过的字符串使用 addslashes(),因为这样会导致双层转义。遇到这种情况时可以使用函数 get_magic_quotes_gpc() 进行检测

参考:
原文链接:https://blog.csdn.net/MengJing_/article/details/89353942

二:mysql_real_escape_string

mysql_real_escape_string
(PHP 4 >= 4.3.0, PHP 5)

mysql_real_escape_string — 将字符串中的特殊字符进行转义,以在 SQL 语句中使用

警告 本扩展自 PHP 5.5.0 起已废弃,并在自 PHP 7.0.0 开始被移除。应使用 MySQLi 或 PDO_MySQL
扩展来替换之。参见 MySQL:选择 API 指南来获取更多信息。用以替代本函数的有:
mysqli_real_escape_string() PDO::quote()

说明

mysql_real_escape_string(string $unescaped_string, resource $link_identifier = NULL): string

考虑到连接的当前字符集,对 unescaped_string 进行特殊字符转义,以便安全地将其放置在 mysql_query() 中。如果要插入二进制数据,则必须使用此函数。

mysql_real_escape_string() 调用 mysql 库的函数 mysql_real_escape_string, 在以下字符前添加反斜线:\x00、\n、\r、\、'、" 和 \x1a.

在向 MySQL 发送查询之前,必须始终(有少数例外)使用此函数来确保数据的安全。

警告
安全: 默认字符集 The character set must be set either at the server level,or with the API function mysql_set_charset() for it to affect mysql_real_escape_string(). See the concepts section on character sets for more information.

示例:

<?php
// Connect
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')OR die(mysql_error());// Query
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",mysql_real_escape_string($user),mysql_real_escape_string($password));
?>
三:mysql_escape_string

mysql_escape_string
(PHP 4 >= 4.0.3, PHP 5)

mysql_escape_string — 转义字符串用于 mysql_query

警告 本函数自 PHP 4.3.0 起已废弃,并且它和整个 MySQL 扩展自 PHP 7.0.0 开始被移除。 可以选择出于活跃开发中的MySQLi 或 PDO_MySQL 扩展来作为替代。 参见 MySQL:选择 API 指南来获取更多信息。用以替代本函数的有:mysqli_escape_string() PDO::quote()

说明

mysql_escape_string(string $unescaped_string): string

本函数将转义 unescaped_string,使之可以安全用于 mysql_query()。此函数已弃用。

本函数和 mysql_real_escape_string() 相同,除了 mysql_real_escape_string() 接受连接处理程序并根据当前字符集进行转义。mysql_escape_string() 不接受连接参数,也不遵循当前字符集设定。

示例

<?php
$item = "Zak's Laptop";
$escaped_item = mysql_escape_string($item);
printf("Escaped string: %s\n", $escaped_item);
?>

以上示例会输出:

Escaped string: Zak\'s Laptop

注意:
mysql_escape_string() 不转义 % 和 _。

相关文章:

PHP常见的SQL防注入方法

利用Mysqli和PDO 产生原因主要就是一些数据没有经过严格的验证&#xff0c;然后直接拼接 SQL 去查询。导致产生漏洞&#xff0c;比如&#xff1a; $id $_GET[id]; $sql "SELECT name FROM users WHERE id $id";因为没有对 $_GET[‘id’] 做数据类型验证&#xf…...

分布式和中间件等

raft协议 paxos算法ddos 如何避免?怎么预防?怎么发现?利用了TCP什么特点?怎么改进TCP可以预防?服务端处理不了的请求怎么办?连接数最大值需要设置吗?怎么设置? Thrift RPC过程是什么样子的?异构系统怎么完成通信?跟http相比什么优缺点?了解grpc吗?kafka topic part…...

通过http发送post请求的三种Content-Type分析

通过okhttp向服务端发起post网络请求&#xff0c;可以通过Content-Type设置发送请求数据的格式。 常用到的三种&#xff1a; 1&#xff09;application/x-www-form-urlencoded; charsetutf-8 2&#xff09;application/json; charsetutf-8 3&#xff09;multipart/form-dat…...

Vue中的自定义指令详解

文章目录 自定义指令自定义指令-指令的值&#xff08;给自定义指令传参数&#xff09; 自定义指令 自定义指令&#xff1a;自己定义的指令&#xff0c;可以封装一些dom 操作&#xff0c;扩展额外功能&#xff08;自动聚焦&#xff0c;自动加载&#xff0c;懒加载等复杂的指令封…...

[管理与领导-100]:管理者到底是什么?调度器?路由器?交换机?监控器?

目录 前言&#xff1a; 二层交换机 三层路由器 监视器&#xff08;Monitor&#xff09; 调度器 前言&#xff1a; 人在群体中&#xff0c;有点像设备在网络中&#xff0c;管理者到底承担什么的功能&#xff1f; 二层交换机 交换机是计算机网络中&#xff0c;用于连接多台…...

保研CS/软件工程/通信问题汇总

机器学习 1.TP、TN、FP、FN、F1 2.机器学习和深度学习的区别和联系 模型复杂性&#xff1a;深度学习是机器学习的一个子领域&#xff0c;其主要区别在于使用深层的神经网络模型。深度学习模型通常包含多个隐层&#xff0c;可以学习更加复杂的特征表示&#xff0c;因此在某些任…...

word、excel、ppt转为PDF

相关引用对象在代码里了 相关依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.0.1</version></dependency> <dependency><groupId>org.apache.poi</group…...

2023华为杯D题——基于Kaya模型的碳排放达峰实证研究

一、前言 化石能源是推动现代经济增长的重要生产要素&#xff0c;经济生产活动与碳排放活动密切相关。充分认识经济增长与碳排放之间的关系对转变生产方式&#xff0c;确定碳达峰、碳中和路径极为必要。本研究在对经济增长与碳排放关系现有研究梳理的基础上&#xff0c;系统地分…...

有哪些好用的上网行为管理软件?(上网行为管理软件功能好的软件推荐)

随着互联网的快速发展&#xff0c;企业的信息化管理和员工的上网行为已经成为企业信息化建设的重要组成部分。上网行为管理软件作为一种新型的管理工具&#xff0c;可以帮助企业实现对员工上网行为的管控和优化&#xff0c;进而提高企业的工作效率和网络安全。本文将对多款市场…...

npm install报错 code:128

报的错误: npm ERR! code 128 npm ERR! An unknown git error occurred npm ERR! command git --no-replace-objects ls-remote ssh://gitgithub.com/nhn/raphael.git npm ERR! gitgithub.com: Permission denied (publickey). npm ERR! fatal: Could not read from remote re…...

爬虫 — Scrapy 框架(一)

目录 一、介绍1、同步与异步2、阻塞与非阻塞 二、工作流程三、项目结构1、安装2、项目文件夹2.1、方式一2.2、方式二 3、创建项目4、项目文件组成4.1、piders/__ init __.py4.2、spiders/demo.py4.3、__ init __.py4.4、items.py4.5、middlewares.py4.6、pipelines.py4.7、sett…...

Python编程语言学习笔记

目录 1 书写格式1.1 程序框架格式1.1 注释1.2 保留字 2 数据2.1 整数类型2.2 浮点类型2.3 复数类型2.4 数值运算符2.5 数值运函数2.6 数值类型转换函数2.7 math 库2.8 字符串2.8.1 字符串的表示2.8.2 字符串的区间访问2.8.3 字符串操作符2.8.4 字符串操作函数 2.9 字符串类型的…...

【运维面试100问】(三)说说你在故障排除方面的经历

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…...

Postman 全局配置接口路径变量等

Postman 全局配置接口路径变量等 一、简介 这里主要是介绍通过配置postman接口测试工具&#xff0c;简化每次新增模块等接口时修改url的繁琐过程&#xff0c;方便以后查阅&#xff01;&#xff01;&#xff01; 二、全局变量设置 1、新增测试环境 新增测试环境 2、接口集合设…...

一文掌握CodiMD安装与使用

简介&#xff1a;CodiMD 是一个基于 Markdown 语言的实时协作文档编辑器&#xff0c;它允许多个用户在同一个文档上进行实时编辑。CodiMD 的前身是 HackMD&#xff0c;但为了满足更开放的开源社区需求&#xff0c;CodiMD 作为其社区版本独立出来。 优势&#xff1a; 1. 开源且…...

无人机顶会顶刊2023

无人机顶会顶刊2023 国际期刊1、Science Robotics2、IEEE Transactions on Robotics(TRO)3、IEEE Transactions on Automation Science and Engineering&#xff08;TASE&#xff09;4、International Journal of Robotics Research(IJRR)5、IEEE Robotics and Automation Lett…...

【Java毕设项目】基于SpringBoot+Vue校园便利平台的设计与实现

博主主页&#xff1a;一季春秋博主简介&#xff1a;专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发&#xff0c;远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容&#xff1a;毕业设计(Java项目、小程序等)、简历模板、学习资料、面试题…...

03Nginx的静态资源部署,反向代理,负载均衡,动静分离的配置

Nginx具体应用 部署静态资源 Nginx相对于Tomcat处理静态资源的能力更加高效,所以在生产环境下一般都会将Nginx可以作为静态web服务器来部署静态资源 静态资源: 在服务端真实存在并且能够直接展示的一些html页面、css文件、js文件、图片、视频等资源文件将静态资源部署到Ngin…...

刷题笔记24——完全二叉树的节点个数

有些事情是不能告诉别人的,有些事情是不必告诉别人的,有些事情是根本没有办法告诉别人的,而且有些事情是,即使告诉了别人,你也会马上后悔的。——罗曼罗兰 222. 完全二叉树的节点个数 java的幂运算要 (int) Math.pow(2,l1)-1计算满二叉树的节点数量公式&#xff1a;2 ^ height…...

sentinel环境搭建以及微服务接入

• sentinel部署 • sentinel-镜像制造 • sentinel-镜像推送 • sentinel-部署配置文件 • 访问控制台 • 外网访问控制台 • 集群内访问 • 配置规则 • 限流效果 • 微服务接入 • pom文件引入依赖 • pod部署文件添加配置 Sentinel 控制台是流量控制、熔断降级规则统一配置…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...