Skip to main content

網站常見的資安問題有哪些?

常見的網站資安問題與防範措施

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);

操作步驟

  1. 將用戶輸入的內容傳入 displayComment 函數。

  2. 使用 textContent 確保輸入不會被當作 HTML 或 JavaScript 執行。

  3. 若需要顯示 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();
});

操作步驟

  1. 確保後端提供一個 API(如 /api/get-csrf-token)來生成唯一的 CSRF Token。

  2. 在表單提交前,動態將 token 加入表單的隱藏欄位。

  3. 後端驗證請求是否包含正確的 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(); // 阻止表單提交
}
});

操作步驟

  1. 在表單輸入欄位添加事件監聽器,檢查用戶輸入。

  2. 使用正則表達式(regular expression)限制輸入格式。

  3. 若輸入無效,阻止表單提交並提示用戶。


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>

操作步驟

  1. 從可信任的 CDN(如 jQuery 官方網站)取得資源的 SRI 雜湊值。

  2. <script> 標籤中添加 integrity 屬性,確保瀏覽器驗證檔案完整性。

  3. 若檔案被篡改,瀏覽器將拒絕執行。


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);
}

操作步驟

  1. 在頁面載入時檢查 window.location.protocol。

  2. 若協議不是 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));

操作步驟

  1. 在專案根目錄建立 .env 檔案,加入 VITE_API_KEY=你的金鑰

  2. 使用 import.meta.env 取得環境變數。

  3. 確保 .env 檔案不被上傳到 Git(加入 .gitignore)。


總結

以上是網站常見的資安問題及其防範措施,特別針對前端工程師的角色,提供實用的 JavaScript 程式碼範例。以下是快速重點整理:

  • XSS:使用 textContent 或 DOMPurify 過濾用戶輸入。

  • CSRF:加入 CSRF Token 並驗證請求來源。

  • SQL 注入:前端進行輸入驗證,與後端配合使用參數化查詢。

  • 第三方資源:使用 SRI 確保資源完整性。

  • 資料傳輸:強制 HTTPS 並檢查協議。

  • 敏感資料:使用環境變數,避免硬編碼。