SQL注入攻击、视图、事物、存储过程、流程控制

一、SQL注入攻击

1、什么是SQL注入攻击
  1. import pymysql
  2.  
  3. conn = pymysql.Connect(
  4. user="root",
  5. password="admin",
  6. host="localhost",
  7. database="day43",
  8. charset="utf8"
  9. )
  10.  
  11. cursor = conn.cursor(pymysql.cursors.DictCursor)
  12.  
  13. sql = "select *from user where user = '%s' and pwd = '%s';" % (input("input userName"),input("input password"))
  14.  
  15. conut=cursor.execute(sql)
  16.  
  17. print(count)
  18. if count:
  19. print("login success")
  20. else:
  21. print("login error")
  22.  
  23. cursor.close()
  24. conn.close()

用户登录验证

  1. 一些了解sql语法的用户,可以输入一些关键字 或合法sql,来导致原始的sql逻辑发生变化,从而跳过登录验证 或者 删除数据库
  1. # -- 用于mysql注释,意思是后面的内容忽略掉
  2. # 当用户输入的用户名为字符串为yy' -- 时,密码是否正确都能登录成功
  3. 产生的sq select *from user where user = 'yy' -- ' and pwd = '987657890';
  4.  
  5. # 当用户输入axxax' or 1=1-- 时,跳过用户名和密码,就可登录
  6. 产生的sql "select *from user where user = 'axxax' or 1=1 -- ' and pwd='123';

2、解决办法:

(1)从客户端注入SQL攻击

  1. # 原来是我们对sql进行字符串拼接
  2. # sql="select * from userinfo where name='%s' and password='%s'" %(user,pwd)
  3. # print(sql)
  4. # res=cursor.execute(sql)
  5.  
  6. #改写为(execute帮我们做字符串拼接,把你的slq(用户输入的)参数放execute函数的arg参数中,让pymysql自动帮你屏蔽注入攻击,我们无需且一定不能再为%s加引号了)
  7. sql="select * from userinfo where name=%s and password=%s" #!!!注意%s需要去掉引号,因为pymysql会自动为我们加上
  8. res=cursor.execute(sql,[user,pwd]) #pymysql模块自动帮我们解决sql注入的问题,只要我们按照pymysql的规矩来。

(2)中间人攻击(在你的客户端和服务器中间加一个中转服务器)

  1. # 这种攻击方式绕过了客户端的输入限制,这种攻击只能将SQL合法性验证放在服务端

二、视图(实际开发中用的不多)

1、什么是视图

视图是虚拟的表,用户在查询时会产生临时表,可以利用视图将临时表永久保存下来。这样用户使用时只需用视图即可。

2、视图的功能

  1. # 功能1:隐藏部分数据,开放指定的数据,使原表安全
  2. 例如:员工只能看自己的工薪信息,不能看别人的
  3.  
  4. # 功能2:因为视图可以将查询结果保存特性,可以用视图来达到减少书写sql的次数
  5. 例如:select *from emp where dept_id = (select id from dept where name = "市场");
  6. 要查询市场的人,将查询结果作为一个视图 以后在使用到这个需求 就直接查看视图

3、创建视图

  1. create view test_view as select *from t1;

