码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • SQL Injection 防御——预编译


    目录

    (一)Reference:

    形成原因:

    (二)什么是预处理

    1、普通的SQL语句执行过程

    2、预处理执行过程

    2.1 把SQL语句分成两部分,命令部分和数据部分

    2.2 先把命令部分发送给MySQL服务端,MySQL服务端进行SQL预编译(?占位符)

     2.3 然后把数据部分发送给MySQL服务端,MySQL服务端对SQL语句进行占位符替换

     2.4  MySQL服务端执行完整的SQL语句并将结果返回给客户端

    总结:

     3、代码实现

    1、数据库开启Log

    2、服务端代码


             由于笔者个人水平有限,行文如有不当,还请各位师傅评论指正,非常感谢

    (一)Reference:


    https://dev.mysql.com/doc/refman/5.7/en/sql-prepared-statements.html
    https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat _Sheet.htm

            本篇文章主要介绍预编译,首先 回顾 SQL 注入发生的原因

    形成原因:

     用户输入的数据作为代码执行了

    1. 用户能控制传参
    2. SQL语句中拼接了用户传参的内容
    3. 拼接后的SQL语句必须能在数据库中执行
    1. def bypass_from_param(string):
    2. sql_string = "select * from products where category = '{}' and released = 0".format(string) print(sql_string)
    3. if __name__ == '__main__':
    4. bypass_from_param("Gifts'")

    (二)什么是预处理


    1、普通的SQL语句执行过程


    1. 客户端对SQL语句进行占位符替换得到完整的SQL语句
    2. 客户端发送完整SQL语句到MySQL服务端
    3. MySQL服务端执行完整的SQL语句并将结果返回给客户端

    总结:

             一次编译,单次运行,此类普通语句被称作 Immediate Statements (即时 SQL)

    2、预处理执行过程


    2.1 把SQL语句分成两部分,命令部分和数据部分

    2.2 先把命令部分发送给MySQL服务端,MySQL服务端进行SQL预编译(?占位符)

     2.3 然后把数据部分发送给MySQL服务端,MySQL服务端对SQL语句进行占位符替换

     2.4  MySQL服务端执行完整的SQL语句并将结果返回给客户端

            处理后的数据就成这样:

    总结:

             所谓预编译语句就是将此类 SQL 语句中的值用占位符替代,可以视为将 SQL 语句模板化或者说参数化,一般称这类语句叫Prepared Statements

     3、代码实现


    1. # 定义预处理语句 PREPARE stmt_name FROM preparable_stmt;
    2. # 执行预处理语句 EXECUTE stmt_name [USING @var_name [, @var_name] ...];
    3. # 删除(释放)定义 {DEALLOCATE | DROP} PREPARE stmt_name;
    4. # 验证 use sql_inject;
    5. prepare select_content from 'select id,name,content,
    6. released from products where category = ? and released = ?';
    7. set @a='Gifts'
    8. set @b=0
    9. execute select_content using @a,@b;

            假如我们a输入的是Gifts'#,输出的数据是空,原因很简单SQL语句之前已经编译过了,现在传入的是参数,表里没有Gift'#的参数,所以返回的是空。

    1、数据库开启Log

    1. vim /etc/mysql/mysql.conf.d/mysqld.cnf
    2. general_log=on
    3. general_log_file=/tmp/mysql.log
    4. # 查看log tail -f /tmp/mysql.log

    2、服务端代码

    1. package api
    2. import (
    3. "log"
    4. "net/http"
    5. "sql_injection/model"
    6. "github.com/gin-gonic/gin"
    7. )
    8. func ProductsHandler(c *gin.Context) {
    9. a := c.Query("category")
    10. s := c.Query("released")
    11. log.Println(a)
    12. //sqlStr := fmt.Sprintf(`select id,name,content,released from products where category = '%s' and released = %s`, a, s)
    13. // 预编译模板
    14. sqlStr := "select id,name,content,released from products where category = ? and released = ? "
    15. log.Println(sqlStr)
    16. stmt, err2 := model.DB.Prepare(sqlStr)
    17. if err2 != nil {
    18. c.JSON(http.StatusOK, gin.H{
    19. "code": 404, "err":
    20. err2.Error(),
    21. "msg": "error",
    22. })
    23. return
    24. }
    25. rows, err := stmt.Query(a, s)
    26. if err != nil {
    27. c.JSON(http.StatusOK,
    28. gin.H{
    29. "code": 404,
    30. "err": err.Error(),
    31. "msg": "error", })
    32. return }
    33. var r []model.Product
    34. for rows.Next() {
    35. var p model.Product
    36. if rowErr := rows.Scan(&p.Id, &p.Name, &p.Content, &p.Released); rowErr != nil
    37. {
    38. c.JSON(200, gin.H{
    39. "code": 404,
    40. "err": rowErr.Error(),
    41. "msg": "error",
    42. })
    43. }r = append(r, p)
    44. }
    45. c.JSON(
    46. 200, gin.H{
    47. "code": 0,
    48. "data": r,
    49. "msg": "success",
    50. })
    51. }
    预处理有什么好处:
    1. 优化MySQL服务器重复执行SQL的方法,可以提升服务器性能,提前让服务器编译,一次编译多次执行,节省后续编译的成本
    2. 避免SQL注入
  • 相关阅读:
    [附源码]Java计算机毕业设计SSM东北鹿产品售卖网站
    【算法】最短路径——迪杰斯特拉 (Dijkstra) 算法
    Elasticsearch(macbook搭建,Elasticsearch+kibana)一步到位
    【16】c++11新特性 —>弱引用智能指针weak_ptr(1)
    基于算能的国产AI边缘计算盒子8核心A53丨17.6Tops算力
    Rodrigues:旋转矩阵的向量表达
    1336:【例3-1】找树根和孩子
    JVM第十八讲:调试排错 - Java 问题排查之工具单
    2018.7-2019.7一周年Java进阶架构师技术文章整理 建议收藏
    CentOS 9 Stream 上安装 WebStorm
  • 原文地址:https://blog.csdn.net/m0_61506558/article/details/126913694
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号