SQL注入五孔不入,尽管是老技术了,但是依然是重点防护的手段,更多的需要我们数据库开发者细心!!
数据表的演练

1 创建数据表

create database jing_dong charset=utf8;
-- 使用 jing_dong数据库
use jing_dong;
create table goods(id int unsigned primary key auto_increment not null,name varchar(150) not null,cate_name varchar(40) not null,brand_name varchar(40) not null,price decimal(10,3) not null default 0,is_show bit not null default 1,is_saleoff bit not null default 0
);
-- 展示数据库
show tables;
-- 插入数据
INSERT INTO `goods` VALUES (1, '联想(Lenovo)天逸510S 个人商务台式机电脑整机(i3-10100 8G 512G', '笔记本', '华硕', 2324.000, b'0', b'0');
INSERT INTO `goods` VALUES (2, '戴尔dell成就3690 商用办公台式机电脑主机(11代i5-11400 16G', '笔记本', '联想', 4234.000, b'0', b'0');
INSERT INTO `goods` VALUES (3, '联想(Lenovo)天逸510S 个人商务台式机电脑整机(i5-10400 16G 1T+256G SSD', '游戏本', '索尼', 2342.000, b'0', b'0');
INSERT INTO `goods` VALUES (4, '武极天机 i5 10400F/GTX1050Ti/游戏台式办公电脑主', '超极本', '苹果', 4655.000, b'0', b'0');
INSERT INTO `goods` VALUES (5, '荣耀笔记本 MagicBook X 14 2021 14英寸全面屏轻薄笔记本电脑 (i3 10110U 8GB', '笔记本', '苹果', 1233.000, b'0', b'0');
INSERT INTO `goods` VALUES (6, '戴尔Dell成就3000 办公商用家用台式机电脑英特尔十代处理器学习财务', '平板电脑', '戴尔', 3434.000, b'0', b'0');
INSERT INTO `goods` VALUES (7, '戴尔笔记本电脑dell灵越15-3501 15.6英寸高性能轻薄商务笔记本电脑(11代英特', '台式机', '华硕', 2344.000, b'0', b'0');
INSERT INTO `goods` VALUES (8, '联想(Lenovo)扬天M4000q英特尔酷睿i3 商用台式机电脑整机(i3-10100', '平板电脑', '联想', 4543.000, b'0', b'0');
INSERT INTO `goods` VALUES (9, '联想ThinkPad E15 2021款 酷睿版 英特尔酷睿i5/i7 轻薄笔记本电脑 人', '台式机', '苹果', 3455.000, b'0', b'0');
INSERT INTO `goods` VALUES (10, '硕扬 i5 10400F/八核/GTX1050TI 4G/32G内存游戏台式吃鸡', '台式机', '索尼', 2455.000, b'0', b'0');
INSERT INTO `goods` VALUES (11, '惠普(HP)小欧高清一体机电脑21.5英寸(J4025 4G 256SSD UMA 无线', '笔记本', '华硕', 7899.000, b'0', b'0');-- 查询为超极本的商品
select *from goods where cate_name="超极本";-- 但是我只想看商品品名称和价格
select name,price from goods where cate_name="超极本";-- 但是我不认识英文怎么办,设置一个中文的对话框
select name as 名字,price as 价格 from goods where cate_name="超极本";-- 显示商品种类
select name,cate_name from goods;-- 我想看所有的电脑的分类,全部类别用distinct进行实现
select distinct cate_name from goods;-- 我想看所有的电脑的分类,用分组来进行实现
select cate_name from goods group by cate_name;-- 我想看电脑的分类并且要加上名字,用分组来进行实现
select cate_name,group_concat(name) from goods group by cate_name;-- 求所有电脑产品的平均价格
select avg(price) from goods;-- 求所有电脑产品的平均价格,并保留两位小数
select round(avg (price),2) from goods;-- 显示每种类别商品的平均价格
select cate_name ,avg(price) from goods group by cate_name;-- 查询每种类型的商品中最贵的,最便宜的,平均价,数量
select cate_name, max(price) ,min(price) ,avg(price),count(*) from goods group by cate_name;-- 查询所有价格大于平均价格的商品,并且按价格降序排序
select id,name,price from goods where price> (select round (avg(price),2) as avg_price from goods) order by price desc;-- 查询每种商品中最贵的电脑信息
select * from goods
inner join(selectcate_name,max(price) as max_price,min(price) as min_price,avg(price) as avg_price,count(*) from goods group by cate_name )as goods_new_info
on goods.cate_name=goods_new_info.cate_name and goods.price=goods_new_info.max_price;
-- 思路,把第一次上面的查询语句看作一个表,用下面的检索条件进行适配,名字相等 价格相等,那么就直接输出出来,相当于两张表合并查询
-- 或者也可以有这种写法(表级的查询)
select *from(select cate_name,max(price) as max_price from goods group by cate_name )as g_new
left join goods as g
on g_new.cate_name =g.cate_name and g_new.max_price =g.price;