4、使用视图

  1. #修改视图,原始表也跟着改
  2. mysql> select * from course;
  3. +-----+--------+------------+
  4. | cid | cname | teacher_id |
  5. +-----+--------+------------+
  6. | 1 | 生物 | 1 |
  7. | 2 | 物理 | 2 |
  8. | 3 | 体育 | 3 |
  9. | 4 | 美术 | 2 |
  10. +-----+--------+------------+
  11. 4 rows in set (0.00 sec)
  12.  
  13. mysql> create view course_view as select * from course; #创建表course的视图
  14. Query OK, 0 rows affected (0.52 sec)
  15.  
  16. mysql> select * from course_view;
  17. +-----+--------+------------+
  18. | cid | cname | teacher_id |
  19. +-----+--------+------------+
  20. | 1 | 生物 | 1 |
  21. | 2 | 物理 | 2 |
  22. | 3 | 体育 | 3 |
  23. | 4 | 美术 | 2 |
  24. +-----+--------+------------+
  25. 4 rows in set (0.00 sec)
  26.  
  27. mysql> update course_view set cname='xxx'; #更新视图中的数据
  28. Query OK, 4 rows affected (0.04 sec)
  29. Rows matched: 4 Changed: 4 Warnings: 0
  30.  
  31. mysql> insert into course_view values(5,'yyy',2); #往视图中插入数据
  32. Query OK, 1 row affected (0.03 sec)
  33.  
  34. mysql> select * from course; #发现原始表的记录也跟着修改了
  35. +-----+-------+------------+
  36. | cid | cname | teacher_id |
  37. +-----+-------+------------+
  38. | 1 | xxx | 1 |
  39. | 2 | xxx | 2 |
  40. | 3 | xxx | 3 |
  41. | 4 | xxx | 2 |
  42. | 5 | yyy | 2 |
  43. +-----+-------+------------+
  44. 5 rows in set (0.00 sec)

修改视图的记录,其实是更新了原表中的记录,然后视图重新运行 as 后面的select语句,从而获取视图中的数据。

5、修改视图

  1. #语法:ALTER VIEW 视图名称 AS SQL语句
  2. mysql> alter view teacher_view as select * from course where cid>3;
  3. Query OK, 0 rows affected (0.04 sec)
  4.  
  5. mysql> select * from teacher_view;
  6. +-----+-------+------------+
  7. | cid | cname | teacher_id |
  8. +-----+-------+------------+
  9. | 4 | xxx | 2 |
  10. | 5 | yyy | 2 |
  11. +-----+-------+------------+
  12. 2 rows in set (0.00 sec)

6、删除视图

  1. # 语法:DROP VIEW 视图名称
  2.  
  3. DROP VIEW teacher_view

7、视图的特点

  1. 1.每次对视图进行的查询,其实都是再次执行了 as 后面的查询语句
  2. 2.可以对视图进行修改,修改会同步到原表
  3. 3.视图是永久存储的,存储的不是数据,而就是一条 as 后面的 查询语句

 三、事务

 1、什么是事务

