SQL注入(execute()之下)

使用pymysql模块操作验证注册登陆时,字符串拼接易导致SQL注入问题,用户可绕开账户密码进入数据库。如利用mysql注释语法 '--' 可绕过密码或用户与密码验证。解决办法是让execute做字符串拼接,按pymysql规矩操作,去掉%s引号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在用pymysql模块操作验证注册登陆的时候,涉及字符串拼接时容易出现明明账户密码不对的情况sql语句还是可以被执行,这样就导致用户可以绕开账户密码就能进入数据库。废话不说,看图:
在这里插入图片描述
sql代码为:

user = input('账户:').strip()
    pwd = input('密码:').strip()
    sql = 'select * from register where name = "%s" and pwd ="%s"' %(user,pwd)
    res = cursor.execute(sql)
    if res == 1:
     	print('登陆成功')
     	print(cursor.fetchall())
 	else:
     	print('登陆失败')

换另一种‘错误’的账号看结果:
在这里插入图片描述
上面’账户‘至少mcc还是正确的,再来一个’完全不沾边‘的账户
在这里插入图片描述
原因是什么呢?

根本原因在于mysql的注释语法 – ,上面的两张图显示了两种sql注入情况,第一种是用户存在,绕过密码,第二种情况用户不存在,绕过用户与密码

看一下第一种情况的sql语句:

select * from register where name = "mcc" -- sdadadf" and pwd =""

数据库中,-- 后的所有内容都被注释掉,即使再输入密码也是没用的,最后的sql语句是select * from register where name = “mcc”,这句sql语句可以被正确执行,也能查出mcc的结果

select * from register where name = "xxx" or 1=1 -- saddjna" and pwd =""

在数据库中,-- 后面的条件全部被注释掉,where 的过滤条件就剩name=“xxx” or 1=1,1=1显然永远成立,where的最终过滤条件就是True,sql执行的就是select * from register 。

解决方法
原来是我们对sql进行字符串拼接
sql=‘select * from register where name="%s" and password="%s"’ %(user,pwd)

res=cursor.execute(sql)

#改写为(execute帮我们做字符串拼接,我们无需且一定不能再为%s加引号了)

sql="select * from register where name=%s and password=%s" 

#!!!注意%s需要去掉引号,因为pymysql会自动为我们加上
res=cursor.execute(sql,[user,pwd]) #pymysql模块自动帮我们解决sql注入的问题,只要我们按照pymysql的规矩来。

### SQL 注入攻击在 HTTP Headers 中的表现及防范方法 SQL 注入SQL Injection)是一种常见的安全漏洞,攻击者通过向应用程序的输入字段注入恶意 SQL 代码来操纵数据库。虽然大多数 SQL 注入攻击发生在 URL 参数或表单提交中,但 HTTP Headers 同样可能成为攻击媒介。例如,攻击者可以利用 `User-Agent`、`Referer` 或自定义头部(如 `X-Requested-With`)注入恶意 SQL 语句。 #### 攻击方式 1. **HTTP Header 注入示例** 假设某个 Web 应用程序将 `User-Agent` 头部直接拼接到 SQL 查询中,例如记录访问者的浏览器信息: ```sql INSERT INTO user_agents (user_agent) VALUES ('" + request.headers['User-Agent'] + "'); ``` 如果攻击者修改 `User-Agent` 的值为 `' OR '1'='1`, 则可能导致 SQL 查询被篡改,从而引发数据泄露或其他恶意行为 [^1]。 2. **联合查询注入** 攻击者可以在 HTTP Headers 中注入额外的 SQL 子句,例如: ```http User-Agent: Mozilla/5.0 ' UNION SELECT username, password FROM users -- ``` 这种方式可能导致数据库返回敏感信息 [^1]。 3. **盲注(Blind SQL Injection)** 在某些情况下,攻击者无法直接看到数据库错误信息,但可以通过时间延迟或布尔逻辑判断数据库结构,例如: ```http User-Agent: Mozilla/5.0 ' AND IF(1=1, SLEEP(5), 0) -- ``` 通过观察响应延迟,攻击者可推测后端数据库逻辑 [^1]。 #### 防范方法 1. **使用参数化查询(Prepared Statements)** 最有效的防范措施是避免直接拼接 SQL 查询字符串。应使用参数化查询来确保用户输入不会被解释为 SQL 命令。例如在 Python 中使用 `cursor.execute()`: ```python cursor.execute("INSERT INTO user_agents (user_agent) VALUES (%s)", (user_agent,)) ``` 2. **输入验证与过滤** 对所有来自 HTTP Headers 的输入进行白名单验证,确保其格式符合预期。例如限制 `User-Agent` 字符集,拒绝包含特殊 SQL 关键字(如 `UNION`, `SELECT`, `DROP`)的内容 [^1]。 3. **最小权限原则** 数据库账户应仅具有执行必要操作的最小权限。例如,用于插入日志的账户不应具备读取用户密码的权限 [^1]。 4. **错误信息处理** 不应将详细的数据库错误信息暴露给客户端。应在服务器端记录错误,并向用户返回通用错误提示,以防止攻击者利用错误反馈进行探测 [^1]。 5. **使用 Web Application Firewall(WAF)** 部署 WAF 可以检测并拦截常见的 SQL 注入模式,例如检测到 `UNION SELECT` 或 `SLEEP()` 等关键字时阻止请求 [^1]。 6. **定期更新依赖库和框架** 使用成熟的 Web 框架(如 Flask、Django)并保持其更新,因为这些框架通常内置了对常见攻击的防护机制 [^2]。 7. **日志审计与监控** 记录所有异常请求,特别是涉及敏感操作的日志。设置警报机制,当检测到可疑 SQL 模式时及时通知管理员 。 ### 示例:Flask 中的安全防护 在 Flask 中,可以结合 SQLAlchemy 实现参数化查询,同时使用 `Werkzeug` 提供的转义函数来处理输入: ```python from flask import Flask, request from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) db = SQLAlchemy(app) @app.route('/') def index(): user_agent = request.headers.get('User-Agent') # 安全地插入用户代理信息 db.session.execute("INSERT INTO user_agents (user_agent) VALUES (:ua)", {'ua': user_agent}) db.session.commit() return "Logged" ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值