經常使用數據庫2 sqlite及SQL注入

知識內容:html

1.sqlite數據庫介紹python

2.sqlite數據庫操做mysql

3.SQL注入web

 

 

 

1、sqlite數據庫介紹sql

1.sqlite數據庫mongodb

sqlite數據庫:輕量級的數據庫,通常開發中使用sqlite數據庫,上線後將sqlite數據庫換成其餘數據庫(好比MySQL、MongoDB)來進行快速開發數據庫

sqlite的數據庫操做相對來講比較簡單,sqlite是python3中自帶的數據庫,不用安裝,python3中的sqlite3是操做sqlite數據庫的模塊,能夠裝一個叫sqlitebrowser的軟件瀏覽sqlite數據庫中的數據編程

 

 

2.如今的數據庫分類安全

  • 數據庫如今主要分 關係型數據庫(傳統好比MySQL oracle等)
  • NoSQL(新式好比 mongodb)
  • 其餘數據庫(好比 fb 的圖數據庫)

 

 

 

2、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()

 

 

 

3、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注入漏洞的發生!

相關文章
相關標籤/搜索