事务就是一组sql语句的集合,它们是原子性的,要么全部执行,要么都不执行

  1. mysql客户端,默认开启自动提交,默认不开启事务,一条sql语句就是一个单独的事务,自动提交,不能实现撤销
  2. pymysql 默认是不自动提交,默认开启事务,需要手动commit,就是NSQL语句表示一个事务,必须在这些语句的结尾手动提交,不提交就可以撤销(rollback

2、事务的特性

  1. #1.原子性
  2. 事务是一个整体,不可分割
  3.  
  4. #2.隔离性
  5. 事务之间要相互隔离,为了维护数据完整性,查询和修改不能同时进行
  6.  
  7. 因为并发访问导致的一些问题
  8. 1.脏读 一个事物 读到了 另一个事务未提交的数据,查询之前要保证,所有的更新都已经完成
  9. 2.幻读 一个查询事务没有结束时,数据被另一个事务执行insert delete
  10. 3.不可重复读 一个事物在查询,另一个事务在 update
  11.  
  12. 四种隔离级别
  13. 读未提交
  14. 读已提交
  15. 可重复读 默认
  16. 串行化
  17.  
  18. #3.一致性
  19. 当事务执行后,所有的数据都是完整的(外键约束、非空约束)
  20.  
  21. #4.持久性
  22. 一旦事务提交,数据就永久保存

3、事务中应掌握点

开启事务以后,必须提交。提交以前,数据可以撤销;一旦提交,数据就无法撤销。

  1. start transaction; 开启一个事物
  2. commit 提交事物
  3. rollback 回滚事务
  1. mysql> select * from emp;
  2. +------+------+--------+
  3. | id | name | salary |
  4. +------+------+--------+
  5. | 1 | tom | 10000 |
  6. | 2 | tony | 12000 |
  7. | 3 | Jack | 13000 |
  8. | 4 | Sary | 9000 |
  9. +------+------+--------+
  10. 4 rows in set (0.20 sec)
  11.  
  12. mysql> start transaction; # 开启事务
  13. Query OK, 0 rows affected (0.00 sec)
  14.  
  15. mysql> update emp set name ='TOM' where id=1; #更改数据
  16. Query OK, 1 row affected (0.06 sec)
  17. Rows matched: 1 Changed: 1 Warnings: 0
  18.  
  19. mysql> select * from emp; # 查看更改后的数据
  20. +------+------+--------+
  21. | id | name | salary |
  22. +------+------+--------+
  23. | 1 | TOM | 10000 |
  24. | 2 | tony | 12000 |
  25. | 3 | Jack | 13000 |
  26. | 4 | Sary | 9000 |
  27. +------+------+--------+
  28. 4 rows in set (0.00 sec)
  29.  
  30. mysql> rollback; # 撤销更改
  31. Query OK, 0 rows affected (0.12 sec)
  32.  
  33. mysql> select * from emp; # 查看撤销后的数据,没有提交,可以完成撤销
  34. +------+------+--------+
  35. | id | name | salary |
  36. +------+------+--------+
  37. | 1 | tom | 10000 |
  38. | 2 | tony | 12000 |
  39. | 3 | Jack | 13000 |
  40. | 4 | Sary | 9000 |
  41. +------+------+--------+
  42. 4 rows in set (0.00 sec)
  43.  
  44. mysql> update emp set name ='TOM' where id=1; # 更改数据
  45. Query OK, 1 row affected (0.13 sec)
  46. Rows matched: 1 Changed: 1 Warnings: 0
  47.  
  48. mysql> commit; # 提交数据
  49. Query OK, 0 rows affected (0.00 sec)
  50.  
  51. mysql> rollback; # 提交数据后,撤销更改
  52. Query OK, 0 rows affected (0.00 sec)
  53.  
  54. mysql> select * from emp; # 查看数据,提交以后,数据无法撤销
  55. +------+------+--------+
  56. | id | name | salary |
  57. +------+------+--------+
  58. | 1 | TOM | 10000 |
  59. | 2 | tony | 12000 |
  60. | 3 | Jack | 13000 |
  61. | 4 | Sary | 9000 |
  62. +------+------+--------+
  63. 4 rows in set (0.00 sec)

提交前后无法撤销数据

4、事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性。

  1. create table user(
  2. id int primary key auto_increment,
  3. name char(32),
  4. balance int
  5. );
  6.  
  7. insert into user(name,balance)
  8. values
  9. ('wsb',1000),
  10. ('egon',1000),
  11. ('ysb',1000);
  12.  
  13. #原子操作
  14. start transaction;
  15. update user set balance=900 where name='wsb'; #买支付100元
  16. update user set balance=1010 where name='egon'; #中介拿走10元
  17. update user set balance=1090 where name='ysb'; #卖家拿到90元
  18. commit;
  19.  
  20. #出现异常,回滚到初始状态
  21. start transaction;
  22. update user set balance=900 where name='wsb'; #买支付100元
  23. update user set balance=1010 where name='egon'; #中介拿走10元
  24. uppdate user set balance=1090 where name='ysb'; #卖家拿到90元,出现异常没有拿到
  25. rollback;
  26. commit;
  27. mysql> select * from user;
  28. +----+------+---------+
  29. | id | name | balance |
  30. +----+------+---------+
  31. | 1 | wsb | 1000 |
  32. | 2 | egon | 1000 |
  33. | 3 | ysb | 1000 |
  34. +----+------+---------+
  35. 3 rows in set (0.00 sec)

四、存储过程

1、什么是存储过程

  1. 存储过程相当于python中的一个函数,通过调用它的名字可以执行其内部的一堆sql

2、存储过程的作用

  1. 可以将你的程序业务逻辑,放到mysql中来处理
  2. 这样可以降低网络访问次数,从而提高你的程序效率

3、程序与数据库结合使用的三种方式

  1. #方式一:
  2. MySQL:存储过程
  3. 程序:调用存储过程
  4.  
  5. #方式二:
  6. MySQL
  7. 程序:纯SQL语句
  8.  
  9. #方式三:
  10. MySQL:
  11. 程序:类和对象,即ORM(本质还是纯SQL语句)

4、创建存储过程

  1. delimiter //
  2. create procedure 过程的名称 ({in,out,inout} 参数名称 数据类型 )
  3. begin
  4. 具体的sql代码
  5. end //
  6.  
  7. # 参数前面需要指定参数的作用
  8. # in 表示该参数用于传入数据
  9. # out 用于返回数据
  10. # inout 即可传入 也可返回
  11. # 参数类型是 mysql中的数据类型
(1)无参存储过程的创建和使用
  1. delimiter // # 修改提交标志,以//结束表示提交
  2. create procedure p1()
  3. BEGIN
  4. select * from blog;
  5. INSERT into blog(name,sub_time) values("xxx",now());
  6. END //
  7. delimiter ;
  8.  
  9. #在mysql中调用
  10. call p1() # call 表示调用,调用方式
  11.  
  12. #在python中基于pymysql调用
  13. cursor.callproc('p1')
  14. print(cursor.fetchall())

无参存储过程

(2)有参存储过程的创建和使用

  1. delimiter //
  2. create procedure p2(in n1 int,in n2 int)
  3. BEGIN
  4. select * from blog where id > n1;
  5. END //
  6. delimiter ;
  7.  
  8. #在mysql中调用
  9. call p2(3,2)
  10.  
  11. #在python中基于pymysql调用
  12. cursor.callproc('p2',(3,2))
  13. print(cursor.fetchall())

in:传入参数

  1. delimiter //
  2. create procedure p3(in n1 int,out res int)
  3. BEGIN
  4. select * from blog where id > n1;
  5. set res = 1;
  6. END //
  7. delimiter ;
  8.  
  9. #在mysql中调用
  10. set @res=0; #0代表假(执行失败),1代表真(执行成功)
  11. call p3(3,@res); # @res表示这个参数时返回值
  12. select @res;
  13.  
  14. #在python中基于pymysql调用
  15. cursor.callproc('p3',(3,0)) #0相当于set @res=0
  16. print(cursor.fetchall()) #查询select的查询结果
  17.  
  18. cursor.execute('select @_p3_0,@_p3_1;') #@p3_0代表第一个参数,@p3_1代表第二个参数,即返回值
  19. print(cursor.fetchall())

out:返回值

  1. delimiter //
  2. create procedure p4(
  3. inout n1 int
  4. )
  5. BEGIN
  6. select * from blog where id > n1;
  7. set n1 = 1;
  8. END //
  9. delimiter ;
  10.  
  11. #在mysql中调用
  12. set @x=3;
  13. call p4(@x);
  14. select @x;
  15.  
  16. #在python中基于pymysql调用
  17. cursor.callproc('p4',(3,))
  18. print(cursor.fetchall()) #查询select的查询结果
  19.  
  20. cursor.execute('select @_p4_0;')
  21. print(cursor.fetchall())

inout

5、执行存储过程

(1)在mysql中执行

  1. -- 无参数
  2. call proc_name()
  3.  
  4. -- 有参数,全in
  5. call proc_name(1,2)
  6.  
  7. -- 有参数,有inoutinout
  8. set @t1=0;
  9. set @t2=3;
  10. call proc_name(1,2,@t1,@t2)

mysql中执行存储过程

(2)在Python中基于pymysql执行存储过程

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import pymysql
  4.  
  5. conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='t1')
  6. cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
  7.  
  8. # 执行存储过程
  9. cursor.callproc('p1', args=(1, 22, 3, 4))
  10. # 获取执行完存储的参数
  11. cursor.execute("select @_p1_0,@_p1_1,@_p1_2,@_p1_3")
  12. result = cursor.fetchall()
  13.  
  14. conn.commit()
  15. cursor.close()
  16. conn.close()
  17.  
  18. print(result)

