欢迎光临
我们一直在努力

Sql注入实际上挂起了我们的系统。我们如何预防SQL注入?

大多数攻击者的目的都是为了赚钱,说白了就是获取有价值的信息并出售,比如用户账号、密码、手机号、身份证信息、银行卡号、地址等敏感信息。

5分钟后,暂时恢复正常。

可以使用代码检测工具(如sqlMap)来检测Sql注入漏洞。

select * fromuserorderbyid选择1 -限制1,20
-下面的limit语句将被注释掉,这将使分页条件无效并返回所有数据。攻击者可以通过此漏洞一次获取所有数据。

Info执行信息,可能包含sql信息。
建议生成环境程序访问的数据库账号和管理员账号分开,一定要控制权限,不能访问系统表。

-1;select * fromuser-
您可以轻松获得用户表中的所有信息。

select * from _ order where id =-1;select * fromuser
如果sql返回数据,则用户表存在,推测是正确的。

而DDL和DCL语句只能由dba的管理员帐户操作。

新的业务请求不能从数据库连接池中连接,除非有太多的数据库连接。
最近在整理安全漏洞相关的问题,准备分享给公司。就在这一次,团队发现了一个sql注入漏洞:在一个公共分页函数中,将排序字段作为参数自定义前端页面。在分页sql的mybatis mapper.xml中,order by字段后使用$符号动态接收计算出的排序参数,可以实现动态排序的功能。

然而,几年前我在老东家的时候,我就没有这么幸运了。

第二步:获取表名。

还有一些攻击者不按常理出牌。sql注入后,他们直接删除系统的表或数据库。

但是这个时候,我还没有找到原因。没办法,只能让运维重启服务。但是,这一次,数据库中的最大连接数增加了,默认值是100。我们当时定的是500,后来调整到了1000。(其实现在大部分公司都把这个参数设为1000)