最后一个的输出结果为:

+----+----------------------------------------------------------------------+-----------+------------+----------+---------+------------+-----------+-----------+-----------+--------------+----------+
| id | name                                                                 | cate_name | brand_name | price    | is_show | is_saleoff | cate_name | max_price | min_price | avg_price    | count(*) |
+----+----------------------------------------------------------------------+-----------+------------+----------+---------+------------+-----------+-----------+-----------+--------------+----------+
|  3 | 联想(Lenovo)天逸510S 个人商务台式机电脑整机(i5-10400 16G 1T+256G SSD | 游戏本    | 索尼       | 2342.000 |         |            | 游戏本    |  2342.000 |  2342.000 | 2342.0000000 |        1 |
|  4 | 武极天机 i5 10400F/GTX1050Ti/游戏台式办公电脑主                      | 超极本    | 苹果       | 4655.000 |         |            | 超极本    |  4655.000 |  4655.000 | 4655.0000000 |        1 |
|  8 | 联想(Lenovo)扬天M4000q英特尔酷睿i3 商用台式机电脑整机(i3-10100       | 平板电脑  | 联想       | 4543.000 |         |            | 平板电脑  |  4543.000 |  3434.000 | 3988.5000000 |        2 |
|  9 | 联想ThinkPad E15 2021款 酷睿版 英特尔酷睿i5/i7 轻薄笔记本电脑 人     | 台式机    | 苹果       | 3455.000 |         |            | 台式机    |  3455.000 |  2344.000 | 2751.3333333 |        3 |
| 11 | 惠普(HP)小欧高清一体机电脑21.5英寸(J4025 4G 256SSD UMA 无线         | 笔记本    | 华硕       | 7899.000 |         |            | 笔记本    |  7899.000 |  1233.000 | 3922.5000000 |        4 |
+----+----------------------------------------------------------------------+-----------+------------+----------+---------+------------+-----------+-----------+-----------+--------------+----------+

查询各个电脑种类的最大价格

select cate_name ,max(price) from goods group by cate_name;

数据库高级演练 拆分为多个表

-- 创建商品分类
create table if not exists goods_cates(id int unsigned primary key auto_increment,name varchar(48) not null
);-- 查看之前的goods表单中的所有分类
select cate_name from goods group by cate_name;--将分组结果写入goods_cates 数据表中insert into goods_cate(name) select cate_name from goods group by cate_name;-- 同步表数据 通过goods_cates 数据表来更新goods表  更新goods 中的cate_name用第二张表来进行更新
update goods as g inner join goods_cates as c on g.cate_name=c.name set g.cate_name =c.id;-- 我们发现主键的goods与goods_cates类型并不是一样的,这里我们就需要改变一下类型
alter table goods change cate_name cate_id int unsigned not null;-- 插入关联,将cate_id 追加约束外键
alter table goods add foreign key(cate_id)  references goods_cates(id);-- 如何取消外键
alter table goods drop foreign key 外键名称;

pymysql 连接的过程

开始 ==> 创建connection > 获取cursor (游标对象)> 执行查询 执行命令 获取数据 处理数据 ==> 关闭cursor ==> 关闭 connection ==> 结束

import pymysql
#创建connect链接数据库
connect = pymysql.connect(host="localhost",port=3306,user='root',password='200228',database='jing_dong',charset='utf8')
#获得游标对象 cursor
cs1= connect.cursor()
#执行SQL语句中的select 并返回受影响的行数,查找一条数据
count =cs1.execute('select id,name from goods where id>=4')
print(count)
for i in range(count):#获取查询结果result = cs1.fetchone()#打印查询的结果print(result)
#关闭cursor对象
cs1.close()
#关闭连接
connect.close()

当我们的游标可以取到商品后,我们也可以取一下数据 信息,

cs1.fetchone() 取一个 cs1.fetchmany() 去多个

cs1.fetchall() 取所有的数据

fetchone等函数因为链接的是游标,因此,再没关闭连接和游标对象时,是按照前面执行的那步接着往下执行的

我们也可以通过定义后再进行取值

line_content = cs1.fetchone()
for temp in line_content:print(temp)#如果要是用fetchmany来进行查看的时候,就是元组套元组来进行显示
#这个的意思就是取五条数据
lines = cs1.fetchmany(5)
print(lines)

工程案例:

开发一款可以方便于京东商品查询的脚本,需使用面向对象开发;实现可查看数据库内所有商品 所有商品的分类 所有商品的品牌分类

from pymysql import connect
class JD(object):def __init__(self):# 初始化创建connection连接self.conn = connect(host="localhost", port=3306, user='root', password='200228', database='jing_dong',charset='utf8')# 创建游标对象self.cs1 = self.conn.cursor()def __del__(self):self.cs1.close()self.conn.close()def execute_sql(self, sql):""":param sql: 传入sql数据,无需每次连接后断开"""self.cs1.execute(sql)for temp in self.cs1.fetchall():print(temp)def show_all_intem(self):"""显示所有的商品"""# 创建connection连接sql = "select *from goods;"self.execute_sql(sql)def show_cates(self):sql = "SELECT name FROM goods_cates"self.execute_sql(sql)def show_brand(self):sql = "SELECT name FROM goods_brands;"self.execute_sql(sql)@staticmethoddef print_menu():"""使用实例方法,全局调用:return: 返回的值传入下一个即将调用的函数中"""print("----京东-----")print("1:所有的商品")print("2:所有的商品分类")print("3:所有的商品品牌分类")num = input("请输入功能对应的序号:")# 这里切记,一定要return返回值return numdef run(self):while True:num = self.print_menu()if num == "1":# 查询所有商品self.show_all_intem()elif num == "2":# 查询分类self.show_cates()elif num == "3":# 查询品牌self.show_brand()else:print("输入有误,请重新输入....")def main():# 1. 创建一个京东商城的对象jd = JD()# 2. 调用这个对象的run 方法,让其运行jd.run()if __name__ == '__main__':main()

pymysql增删改查:实质上都是一样的,唯一不一样的就是最后一个需要提交 通过使用 commit 方法

插入数据:

from pymysql import connectconn = connect(host="localhost", port=3306, user='root', password='200228', database='jing_dong',charset='utf8')
# 创建游标对象
cs1 = conn.cursor()
sql = "insert into goods_cates(name) VALUES ('硬盘_new')"
cs1.execute(sql)
#无论是更新还是删除,必须要commit提交一下数据库
conn.commit()
cs1.close()
conn.close()

实现数据的插入

from pymysql import connectclass JD(object):def __init__(self):# 初始化创建connection连接self.conn = connect(host="localhost", port=3306, user='root', password='200228', database='jing_dong',charset='utf8')# 创建游标对象self.cs1 = self.conn.cursor()def __del__(self):self.cs1.close()self.conn.close()def execute_sql(self, sql):""":param sql: 传入sql数据,无需每次连接后断开"""self.cs1.execute(sql)for temp in self.cs1.fetchall():print(temp)def show_all_intem(self):"""显示所有的商品"""# 创建connection连接sql = "select *from goods;"self.execute_sql(sql)def show_cates(self):sql = "SELECT name FROM goods_cates"self.execute_sql(sql)def show_brand(self):sql = "SELECT name FROM goods_brand;"self.execute_sql(sql)def add_menu(self):item_name =input("请输入新商品分类名称")sql ="""insert into goods_brand(name) VALUES("%s") """ %item_nameself.execute_sql(sql)#更新创建数据表单,实现数据的更新self.conn.commit()@staticmethoddef print_menu():"""使用实例方法,全局调用:return: 返回的值传入下一个即将调用的函数中"""print("----京东-----")print("1:所有的商品")print("2:所有的商品分类")print("3:所有的商品品牌分类")print("4:插入商品品牌")num = input("请输入功能对应的序号:")# 这里切记,一定要return返回值return numdef run(self):while True:num = self.print_menu()if num == "1":# 查询所有商品self.show_all_intem()elif num == "2":# 查询分类self.show_cates()elif num == "3":# 查询品牌self.show_brand()elif num == "4":# 插入数据self.add_menu()else:print("输入有误,请重新输入....")def main():# 1. 创建一个京东商城的对象jd = JD()# 2. 调用这个对象的run 方法,让其运行jd.run()if __name__ == '__main__':main()

SQL注入:

什么是SQL注入,在数据库没有超级管理员的权限时,我们通过一些奇怪的命令也可以获取到数据表单

-- 输入5之后 可以通过这条命令获取到全部的信息
-- select * from goods where name =''or 1=1 or'';
'or 1=1 or'

输出

----->select * from goods where name =''or 1=1 or'';ql<------
(1, '联想(Lenovo)天逸510S 个人商务台式机电脑整机(i3-10100 8G 512G', 4, '华硕', Decimal('2324.000'), b'\x00', b'\x00')
(2, '戴尔dell成就3690 商用办公台式机电脑主机(11代i5-11400 16G', 4, '联想', Decimal('4234.000'), b'\x00', b'\x00')
(3, '联想(Lenovo)天逸510S 个人商务台式机电脑整机(i5-10400 16G 1T+256G SSD', 3, '索尼', Decimal('2342.000'), b'\x00', b'\x00')
(4, '武极天机 i5 10400F/GTX1050Ti/游戏台式办公电脑主', 5, '苹果', Decimal('4655.000'), b'\x00', b'\x00')
(5, '荣耀笔记本 MagicBook X 14 2021 14英寸全面屏轻薄笔记本电脑 (i3 10110U 8GB', 4, '苹果', Decimal('1233.000'), b'\x00', b'\x00')
(6, '戴尔Dell成就3000 办公商用家用台式机电脑英特尔十代处理器学习财务', 2, '戴尔', Decimal('3434.000'), b'\x00', b'\x00')
(7, '戴尔笔记本电脑dell灵越15-3501 15.6英寸高性能轻薄商务笔记本电脑(11代英特', 1, '华硕', Decimal('2344.000'), b'\x00', b'\x00')
(8, '联想(Lenovo)扬天M4000q英特尔酷睿i3 商用台式机电脑整机(i3-10100', 2, '联想', Decimal('4543.000'), b'\x00', b'\x00')
(9, '联想ThinkPad E15 2021款 酷睿版 英特尔酷睿i5/i7 轻薄笔记本电脑 人', 1, '苹果', Decimal('3455.000'), b'\x00', b'\x00')
(10, '硕扬 i5 10400F/八核/GTX1050TI 4G/32G内存游戏台式吃鸡', 1, '索尼', Decimal('2455.000'), b'\x00', b'\x00')
(11, '惠普(HP)小欧高清一体机电脑21.5英寸(J4025 4G 256SSD UMA 无线', 4, '华硕', Decimal('7899.000'), b'\x00', b'\x00')

我们如何做到用更安全的方式防护SQL注入呢

#安全的方式
#构建参数列表
params =[find_name]
#执行select语句,并返回收影响的行数,查询所有数据
count =cs1.execute('select * from goods where name=%s',params)
#注意 如果有多个参数,需要进行参数化,那么params=[数值1,数值2....] ,此时sql语句中有多个%s即可
#打印受影响的行数
print(count)

防止SQL注入代码:

from pymysql import connectclass JD(object):def __init__(self):# 初始化创建connection连接self.conn = connect(host="localhost", port=3306, user='root', password='200228', database='jing_dong',charset='utf8')# 创建游标对象self.cs1 = self.conn.cursor()def __del__(self):self.cs1.close()self.conn.close()def execute_sql(self, sql):""":param sql: 传入sql数据,无需每次连接后断开"""self.cs1.execute(sql)for temp in self.cs1.fetchall():print(temp)def show_all_intem(self):"""显示所有的商品"""# 创建connection连接sql = "select *from goods;"self.execute_sql(sql)def show_cates(self):sql = "SELECT name FROM goods_cates"self.execute_sql(sql)def show_brand(self):sql = "SELECT name FROM goods_brand;"self.execute_sql(sql)def add_menu(self):item_name =input("请输入新商品分类名称")sql ="""insert into goods_brand(name) VALUES("%s") """ %item_nameself.execute_sql(sql)#更新创建数据表单,实现数据的更新self.conn.commit()def get_info_by_name(self):find_name = input("请输入要查询的商品名字:")sql = "select * from goods where name= %s"self.cs1.execute(sql,[find_name])print(self.cs1.fetchall())@staticmethoddef print_menu():"""使用实例方法,全局调用:return: 返回的值传入下一个即将调用的函数中"""print("----京东-----")print("1:所有的商品")print("2:所有的商品分类")print("3:所有的商品品牌分类")print("4:插入商品品牌")print("5:根据名字查询一个商品")num = input("请输入功能对应的序号:")# 这里切记,一定要return返回值return numdef run(self):while True:num = self.print_menu()if num == "1":# 查询所有商品self.show_all_intem()elif num == "2":# 查询分类self.show_cates()elif num == "3":# 查询品牌self.show_brand()elif num == "4":# 插入数据self.add_menu()elif num == "5":#根据名字查询商品self.get_info_by_name()else:print("输入有误,请重新输入....")def main():# 1. 创建一个京东商城的对象jd = JD()# 2. 调用这个对象的run 方法,让其运行jd.run()if __name__ == '__main__':main()

写在最后:
SQL注入的防治之一,只有唯一的方法,千万不要自己去拼接,而是我们需要用pymysql自带的函数来进行进一步拼接,这边的话我们要更多的使用 execute 来进行安全防护

我们设想一下,查询可以通过 'or 1=1'来进行查看的,我们仅仅是通过查看,走更危险的一步 如果要是 删除呢(手动滑稽) drop table message 哈哈哈这就有意思了,未来可能面临三餐管饭了,乌云网被封了,如果要是能看到更多安全渗透可以学到更多的安全防护知识。网络安全固然有意思,千万不要上头,SQL注入尽管已经很老了,但是有矛就一定有盾,天下没有不透风的墙,最笨的方法我们可以一点点去试,总会有更多的漏洞等着我们去发现,初学者千万不要以身试法,不要去试探底线!!! 通过非法途径获取50+用户的信息就可以管饭了。。。。希望大家的技术越来越强!!!!

网络安全篇(数据表单的创建 SQL命令拾遗 数据的SQL注入的防护)相关推荐

  1. MySQL之数据表(数据库的创建与删除、数据表的创建与删除)

    MySQL之数据表 创建数据库 删除数据库 认识数据表 创建数据表 删除数据表 创建数据库   在创建表之前,一定要先创建用来存储表的数据库.数据库中包含数据表.视图.索引.查询.规则.默认值等数据库 ...

  2. 【Springboot学习笔记】SpringBoot+Mybatis+Thymeleaf+Layui数据表单从零开始实现按条件模糊分页查询的方法

    [Springboot学习笔记]SpringBoot+Mybatis+Thymeleaf+Layui数据表单从零开始实现按条件模糊分页查询的方法 目录 1.搭建环境 1.1直接从网上下载SpringB ...

  3. layui删除后刷新表格_layui form表单提交之后重新加载数据表格的方法

    如下图,在我们做高级查询的时候需要重新加载数据表格table.reload(); HTML form表单 菜单:  JS $(function () { //注意:这里是数据表格的加载数据,必须写 ...

  4. excel数据表单_Excel中的工作表数据输入表单

    excel数据表单 With a bit of programming, you can make it easy for users to enter data in an Excel workbo ...

  5. excel数据表单_新的改进的Excel数据输入表单

    excel数据表单 Many moons ago, Dave Peterson created a sample Excel worksheet data entry form and kindly ...

  6. 【示例教程】使用Leadtools对身份证进行识别和表单模板创建

    使用Leadtools的表单识别功能可以对固定格式的表单很方便的进行批量识别,生活中常见的身份证.驾驶证.发票等都可以识别出准确的结果.另外通过表单匹配的功能同时也能实现对表单进行自动分类.本篇教程以 ...

  7. 权限控制相关数据表分析和创建

    权限控制相关数据表分析和创建 实体类分析:包含用户.角色.权限三大块 用户User,角色Role,权限Permission 为了方便进行动态的菜单管理,也就是不同权限用户进入到后台系统所看到的菜单是不 ...

  8. web元件库、axure元件库、通用元件库、常用web组件、常用表单、框架、数据表单、导航栏、边框、图标、列表、日期时间选择器、评分组件、穿梭框、输入框、步骤条、图表组件、数据可视化、后台模板、时间轴

    web元件库.axure元件库.通用元件库.常用web组件.常用表单.框架.数据表单.导航栏.边框.图标.列表.日期时间选择器.评分组件.穿梭框.输入框.步骤条.图表组件.数据可视化.后台模板.时间轴 ...

  9. mysql 收藏表如何建立_代码收藏系列--mysql创建数据库、数据表、函数、存储过程命令...

    创建mysql数据库 CREATE DATABASE IF NOT EXISTS `database_name` DEFAULT CHARSET utf8 COLLATE utf8_general_c ...

最新文章

  1. mysql 字符类型
  2. C#中的Using的用法
  3. 实施Jersey 2 Spring集成
  4. 我参与的一个x86平台项目的经历
  5. android中实现GPS定位功能,Android中实现GPS定位的简单例子
  6. html 文件动态加载.PDI 流程图
  7. C++ 最大堆最小堆与push_heap pop_heap
  8. JWT—JSON Web Token - 理解JWT网络间应用用户安全认证交互设计
  9. WPF学习拾遗(三)TextBox焦点问题
  10. JSP中文乱码问题终极解决方案(下)
  11. 个人征信系统机构接入工作流程
  12. Make the Team(匈牙利算法)
  13. 俞渝年轻图片_组图:2007中国职场女性榜样-俞渝
  14. Python:打印九九乘法口诀表
  15. ant design vue时间范围(range-picker)自定义时间段范围
  16. S19文件解析实现代码
  17. FZU2214 超大背包
  18. mysql temporary_MYSQL中的CREATE TEMPORARY TABLE
  19. 安霸flash dma操作
  20. sqlmap问题及解决办法

热门文章

  1. ASP.NET六大验证控件
  2. api.weixin.qq.com: 未知的名称或服务
  3. 中小股民会牺牲在牛市的泡沫里?[转]
  4. 小白也能看懂的HTTPS协议
  5. linux crossover 乱码,解决ubuntu下crossover中qq中文字体乱码问题
  6. 基于TNEWS‘ 今日头条中文新闻(短文本)分类
  7. linux将默认的英文语言改为中文
  8. Could not execute menu item (internal error),如何修改端口号
  9. 录制游戏视频——fraps
  10. Python eval()函数