基于pymysql执行存储过程

6、删除存储过程

  1. drop procedure proc_name;

删除存储过程

补充:

  1. mysql中的变量分为三种
  2. 1.全局变量 两个@@代表系统变量 系统以及定好的变量
  3. 2.会话级变量 一个@代表用户变量 自己定义的变量
  4. 3.局部变量
  5.  
  6. 查看当前隔离级别
  7. select @@global.tx_isolation,@@tx_isolation;
  8. 设置隔离级别 分两种
  9. 全局 会话级
  10. set global tx_isolation = "read-committed"; //全局
  11. set tx_isolation = "read-committed"; //全局

五、流程控制

  1. delimiter //
  2. CREATE PROCEDURE proc_if ()
  3. BEGIN
  4.  
  5. declare i int default 0;
  6. if i = 1 THEN
  7. SELECT 1;
  8. ELSEIF i = 2 THEN
  9. SELECT 2;
  10. ELSE
  11. SELECT 7;
  12. END IF;
  13.  
  14. END //
  15. delimiter ;

if条件

  1. delimiter //
  2. CREATE PROCEDURE proc_while ()
  3. BEGIN
  4.  
  5. DECLARE num INT ;
  6. SET num = 0 ;
  7. WHILE num < 10 DO
  8. SELECT
  9. num ;
  10. SET num = num + 1 ;
  11. END WHILE ;
  12.  
  13. END //
  14. delimiter ;