Sql注入导致数据库连接过多。根本原因是表被长时间锁定。
当like语句中使用一些特殊字符(如%作为参数时,应该对它们进行转义。

数据库连接池不足,没有空闲连接。
我会继续找原因。根据我当时的经验,通常数据库连接太多,可能是忘记关闭连接造成的。但是,仔细检查代码后,没有发现任何问题。我们当时用的数据库连接池会自动回收空闲连接,排除了这种可能。

后来数据库连接太多的问题没有再出现。

select * from user order by ‘ id;选择1 -‘限制1,20
所以不会有sql注入的问题。

一个正常的业务请求从数据库连接池中成功获取连接后,当它需要操作表时,尝试获取表锁,直到超时才能获取。注意,大量的数据库连接可能被占用,无法及时返回。
顺便说一下,如果删除了一个表或者数据库,其实还有一个补救办法,就是从备份文件中恢复,可能只有少量的实时数据丢失,所以一定要有备份机制。

您还可以检查当前的连接状态,以帮助识别有问题的查询语句。(需要注意的是,上图只是我举的一个例子,真实的网上结果并不是这样)

通过这条sql中的信息,我很快找到了相关代码,在查询数据时使用了语句而不是PrepareStatement预编译机制。

攻击者将这样的参数注入SQL:-1;锁定语句。
动态排序的初衷是好的,但是存在sql注入的风险。还好这次发现了问题,及时解决了,没有造成什么损失。

所以建议你加密存储这些敏感信息,可以使用AES对称加密。

Command执行命令,包括:守护进程、查询、睡眠等。
一般我们需要控制网上账户的权限,只允许DML(数据操作语言)数据操作语言语句,包括:选择、更新、插入、删除等。

从以上三个方面可以看出,sql注入问题的危害确实很大。这种问题一定要避免。不要冒险。如果遇到一些不按常理出牌的攻击者,一旦被攻击,可能会损失惨重。

我什么也没说就开始定位问题。首先,我检查了服务器日志,发现了许多异常,并报告了太多的数据库连接。因为支付功能如此重要,当时为了保证支付功能的快速恢复,我们先找了运维重启支付服务的两个节点。

orderby${sortString}
sortString字段的内容是在方法中动态计算的。在这种情况下,不能用#代替$,所以程序会报告一个错误。

%是mysql中的关键词。如果使用like & # 39%% ‘,like条件将无效。

原因很好处理,通过将数据查询地点改为preparestatement预编译机制,最终可以解决问题。

select * from user where name like“%/% %”;
将只返回带有%的用户。

有些攻击者甚至可以直接挂机我们的服务,就像以前的雇主一样。

因为-下面的语句将被注释,那么只有表锁定语句将被执行来锁定表。
有必要捕捉所有异常。记住接口直接返回异常信息,因为有些异常信息包含sql信息,包括数据库名、表名、字段名等。有了这些信息,攻击者就可以通过sql注入任意攻击您的数据库。目前主流的做法是有专门的网关服务,统一公共接口。当用户请求一个接口时,它首先通过该接口,然后将请求转发给业务服务。这样做的好处是可以统一封装返回的数据。如果有异常,可以返回统一的异常信息,隐藏敏感信息。此外,它还可以限制电流和控制权限。

其中,先执行前面的查询语句。
复制dba sql发给我。然后kill -9杀死执行时间长的sql线程。

尽量使用预编译机制,很少使用字符串串联传递参数,这是sql注入问题的根源。

首先,还原事故现场
有一天,小姐姐跑来跟我说,很多用户交不出钱。这个支付服务是老系统了,转手了三个人。一直很稳定,没有任何问题。

但可以确定是sql注入的。

必填的name字段就变得没用了,攻击者就可以获取用户表的所有数据。

selectcode,namefromt_orderwhereid=${id}。
第一步是获取数据库和帐户名。

在运行时,传递的参数将被视为纯文本,不会被重新编译,也不会被视为sql指令。

select * from muserherenamelike“% sue %”;
总的来说,没有问题。

%需要转义:/%。

需要监控数据库sql的执行情况,有异常情况会通过邮件或短信提示。

3.为什么预编译可以防止sql注入?
preparestatement预编译机制在执行sql语句之前对其进行解析、编译和优化,其中占位符用于参数位置?恰恰相反。

动词 (verb的缩写)一些特别的场景呢?
在java中,如果使用mybatis作为持久性框架,那么在mapper.xml文件中,如果使用#作为参数,那么将使用预编译机制。

为生产环境的数据库设置一个单独的帐户,只分配与DML相关的权限,但不能访问系统表。切勿在程序中直接使用管理员帐户。

将返回当前数据库名:sue和帐户名:root@localhost。
事实上,mysql有一些系统表。您可以找到关于我们定制数据库和表格的信息。

代码审查机制的建立可以发现一些隐藏的问题,提高代码质量。

将返回数据库sue下的所有表名。
使用$时有sql注入的风险

-1;Lock语句;-
长时间锁定表后,数据库连接可能会耗尽。

我得到了那个sql并仔细分析了它。我发现一个订单查询语句被攻击者注入到一个长sql中。肯定是大师写的。我没见过一些语法。

这一次,它为我赢得了更多的时间,我请数据库管理员帮我找出原因。

当预编译参数无法使用时,要么打开druid的过滤防火墙,要么自己写代码逻辑过滤掉所有可能的关键字。

果然发现异常查询sql,已经执行了快1个小时了,还没完成。
建议表名不要太简单,要有合适的前缀,比如:t_user。这样可以增加盲目猜测的难度。

不允许使用DDL(数据定义语言)数据库定义语言语句,包括:create、alter、drop等。

-1;deletefromuser-
上述语句将删除用户表中的所有数据。

setGLOBALmax _ connections = 500
无需重启mysql服务即可及时生效。

自己写个util工具过滤掉所有注入的关键字,动态计算时调用这个工具。
如果以阿里的druid作为数据源,可以在filter中打开墙(防火墙),有防止sql注入的功能。但是有一个问题,就是默认情况下不允许多个语句同时操作,批量更新操作也被阻塞,这就需要我们自定义过滤器。
此时,我们需要监控数据库线程。如果某个sql执行时间过长,我们需要一封电子邮件警告。另外,合理设置数据库连接的超时期限也可以稍微缓解这类问题。

select * from user where name like“% % %”;
在这种情况下,预编译机制是正常的,但是sql的执行结果不会返回% users,而是所有用户。

select*fromusername=#{name}
在绝大多数情况下,我们鼓励您使用#来传递引用,这样更安全、更高效。

一次sql注入直接扼杀了我们的支付服务。

-1;dropdatabasetest-
上述语句将删除整个测试数据库的所有内容。

即攻击者根据常识猜测可能的表名。

过了一会儿,另一个节点出现了数据库连接过多的问题。

DCL(数据控制语言)数据库控制语言语句也是不允许的,包括:grant、deny、revoke等。

分享到: 更多 (0)

—— 专注企业营销推广 ——

百度推广抖音运营