網站常見的資安問題有哪些?
常見的網站資安問題與防範措施
1. 跨站腳本攻擊 (Cross-Site Scripting, XSS)
問題描述: XSS 是一種攻擊方式,駭客將惡意 JavaScript 程式碼注入到網站中,當其他用戶訪問時,這些程式碼會在用戶的瀏覽器中執行,可能竊取用戶的 cookie、session 資料或執行其他惡意行為。
常見情境:
-
用戶輸入未經處理的資料(例如在留言板輸入
<script>alert('Hacked!')</script>
),直接顯示在網頁上。 -
從 URL 或外部來源載入未過濾的內容。
防範措施:
-
對用戶輸入進行過濾與轉義:確保用戶輸入的內容不會被當作程式碼執行。
-
使用安全的框架:像 React、Vue.js 等框架會自動對輸出進行轉義。
-
設置 Content Security Policy (CSP):限制網站可執行的腳本來源。
-
避免使用 eval 或 innerHTML:這些方法容易被用來執行惡意程式碼。
JavaScript 範例(防範 XSS):
假設你有一個留言板,需顯示用戶輸入的內容,應該使用安全的轉義方式:
// HTML: <div id="comment-section"></div>
// JavaScript: 安全顯示用戶輸入
function displayComment(userInput) {
// 創建一個元素來存放用戶輸入
const commentSection = document.getElementById("comment-section");
// 使用 textContent 代替 innerHTML,避免執行惡意程式碼
const commentElement = document.createElement("p");
commentElement.textContent = userInput; // 安全轉義用戶輸入
commentSection.appendChild(commentElement);
}
// 模擬用戶輸入(可能包含惡意程式碼)
const userInput = "<script>alert('Hacked!')</script> Hello, World!";
displayComment(userInput);
操作步驟:
-
將用戶輸入的內容傳入
displayComment
函數。 -
使用
textContent
確保輸入不會被當作 HTML 或 JavaScript 執行。 -
若需要顯示 HTML 標籤,考慮使用像
DOMPurify
這樣的庫來過濾惡意程式碼。
額外建議:
-
安裝 DOMPurify 庫(透過 npm 安裝:npm install dompurify)。
-
使用範例:
import DOMPurify from "dompurify";
function displayCommentWithHTML(userInput) {
const commentSection = document.getElementById("comment-section");
const sanitizedHTML = DOMPurify.sanitize(userInput); // 過濾惡意程式碼
const commentElement = document.createElement("p");
commentElement.innerHTML = sanitizedHTML; // 安全插入 HTML
commentSection.appendChild(commentElement);
}
2. 跨站請求偽造 (Cross-Site Request Forgery, CSRF)
問題描述: CSRF 攻擊讓用戶在不知情的情況下,透過已認證的瀏覽器發送惡意請求。例如,駭客誘導用戶點擊惡意連結,執行未經授權的操作(像轉帳或更改密碼)。
常見情境:
-
用戶在登入某網站後,點擊了駭客提供的惡意連結,該連結向網站發送 POST 請求。
-
網站未驗證請求來源,誤以為是合法用戶的操作。
防範措施:
-
使用 CSRF Token:為每個表單生成唯一的隨機 token,伺服器驗證 token 是否有效。
-
檢查 Referer 或 Origin 標頭:確保請求來自可信任的域名。
-
要求二次驗證:對敏感操作(如更改密碼)要求額外的身份驗證。
JavaScript 範例(生成 CSRF Token):
假設你有一個表單需要提交資料,前端需附加 CSRF Token:
// HTML: <form id="myForm" action="/submit" method="POST"></form>
// JavaScript: 動態添加 CSRF Token 到表單
function addCsrfTokenToForm() {
// 假設從後端 API 取得 CSRF Token
fetch("/api/get-csrf-token")
.then((response) => response.json())
.then((data) => {
const form = document.getElementById("myForm");
// 創建隱藏的 CSRF Token 輸入欄位
const csrfInput = document.createElement("input");
csrfInput.type = "hidden";
csrfInput.name = "csrf_token";
csrfInput.value = data.csrfToken; // 從後端取得的 token
form.appendChild(csrfInput);
})
.catch((error) => console.error("無法取得 CSRF Token:", error));
}
// 表單提交時呼叫
document.getElementById("myForm").addEventListener("submit", () => {
addCsrfTokenToForm();
});
操作步驟:
-
確保後端提供一個 API(如 /api/get-csrf-token)來生成唯一的 CSRF Token。
-
在表單提交前,動態將 token 加入表單的隱藏欄位。
-
後端驗證請求是否包含正確的 token。
3. SQL 注入 (SQL Injection)
問題描述: 雖然 SQL 注入主要是後端問題,但前端工程師可能因未過濾用戶輸入而間接導致問題。駭客透過輸入惡意 SQL 語句,操縱後端資料庫,竊取資料或破壞系統。
常見情境:
-
用戶在輸入欄位輸入類似 ' OR '1'='1 的語句,繞過身份驗證。
-
前端未對輸入進行基礎驗證,導致後端直接處理危險資料。
防範措施(前端部分):
-
輸入驗證:限制用戶輸入的格式(如只允許字母、數字)。
-
避免直接將用戶輸入傳給後端:使用參數化查詢或 ORM 框架(後端負責)。
-
提示後端團隊:確保後端使用安全的資料庫操作方式。
JavaScript 範例(輸入驗證):
假設你有一個登入表單,需驗證用戶輸入:
// HTML: <form id="loginForm"><input type="text" id="username"></form>
// JavaScript: 驗證用戶輸入
function validateInput() {
const usernameInput = document.getElementById("username");
const username = usernameInput.value;
// 限制只允許字母、數字和底線
const validPattern = /^[a-zA-Z0-9_]+$/;
if (!validPattern.test(username)) {
alert("帳號只能包含字母、數字和底線!");
usernameInput.value = ""; // 清空無效輸入
return false;
}
// 提交表單
console.log("輸入合法,準備提交:", username);
return true;
}
// 綁定表單提交事件
document.getElementById("loginForm").addEventListener("submit", (event) => {
if (!validateInput()) {
event.preventDefault(); // 阻止表單提交
}
});
操作步驟:
-
在表單輸入欄位添加事件監聽器,檢查用戶輸入。
-
使用正則表達式(regular expression)限制輸入格式。
-
若輸入無效,阻止表單提交並提示用戶。
4. 不安全的第三方資源
問題描述: 網站引用未受信任的第三方腳本(如 CDN 的 JavaScript 檔案)可能引入惡意程式碼,影響網站安全。
常見情境:
-
使用未驗證的 CDN 載入 jQuery 或其他庫。
-
第三方廣告腳本包含惡意程式碼。
防範措施:
-
使用 Subresource Integrity (SRI):為第三方資源添加完整性檢查,確保載入的檔案未被篡改。
-
限制第三方腳本:僅從可信任的來源載入資源。
-
定期檢查依賴:使用工具(如 npm audit)檢查第三方庫的安全性。
JavaScript 範例(使用 SRI): 在 HTML 中載入第三方資源時,加入 SRI:
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"
></script>
操作步驟:
-
從可信任的 CDN(如 jQuery 官方網站)取得資源的 SRI 雜湊值。
-
在
<script>
標籤中添加 integrity 屬性,確保瀏覽器驗證檔案完整性。 -
若檔案被篡改,瀏覽器將拒絕執行。
5. 不安全的資料傳輸
問題描述: 若網站未使用 HTTPS,傳輸的資料(例如表單資料、API 請求)可能被攔截,導致用戶隱私洩露。
常見情境:
-
表單資料透過 HTTP 傳輸,駭客可竊聽用戶的密碼或個人資訊。
-
API 請求未加密,敏感資料暴露。
防範措施:
-
強制使用 HTTPS:確保網站和 API 都使用 TLS/SSL 加密。
-
設置 HSTS:告訴瀏覽器僅透過 HTTPS 訪問網站。
-
前端檢查協議:在前端檢查是否使用 HTTPS,若不是則導向安全頁面。
JavaScript 範例(檢查 HTTPS):
// 檢查當前頁面是否使用 HTTPS
if (window.location.protocol !== "https:") {
// 導向到 HTTPS 版本
window.location.href =
"https:" + window.location.href.substring(window.location.protocol.length);
}
操作步驟:
-
在頁面載入時檢查 window.location.protocol。
-
若協議不是 https:,自動導向 HTTPS 版本。
6. 敏感資料暴露
問題描述: 網站可能不小心在前端暴露敏感資料(如 API 金鑰、用戶隱私資訊),讓駭客輕易取得。
常見情境:
-
API 金鑰硬編碼在 JavaScript 檔案中。
-
錯誤訊息顯示過多後端資訊(如資料庫結構)。
防範措施:
-
避免硬編碼敏感資料:將 API 金鑰等存放在後端或環境變數中。
-
限制錯誤訊息:不要在前端顯示詳細的錯誤訊息。
-
使用環境變數:在前端專案中使用 .env 檔案管理敏感資料。
JavaScript 範例(使用環境變數):
假設使用 Vite 建構工具,需從環境變數載入 API 金鑰:
// .env 檔案:VITE_API_KEY=your-api-key
// JavaScript: 安全取得 API 金鑰
const apiKey = import.meta.env.VITE_API_KEY;
fetch("https://api.example.com/data", {
headers: {
Authorization: `Bearer ${apiKey}`,
},
})
.then((response) => response.json())
.then((data) => console.log("API 回應:", data))
.catch((error) => console.error("API 請求失敗:", error));
操作步驟:
-
在專案根目錄建立
.env
檔案,加入VITE_API_KEY=你的金鑰
。 -
使用
import.meta.env
取得環境變數。 -
確保
.env
檔案不被上傳到 Git(加入.gitignore
)。
總結
以上是網站常見的資安問題及其防範措施,特別針對前端工程師的角色,提供實用的 JavaScript 程式碼範例。以下是快速重點整理:
-
XSS:使用 textContent 或 DOMPurify 過濾用戶輸入。
-
CSRF:加入 CSRF Token 並驗證請求來源。
-
SQL 注入:前端進行輸入驗證,與後端配合使用參數化查詢。
-
第三方資源:使用 SRI 確保資源完整性。
-
資料傳輸:強制 HTTPS 並檢查協議。
-
敏感資料:使用環境變數,避免硬編碼。