iT邦幫忙

2026 iThome 鐵人賽

0

DAY32 應用程式安全

  • 一. 資料庫 Database
    • 1-1 SQL 結構化查詢語言
    • 1-2 SQL Injection
  • 二. 避免與防禦方法
    • 2-1 預備語句 Prepared Statements
    • 2-2 輸入驗證
    • 2-3 資料庫最小權限
  • 三. SQL Injection的類型

如果程式把使用者輸入錯誤的交給Database資料庫會發生什麼事?
SQL Injection (SQL注入)


一. 資料庫 Database

一樣用健身房舉例:
員工的會員管理網站

通常裡面會有

  • 會員編號
  • 姓名
  • 帳號
  • 方案

這些資料通常不會直接寫在網頁裡
而是放在資料庫Database中

例如:

(資料庫)

ID name Email
1. MIKEY XXX@mail.com
2. TONY YYY@mail.com

當網站要查詢資料時:
Web application網頁應用程式 -> Database資料庫 -> 取得資料 -> 回傳給使用者

1-1 SQL 結構化查詢語言

Structured Query Language,SQL
結構化查詢語言

用來和關聯式Database資料庫溝通、查詢、操作資料的語言

例如:

想找一個Username是MIKEY的會員

SELECT * FROM users
WHERE username = 'MIKEY';

翻譯
從 users這個資料表中,選取所有欄位 (*=全部)
WHERE username = 'MIKEY'; 篩選條件
只回傳username欄位中,值等於MIKEY的那幾筆資料

使用者操作上會是:
輸入MIKEY->Web application網頁應用程式
用SQL語法對資料庫下指令(資料庫查詢Database Query)->資料庫
找到MIKEY -> 回傳結果

資料庫查詢通常分四大類

  • 新增 -> INSERT — 把新資料塞進去
  • 查詢 -> SELECT - 把資料撈出來看(剛剛的例子)
  • 更新 -> UPDATE - 修改已有的資料庫
  • 刪除 -> DELETE - 把資料移除

通常問題會出在:
程式怎麼去處理使用者的輸入

1-2 SQL Injection

假設把程式寫成: (字串拼接)

SQL=
"SELECT * FROM users WHERE username ='"
+ 使用者輸入
+ "'"
  • 第一行SQL= 存進名為"SQL的變數"
  • 第二行 "SELECT * FROM users WHERE username ='"
    SQL查詢,注意這段的結尾是'(把使用者輸入包起來用)
  • 第三行 + 使用者輸入
    在'的後面加入使用者輸入內容(+是接上的意思)
  • 第四行 + "'"
    跟第二行最後的'做呼應,包住中間的值
  • 假設使用者輸入MIKEY
  • SELECT * FROM users WHERE username ='MIKEY'
    以上是使用者正常的輸入,跑出正常的回應

那假設使用者不照規矩來

使用者輸入的不是普通文字,而是帶有SQL語法的內容呢?


假設惡意使用者:輸入' OR'1'='1

出來的回應就會是
SELECT * FROM users WHERE username ='' OR'1'='1'

  1. username =''被提早結束了,是一個空值
  2. OR (或者),只要前後任一條件成立就算通過
  3. '1'='1' 1=1,永遠成立true

WHERE 後面的條件,是對每一筆資料逐筆檢查的
資料庫會一筆一筆問:「這筆資料符合條件嗎?」

因為OR後面永遠是true所以不管前面的條件是什麼,每一筆資料都符合,整張表全部回傳

運作過程 以上面的健身房資料庫舉例:
WHERE會去比對

第一筆MIKEY
username =''->MIKEY不是空值->所以不成立
'1'='1'-> 1=1 -> 成立true
這筆資料通過可以回傳

第二筆TONY
username =''->TONY不是空值->所以不成立
'1'='1'-> 1=1 -> 成立true
這筆資料通過可以回傳

結果就是每一筆資料都因為1=1成立所以回傳
導致攻擊者可以查看所有資料
機密性受影響


假設使用者輸入'; DROP TABLE users; --

出來的回應會是:
SELECT * FROM users WHERE username =''; DROP TABLE users; --'

  1. username ='' ->用空值提早結束查詢
  2. ; -> 代表這句結束,開始下一句
  3. DROP TABLE users -> SQL獨立指令,意思是刪掉users資料表,整張消失
  4. ; -> 第二句結束
  5. --' -> SQL的註解,把後面的'註解忽略掉,才不會造成語法錯誤

