以下是填帳號密碼的欄位,接收到開發者預期的正常輸入,再根據使用者的輸入去撈資料。
[ 正常輸入 ]
// 接收輸入的 SQL
SELECT * FROM users WHERE user='123' AND pwd='456';
而 SQL Injection 的本質就是把「 輸入的惡意資料」 變成「 程式的一部分 」
意思是駭客可以在輸入資料時,用一些奇怪的方式(惡意字串)竄改 SQL 語法,以偷取、假冒別人資料或刪除資料庫,例如以下輸入就可以成功登入別人帳號:
[ SQL Injection ]
// 接收輸入的 SQL
SELECT * FROM users HWERE user='' or 1=1 --' AND pwd =''; // => 永遠成立
--
: 代表註解,所以後面的條件就被忽略or 1=1
,且 pwd
也因為註解被忽略掉,所以 WHERE
條件永遠成立,就可以成功登入帳號了。Prepare Statement 做的就是幫我們處理 SQL 跳脫這件事
步驟:
bind_param()
的第一個參數,有幾個參數就要寫幾個字元,字元依照參數的資料類型而定
string
=> s
int
=> i
<?php
$stat = $conn->prepare("SELECT * FROM users WHERE username=? and pwd=?"); // => 把參數換成 ?
$stat->bind_param('ss', $username, $password); // => 替換成準備好的參數
$stat->execute(); // => 執行 query 語法
$result = $stat->getResult(); // => 執行結果
if ($result->num_rows > 0) {
$row = $result->fetch_assoc(); // => 撈資料
}
?>
在別人網站執行 Javascript
跟 SQL Injection 一樣,本質也是讓使用者「 輸入的資料」 變成「 程式的一部分 」
利用 input 欄位可以輸入內容的特性,只要使用者輸入特別的 JS 語法,且網頁有 輸出此內容 的時候,就可以竄改網頁或竊取資料。
XSS 漏洞分為幾種類型:
<input type="text" placeholder="輸入內容"> // 輸入欄位
<script>alert("XSS攻擊測試");</script> // 輸入惡意碼
<p>文字文字文字</p> // => 正常輸出
<p><script>alert("XSS攻擊測試");</script></p> // => 不正常輸出,且每個使用者都會中標
如果網頁是在網址上用參數判斷狀態:login.php?status='登入失敗'
,且輸出錯誤訊息的方式是 直接把 value 印在網頁上,那麼只要把 value 換成 js 語法就可以攻擊成功
// 網頁程式
if (isset($_GET['status']) && !empty($_GET['status'])) {
echo $_GET['status'];
}
// 網址列
http://www.example.com?status='新增成功' => 印出新增成功
http://www.example.com?status=<script>alert(1)</script> => 執行惡意程式
.html()
或 .innerHTML()
的語法.innerText()
=> 只會輸出純文字最常見的是偷 cookie 資料:
<img>
(因為不受同源政策影響),然後在 src
裡面發送一個 帶著 cookie 資訊的 reqeust,傳送到自己的 Server,這樣就可以拿到點此網址的使用者 cookie 了<img src="" onerror="sendRequest('document.cookie')">
// src 讀取失敗,執行 onerror
// sendRequest() => 只是拿來說明可以送 request 到自己 Server,單純舉例用
檢查有無惡意碼的時機,可以分為在「輸入之前」跟「輸出之前」,一般建議是無論如何、輸出端的檢查一定要做!
因為 XSS 有太多漏洞可以鑽: HTML, JavaScript, CSS, XML, URL,要很完整對輸入做防範非常困難。
例如刪除所有 <script>
、 onerror
及其他可以執行 JS 的字串,但設黑名單也不是一個理想的方式,因為有太多種變形可以換,白名單是比較推薦的作法,只是要寫的完整也是非常麻煩。
// php 跳脫字元的內建函式 htmlspecialchars
echo htmlspecialchars($str, ENT_QUOTES, 'utf-8')
// 輸出時需要 encoding
& --> &
< --> <
> --> >
" --> "
' --> '
/ --> /
參考資料:
( 以上內容大部分是 程式導師實驗計畫第三期 的學習筆記,如有錯誤歡迎糾正,非常感謝 🤓 )
Written on July 2nd , 2019 by Yakim shu