• 常用数据库2 sqlite及SQL注入


    知识内容:

    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.com
    2     xxx     333      xxx@qq.com

    2.关于SQL语言

    sql语句详细:http://www.cnblogs.com/wyb666/p/9017402.html

    1 数据库通过 SQL 来操作数据
    2 SQL (结构化查询语言)-> 操作数据库的接口 也就是操作数据库的方法
    3 增加数据  删除数据  修改数据  查询数据
    4 CRUD
    5 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     SET
    101         `email`=?
    102     WHERE
    103         `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     # create
    116     # 打开数据库后 就可以用 create 函数创建表 -> 注意创建表只能创建一次 创建已创建的表会报错
    117     # create(conn)
    118 
    119     # insert
    120     # 然后可以用 insert 函数插入数据   -> 注意插入一次后下面的数据就不能再插入 因为用户名有限制(unique)
    121     # insert(conn, 'test', '123456', 'a@b.c')
    122 
    123     # delete
    124     # 可以用 delete 函数删除数据
    125     # delete(conn, 1)
    126 
    127     # update
    128     # 可以用 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     SELECT
    14         id, username, email
    15     FROM
    16         users
    17     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         SELECT
    33             id, username, email
    34         FROM
    35             users
    36         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         SELECT
    52             id, username, email
    53         FROM
    54             users
    55         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注入漏洞的发生!

  • 相关阅读:
    sqlserver游标概念与实例全面解说
    Dos网络查看命令
    SQL Server和Access数据读写
    表中记录查询排序(设置排序规则)
    sql server中扩展存储过程
    sql server中分布式查询随笔(链接服务器(sp_addlinkedserver)和远程登录映射(sp_addlinkedsrvlogin)使用小总结)
    合并有数据的列
    防止用户同时使用一个存储过程
    (转载) 两个数据库比较 对比视图存储过程及表结构差异
    Sql Server REPLACE函数的使用
  • 原文地址:https://www.cnblogs.com/wyb666/p/9236686.html
Copyright © 2020-2023  润新知