博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
常用数据库2 sqlite及SQL注入
阅读量:6239 次
发布时间:2019-06-22

本文共 6487 字,大约阅读时间需要 21 分钟。

知识内容:

1.sqlite数据库介绍

2.sqlite数据库操作

3.SQL注入

 

 

 

一、sqlite数据库介绍

1.sqlite数据库

sqlite数据库:轻量级的数据库,一般开发中使用sqlite数据库,上线后将sqlite数据库换成其他数据库(比如MySQL、MongoDB)来进行快速开发

sqlite的数据库操作相对来说比较简单,sqlite是python3中自带的数据库,不用安装,python3中的sqlite3是操作sqlite数据库的模块,可以装一个叫sqlitebrowser的软件浏览sqlite数据库中的数据

 

 

2.现在的数据库分类

  • 数据库现在主要分 关系型数据库(传统比如MySQL oracle等)
  • NoSQL(新式比如 mongodb)
  • 其他数据库(比如 fb 的图数据库)

 

 

 

二、sqlite数据库操作

1.数据库结构

传统数据库以表的形式存储数据一张表可以有很多个字段以用户表为例, 存储 4 个数据的表结构如下用户 id  用户名  密码  邮箱范例数据如下1     wyb     666      wyb@qq.com2     xxx     333      xxx@qq.com

 

 

2.关于SQL语言

sql语句详细:

1 数据库通过 SQL 来操作数据2 SQL (结构化查询语言)-> 操作数据库的接口 也就是操作数据库的方法3 增加数据  删除数据  修改数据  查询数据4 CRUD5 create retrieve update delete

 

 

3.sqlite操作数据库

几种关系型数据库的用法和 sql 语法都极度相似,开发中一般会用 sqlite 数据库,部署到服务器上的时候才会使用 mysql 等数据库

直接看下面代码:

1 # __author__ = "wyb"  2 # date: 2018/6/27  3 import sqlite3  4   5 # SQL 语句示例:  6 # INSERT INTO  7 #     `users`(`id`,`username`,`password`,`email`)  8 # VALUES \  9 #     (2,'','',NULL); 10 # 11 # UPDATE `users` SET `username`=? WHERE `_rowid_`='2'; 12 # UPDATE `users` SET `password`=? WHERE `_rowid_`='2'; 13 # UPDATE `users` SET `email`=? WHERE `_rowid_`='2'; 14  15  16 """ 17 下面是 python 操作 sqlite 数据库的范例代码 18 """ 19  20  21 # 创建数据库中的表 22 def create(conn): 23     # 注意 CREATE TABLE 这种语句不分大小写 24     sql_create = ''' 25     CREATE TABLE `users` ( 26         `id`    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 27         `username`    TEXT NOT NULL UNIQUE, 28         `password`    TEXT NOT NULL, 29         `email`    TEXT 30     ) 31     ''' 32     # 用 execute 执行一条 sql 语句 33     conn.execute(sql_create) 34     print('创建成功') 35  36  37 # 向数据库中插入数据 38 def insert(conn, username, password, email): 39     sql_insert = ''' 40     INSERT INTO 41         users(username,password,email) 42     VALUES 43         (?, ?, ?); 44     ''' 45     # 下面的写法用 string.format 拼 sql, 是一个严重的安全漏洞 -> SQL注入 46     # 会被 SQL 注入 47     # sql = ''' 48     # INSERT INTO 49     #     users(username,password,email) 50     # VALUES 51     #     ("{}", "{}", "{}") 52     # '''.format('123', '345', 'a.com') 53     # conn.execute(sql) 54     # 参数拼接要用 ?,execute 中的参数传递必须是一个 tuple 类型 55     conn.execute(sql_insert, (username, password, email)) 56     print('插入数据成功') 57  58  59 # 查询数据 60 def select(conn): 61     sql = ''' 62     SELECT 63         * 64     FROM 65         users 66     ''' 67     # 这是读取数据的套路 68     cursor = conn.execute(sql) 69     print('所有数据', list(cursor)) 70     # for row in cursor: 71     #     print(row) 72  73  74 # 删除数据 75 def delete(conn, user_id): 76     sql_delete = ''' 77     DELETE FROM 78         users 79     WHERE 80         id=? 81     ''' 82     # 注意, execute 的第二个参数是一个 tuple 83     # tuple 只有一个元素的时候必须是这样的写法 84     conn.execute(sql_delete, (user_id,)) 85  86  87 # 更新数据 88 def update(conn, user_id, email): 89     """ 90     UPDATE 91         `users` 92     SET 93         `email`='gua', `username`='瓜' 94     WHERE 95         `id`=6 96     """ 97     sql_update = ''' 98     UPDATE 99         `users`100     SET101         `email`=?102     WHERE103         `id`=?104     '''105     conn.execute(sql_update, (email, user_id))106 107 108 # 主程序109 def main():110     # 指定数据库名字并打开 -> 没有会自动创建111     db_path = 'web8.sqlite'112     conn = sqlite3.connect(db_path)113     print("打开数据库")114 115     # create116     # 打开数据库后 就可以用 create 函数创建表 -> 注意创建表只能创建一次 创建已创建的表会报错117     # create(conn)118 119     # insert120     # 然后可以用 insert 函数插入数据   -> 注意插入一次后下面的数据就不能再插入 因为用户名有限制(unique)121     # insert(conn, 'test', '123456', 'a@b.c')122 123     # delete124     # 可以用 delete 函数删除数据125     # delete(conn, 1)126 127     # update128     # 可以用 update 函数更新数据129     # update(conn, 1, 'woz_wyb@qq.com')130     # select 函数查询数据131     select(conn)132 133     # 最后提交:134     # 必须用 commit 函数提交你的修改135     # 否则你的修改不会被写入数据库136     conn.commit()137     # 用完数据库要关闭138     conn.close()139 140 141 if __name__ == '__main__':142     main()

 

 

 