原本的指令執行完成後,雖然沒成立
但後面又串了一個獨立的SQL指令是DROP TABLE users把整張資料表刪除
再用--把原本程式設計串接的'註解掉讓它不會造成語法上的錯誤

完整性受影響


學習指引描述SQL Injection
在輸入字串中夾帶SQL指令;如果程式設計不良、沒妥善處理輸入,資料庫可能把惡意內容當成正常SQL指令執行
資料與指令被混在一起

IPAS 114-2 Q3
關於 SQL 注入(SQL Injection)攻擊的描述,下列何者較為適當?
C: 在資料庫中執行惡意SQL語句

IPAS 114-2 Q25
在 Web 應用程式中,若未對使用者輸入進行適當的驗證與過濾,攻擊者可能利用下列何種攻擊方法,輸入惡意資料進而未經授權地存取或修改資料庫中的資料?
B: SQL注入攻擊

用字串拼接的方式會造成Database最後收到的只有一整串的SQL
但它不知道:

  • 哪一段是使用者寫的
  • 哪一段是程式設計好的

導致程式指令與資料混淆


二. 避免與防禦方法

2-1 預備語句 Prepared Statements

先把 SQL 的結構固定好,再把使用者輸入當成「參數資料」放進去

參數?

SELECT * FROM users
WHERE username = ?;

這裡的?是佔位符
意思是等等會有一個值,但現在還不知道是什麼
(提前告訴資料庫這是一個值)
這時不管使用者輸入什麼都會被當成值,而不會是指令

與字串拼接不同的地方
關鍵在於處理順序
資料庫收到一串SQL會先進行解析
判斷哪些是關鍵字、哪些是符號、哪些是值
字串拼接:
使用者輸入的內容會被加進SQL原本的設計中一同被送去資料庫
這時資料庫會進行解析(但這個時候惡意使用者已經把惡意指令輸入了)
參數化查詢:
資料庫會先收到程式設計者原本設計好的結構
並告訴資料庫?是一個值
所以再來使用者的輸入都會被當成值來處理
而不是指令

IPAS 115-1 Q26
在開發Web應用程式時,為防止SQL注入攻擊(SQL Injection),下列措施中何項較為有效?
A: 使用預備語句或參數化查詢

2-2 輸入驗證

在使用者的輸入送進資料庫前,先檢查它合不合理

這比較好理解
例如:
人家輸入框要你輸入年齡

正常應該填數字,並且通常是2位數
結果你給人家填ABC或?":之類的符號

只有在使用者輸入正常年齡該有的數字格式時才給予通過
這時才能進入資料庫中

輸入驗證防禦有用
不能當作唯一的防線
因為有些欄位本來就很難驗證
只是剛好舉例年齡比較好說

115-1 Q26 對使用者輸入資料進行 Encoding(編碼)
為什麼它錯
對輸入編碼、跳脫屬於次要的輔助防線
可能被繞過,不是主要防禦

2-3 資料庫最小權限

假設網頁應用程式連資料庫時使用的帳號:
只有SELECT查詢會員資料的權限
這樣造成傷害時
也能限制影響的範圍

資料庫就會拒絕DELETE、UPDATE、DROP的指令


三. SQL Injection的類型

IPAS 請問下列何種 SQLi 攻擊類型可利用資料庫伺服器所發出的 DNS(Domain Name System)請求功能將資料傳遞給攻擊者?
A: Inferential SQL Injection
B: Out-of-band SQL Injection 帶外SQL注入
C: Blind SQL Injection
D: In-band SQL Injection 同通道SQL注入

In-band SQL Injection 同通道注入

攻擊者注入 SQL,結果直接顯示在網頁回應中,用的是同一個通道
讓資料從原本攻擊的地方看到

Inferential/Blind 推論式/盲注(同義詞)

靠回應的真假反應推測資料,不會讓資料庫主動對外送封包
簡單來說就是看不到資料,只能靠系統反應來推

Out-of-band SQL Injection 帶外注入

帶外注入走的是另一條通道,逼資料庫自己發 DNS 查詢、把要偷的資料夾在網域名稱裡送出去,正是題目描述的手法
簡單來說就是讓資料走另一個通道出來


上一篇
DAY30-31 作業系統安全與事件控制
下一篇
DAY33 工作階段安全/XSS/CSRF
系列文
格鬥教練想轉職學資安是否搞錯了什麼(自學第一步)IPAS初級筆記 共 32 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言