模糊查询LIKE语句的SQL注入预防

本文介绍了一种在使用MyBatis框架时如何避免SQL注入的方法,特别是针对模糊查询中的LIKE语句。通过实例展示了不当的参数处理可能导致的安全隐患,并提出了使用#符号结合concat函数来有效防止SQL注入。
      一、在iBatis或者myBatis模糊查询的LIKE语句避免采用如下写法,否则会导致SQL注入;
     <select id="INSTITUTIONS-GET-PARAMS" resultMap="INSTITUTIONSDO-MAP" parameterClass="java.util.Map">
		<![CDATA[
		SELECT /*INSTITUTIONS-CLASSIFICATION-GET-ALL-COUNT */ 
			i.id,
			i.institution_name,
			i.institution_short_name,
			i.create_time,
			i.agency_headquarters,
			i.registration_site,
			i.website_url,
			i.brief_introduction,
			i.logo_url,
			i.hot 
		FROM ins i 
		]]>
		<isNotEmpty property="categoryCode">
			LEFT JOIN ins_industry ii 
    			ON i.id = ii.institutionId
 		 	LEFT JOIN ind_type it 
    			ON it.id = ii.typeId 
		</isNotEmpty>
		where 1=1 
		<dynamic>
			<isNotEmpty property="categoryCode"  prepend=" AND ">
				<![CDATA[
				it.category_code = #categoryCode# 
				]]>
			</isNotEmpty>
			<isNotEmpty property="institutionName"  prepend=" AND ">
				i.institution_short_name LIKE '%$institutionName$%' 
			</isNotEmpty>
			ORDER BY i.hot ASC 
			<isNotEmpty property="start">
	    	  LIMIT #start#, 
	    		<isNotEmpty property="size">
	    			#size#
	    		</isNotEmpty>
	    	</isNotEmpty>
		</dynamic>
   </select>

    如上SQL语句,如果用户输入:%' AND 2498=2498 AND '%'=',会构成如下SQL,精简后如下,是能正确返回记录的,即存在SQL注入:
          SELECT 
			i.id,
			i.institution_name,
			i.institution_short_name,
			i.create_time,
			i.agency_headquarters,
			i.registration_site,
			i.website_url,
			i.brief_introduction,
			i.logo_url,
			i.hot 
		FROM ins i 
			LEFT JOIN ins_industry ii 
    			ON i.id = ii.institutionId
 		 	LEFT JOIN ind_type it 
    			ON it.id = ii.typeId 
		where 1=1 AND 
				i.institution_short_name LIKE '%%' AND 2498=2498 AND '%'='%' 
		ORDER BY i.hot ASC LIMIT 0, 10 


     二、解决办法:
           1、尽量避免采用$的方式,$会导致SQL注入,LIKE '%$institutionName$%' 和 LIKE concat('%',$institutionName$,'%') 都会导致SQL注入
           2、尽量采用#的方式,#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号;更详细的可以查看$和#的区别;
           3、对于例子中的模糊查询,可以用#结合concat函数,即修改为LIKE concat('%',#institutionName#,'%') ;
           4、以上只是编码LIKE语句的SQL注入防范,实际中需要对用户输入进行过滤处理;    
### SQL注入中的LIKE操作符用于模糊查询 在SQL语句中,`LIKE`是一个非常有用的工具,可以用来执行基于模式匹配的搜索。当涉及到SQL注入攻击时,如果应用程序构建查询的方式不安全,则可能允许攻击者利用`LIKE`来进行未授权的数据检索[^1]。 #### 使用LIKE进行模糊查询的例子 假设有一个存在漏洞的应用程序通过HTTP GET请求接收参数并直接拼接到SQL查询字符串里: ```sql SELECT * FROM users WHERE username LIKE '%input%'; ``` 这里的`input`是从用户输入获取的内容。如果开发者没有正确地转义特殊字符或者使用预处理语句防止恶意输入的话,那么攻击者就可以构造特定形式的输入以绕过预期的安全控制。 例如,考虑下面这个简单的Python脚本模拟了一个易受攻击的Web应用接口: ```python import sqlite3 def search_user(query_param): conn = sqlite3.connect(':memory:') cursor = conn.cursor() # 创建表结构 create_table_sql = """ CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY, username TEXT UNIQUE NOT NULL ); """ cursor.execute(create_table_sql) # 插入一些测试数据 insert_data_sql = "INSERT INTO users (username) VALUES ('admin'), ('testuser')" cursor.executescript(insert_data_sql) # 构建带有潜在风险的SQL查询 sql_query = f"SELECT * FROM users WHERE username LIKE '%{query_param}%';" results = cursor.execute(sql_query).fetchall() return results # 正常情况下传入合法用户名片段作为查询条件 print(search_user('ad')) ``` 这段代码展示了如何在一个内存数据库中创建表格、插入记录以及执行包含`LIKE`子句的查询。然而,在实际环境中应当避免这种做法;相反应该采用参数化查询或其他适当的方法确保安全性。 为了防范此类问题的发生,建议采取如下措施之一或组合使用: - **参数绑定**:大多数现代编程语言都提供了内置的支持函数库可以帮助我们更方便地实现这一点。 ```python import sqlite3 def safe_search_user(safe_query_param): conn = sqlite3.connect(':memory:') cursor = conn.cursor() ... # 安全方式下的SQL查询 sql_query = "SELECT * FROM users WHERE username LIKE ?;" results = cursor.execute(sql_query, ['%' + safe_query_param + '%']).fetchall() return results ``` - **正则表达式验证**:可以在接收到客户端提交的信息之前先对其进行格式校验,只接受符合规定范围内的值。 - **最小权限原则**:确保运行环境所使用的账户仅具有完成任务所需的最低限度的权利集。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值