三、SQL注入问题

1.什么是SQL注入

SQL注入:所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将恶意的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入恶意SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句

比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击

注意在拼SQL语句时一定要使用?让数据库自己去拼接字符串,而不是使用某种编程语言自带的语法去拼接字符串,比如在下面使用python中的format拼接字符串就会导致SQL注入的漏洞!

 

 

2.SQL注入实例

表结构:

创建数据库及表及插入数据见上面的sqlite操作数据库,SQL注入的实例:

1 # __author__ = "wyb" 2 # date: 2018/6/28 3 import sqlite3 4  5  6 # 查询数据 存在SQL注入隐患 7 def select(conn): 8     # 以下是一个隐患! 完全可以构造一个字符串来注入SQL 看下面的sql_inject函数 9     # 这样的漏洞就是等着被人搞 尤其是PHP 这样的漏洞非常多 字符串拼接在这里是又麻烦又不安全 不要在SQL语句上使用语言自带的字符串拼接10     user = "123"11     pwd = "345"12     sql = '''13     SELECT14         id, username, email15     FROM16         users17     WHERE 18         username="{}" and password="{}"19     '''.format(user, pwd)20     # 这是读取数据的套路21     cursor = conn.execute(sql)22     print('所有数据', list(cursor))23     # for row in cursor:24     #     print(row)25 26 27 # SQL注入演示28 def sql_inject(conn):29     user = '123" or "1"="1'                         # 一个注入的用户名30     pwd = "xxadfaksbglwsyfansdvliaysf"              # 随便乱打的密码31     sql = '''32         SELECT33             id, username, email34         FROM35             users36         WHERE 37             username="{}" and password="{}"38         '''.format(user, pwd)39     # user = '123" or "1"="1' -> 拼接的结果是:  username="123" or "1"="1" and password="随便乱打一个密码" -> 恒成立40 41     # 读取数据42     cursor = conn.execute(sql)43     print('所有数据', list(cursor))44 45 46 # SQL拼接正确做法 -> 使用?让数据库自己处理拼接47 def sql_select(conn):48     user = '123" or "1"="1'                         # 一个注入的用户名49     pwd = "xxadfaksbglwsyfansdvliaysf"              # 随便乱打的密码50     sql = '''51         SELECT52             id, username, email53         FROM54             users55         WHERE 56             username=? and password=?57         '''58 59     # 读取数据60     cursor = conn.execute(sql, (user, pwd))61     print('所有数据', list(cursor))62 63 64 # 主程序65 def main():66     # 指定数据库名字并打开 -> 没有会自动创建67     db_path = 'web8.sqlite'68     conn = sqlite3.connect(db_path)69     print("打开数据库")70 71     # select 查询72     # select(conn)73     # SQL注入74     sql_inject(conn)75     # 正确的SQL拼接写法76     sql_select(conn)77 78     # 最后提交:79     # 必须用 commit 函数提交你的修改80     # 否则你的修改不会被写入数据库81     conn.commit()82     # 用完数据库要关闭83     conn.close()84 85 86 if __name__ == '__main__':87     main()

最后总结:在拼接SQL语句时一定使用?,千万不要使用编程语言自带的拼接语法(比如python中的format),避免SQL注入漏洞的发生!

 

 

3.如何防止SQL注入

在拼接SQL语句时一定使用?,千万不要使用编程语言自带的拼接语法(比如python中的format),避免SQL注入漏洞的发生!

转载于:https://www.cnblogs.com/wyb666/p/9236686.html

你可能感兴趣的文章