while循环

  1. delimiter //
  2. CREATE PROCEDURE proc_repeat ()
  3. BEGIN
  4.  
  5. DECLARE i INT ;
  6. SET i = 0 ;
  7. repeat
  8. select i;
  9. set i = i + 1;
  10. until i >= 5
  11. end repeat;
  12.  
  13. END //
  14. delimiter ;

repeat循环

  1. BEGIN
  2.  
  3. declare i int default 0;
  4. loop_label: loop
  5.  
  6. set i=i+1;
  7. if i<8 then
  8. iterate loop_label;
  9. end if;
  10. if i>=10 then
  11. leave loop_label;
  12. end if;
  13. select i;
  14. end loop loop_label;
  15.  
  16. END

loop循环

MySQL数据库(六) —— SQL注入攻击、视图、事物、存储过程、流程控制的更多相关文章

  1. sql注入问题-视图-事物-以及存储过程(可视化工具)

    可视化工具(了解) 可视化工具 workbench 视图 视图 是一张虚拟的表 语法: create view 视图表名 as select * from t1; 作用: .他是执行as 后面的sql ...

  2. 使用SQLMAP对网站和数据库进行SQL注入攻击

    from:http://www.blackmoreops.com/2014/05/07/use-sqlmap-sql-injection-hack-website-database/ 0x00 背景介 ...

  3. day40:python操作mysql:pymysql模块&SQL注入攻击

    目录 part1:用python连接mysql 1.用python连接mysql的基本语法 2.用python 创建&删除表 3.用python操作事务处理 part2:sql注入攻击 1.s ...

  4. 【数据库】SQL注入攻击

    背景: 机房收费系统验收的时候,师父提到SQL注入攻击.自己以前看过类似的博客大概知道一些这方面的事情,于是自己动手查了查. 定义: 所谓SQL注入,通过SQL命令插入到Web表单提交或者输入域名或页 ...

  5. Mysql数据库防SQL注入原理

    每个语言都有自己的数据库框架或库,无论是哪种语言,哪种库,它们在数据库防注入方面使用的技术原理无外乎下面介绍的几种方法. 一.特殊字符转义处理 Mysql特殊字符指在mysql中具有特殊含义的字符,除 ...

  6. php和mysql数据库防SQL注入的有效解决办法

    <?php$mysqli = new mysqli("localhost", "my_user", "my_password", &q ...

  7. MySQL数据库(六)-- SQL注入攻击、视图、事物、存储过程、流程控制

    一.SQL注入攻击 1.什么是SQL注入攻击 一些了解sql语法的用户,可以输入一些关键字 或合法sql,来导致原始的sql逻辑发生变化,从而跳过登录验证 或者 删除数据库 import pymysq ...

  8. 06 数据库入门学习-视图、sql注入、事务、存储过程

    一.视图 1.什么是视图 视图本质是一张虚拟的表 2.为什么要用 为了原表的安全 只要有两大功能 1.隐藏部分数据,开放指定数据 2.视图可以将查询结果保存,减少sql语句的次数 特点: 1.视图使用 ...

  9. 网站mysql防止sql注入攻击 3种方法总结

    mysql数据库一直以来都遭受到sql注入攻击的影响,很多网站,包括目前的PC端以及手机端都在使用php+mysql数据库这种架构,大多数网站受到的攻击都是与sql注入攻击有关,那么mysql数据库如 ...

随机推荐

  1. python requests方法post请求json格式处理

    方法如下: import requestsimport json data = {    'a': 123,    'b': 456} ## headers中添加上content-type这个参数,指 ...

  2. DPL, CPL及RPL之间的关系

    DPL: Descriptor Privilege Level 1) GDT/LDT表中的描述符 GDT/LDT表中的描述符,描述的是一段内存. 其中的DPL代表着GDT/LDT中的描述符描述的内存段 ...

  3. Pandas数据处理 学习

    pandas是在numpy的基础上建立的新程序库,提供了一种高效的DataFrame数据结构. DataFrame本质上是一种带行标签和列标签.支持相同数据类型和缺失值的多维数组. 先看版本信息: p ...

  4. jmeter 不同线程组之间传递变量1

    一 采用全局变量在不同线程组之间传递变量的坑 ${__setProperty(newcompanyId,${companyId},)}; 不采用全局变量传递参数,请求报文格式如下: 正确的报文: {& ...

  5. shell编程:利用脚本实现nginx的守护自动重启

    nginx_daemon.sh #!/bin/bash # this_pid=$$ while true do ps -ef | grep nginx | grep -v grep | grep -v ...

  6. ReentrantLock的相关方法使用

    获取锁定 void lock():常用获取锁定的方法 void lockInterruptibly():如果当前线程未被中断,则获取锁定:如果当前线程被中断,则出现异常 boolean tryLock ...

  7. ASP.NET MVC 学习笔记之View 和Redriect的区别

    首先先说一下Redriect 和RedirectToAction 两个没什么区别,都是向浏览器发送302 Found相应,再有浏览器向对应的url进行请求 只是参数的意义不同而已 再说Redirect ...

  8. mysql导入.csv文件出错

    1.报错信息 ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cann ...

  9. sql中char,varchar,nvarchar的区别

    char[n] 是定长的,也就是当存储字符小于n时,他会自动补齐(补空值).优点:效率较varchar高. varchar[n]是变长且非unicode字符数据类型,n的取值在1到8000之间,该类型 ...

  10. codeforces 1198E Rectangle Painting 2 最小点覆盖

    题目传送门 题意: 有一个$n∗n$的网格,网格中有一些矩形是黑的,其他点都是白的. 你每次可以花费$ min (h,w)$的代价把一个$h*w$的矩形区域变白.求把所有黑格变白的最小代价. 思路: ...