请选择 进入手机版 | 继续访问电脑版

专注代码检测 - 阅镜

 找回密码
 立即注册
热搜: 安装 代码
查看: 113|回复: 0

SQL操作安全

[复制链接]

70

主题

70

帖子

232

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
232
发表于 2021-9-12 14:38:38 | 显示全部楼层 |阅读模式
【必须】使用参数化查询
  • 使用参数化SQL语句,强制区分数据和命令,避免产生SQL注入漏洞。

  1. # 错误示例
  2. import mysql.connector

  3. mydb = mysql.connector.connect(
  4. ... ...
  5. )

  6. cur = mydb.cursor()
  7. userid = get_id_from_user()
  8. # 使用%直接格式化字符串拼接SQL语句
  9. cur.execute("SELECT `id`, `password` FROM `auth_user` WHERE `id`=%s " % (userid,))
  10. myresult = cur.fetchall()
  11. # 安全示例
  12. import mysql.connector

  13. mydb = mysql.connector.connect(
  14. ... ...
  15. )
  16. cur = mydb.cursor()
  17. userid = get_id_from_user()
  18. # 将元组以参数的形式传入
  19. cur.execute("SELECT `id`, `password` FROM `auth_user` WHERE `id`=%s " , (userid,))
  20. myresult = cur.fetchall()
复制代码

  • 推荐使用ORM框架来操作数据库,如:使用SQLAlchemy。

  1. # 安装sqlalchemy并初始化数据库连接
  2. # pip install sqlalchemy
  3. from sqlalchemy import create_engine
  4. # 初始化数据库连接,修改为你的数据库用户名和密码
  5. engine = create_engine('mysql+mysqlconnector://user:password@host:port/DATABASE')
  6. # 引用数据类型
  7. from sqlalchemy import Column, String, Integer, Float
  8. from sqlalchemy.ext.declarative import declarative_base

  9. Base = declarative_base()
  10. # 定义 Player 对象:
  11. class Player(Base):
  12.     # 表的名字:
  13.     __tablename__ = 'player'

  14.     # 表的结构:
  15.     player_id = Column(Integer, primary_key=True, autoincrement=True)
  16.     team_id = Column(Integer)
  17.     player_name = Column(String(255))
  18.     height = Column(Float(3, 2))
  19. # 增删改查
  20. from sqlalchemy.orm import sessionmaker
  21. # 创建 DBSession 类型:
  22. DBSession = sessionmaker(bind=engine)
  23. # 创建 session 对象:
  24. session = DBSession()

  25. # 增:
  26. new_player = Player(team_id=101, player_name="Tom", height=1.98)
  27. session.add(new_player)
  28. # 删:
  29. row = session.query(Player).filter(Player.player_name=="Tom").first()
  30. session.delete(row)
  31. # 改:
  32. row = session.query(Player).filter(Player.player_name=="Tom").first()
  33. row.height = 1.99
  34. # 查:
  35. rows = session.query(Player).filter(Player.height >= 1.88).all()

  36. # 提交即保存到数据库:
  37. session.commit()
  38. # 关闭 session:
  39. session.close()
复制代码


【必须】对参数进行过滤
将接受到的外部参数动态拼接到SQL语句时,必须对参数进行安全过滤。
  1. def sql_filter(sql, max_length=20):
  2.     dirty_stuff = [""", "\", "/", "*", "'", "=", "-", "#", ";", "<", ">", "+",
  3.                    "&", "[        DISCUZ_CODE_2        ]quot;, "(", ")", "%", "@", ","]
  4.     for stuff in dirty_stuff:
  5.         sql = sql.replace(stuff, "x")
  6.     return sql[:max_length]
复制代码
回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

QQ|Archiver|手机版|小黑屋| 阅镜 ( 京ICP备2020034574号 )|网站地图|网站地图点击这里给我发消息

GMT+8, 2022-1-17 09:54 , Processed in 0.069455 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表