跳至主要内容

9 篇文章 含有標籤「web」

檢視所有標籤

Web 前端效能優化入門教學筆記 | 學習筆記

· 閱讀時間約 4 分鐘
kdchang

在網頁開發中,效能優化是一個不可忽視的重要課題。無論是企業網站、單頁應用(SPA),或是電商平台,效能表現都直接影響使用者體驗與轉換率。

本篇筆記將介紹 Web 前端效能優化的核心概念、常見策略與實務範例,幫助你為專案建立良好的基礎。


為什麼需要前端效能優化?

前端效能不佳會導致:

  • 首次載入時間過長
  • 使用者等待過久,產生跳出行為
  • SEO 表現不佳(Google 會參考 LCP、CLS、FCP 等指標)

透過有效的優化策略,我們能讓網站更快、更穩、更吸引人。


效能優化的三個層面

  1. 載入效能(Loading Performance):提升頁面初始載入速度。
  2. 互動效能(Interaction Performance):優化點擊、滑動等互動的流暢度。
  3. 渲染效能(Rendering Performance):減少重繪、重排與動畫卡頓。

一、減少不必要的資源請求

使用 CDN

透過 CDN(Content Delivery Network)可將靜態資源分發到全球節點,加速載入。

<!-- 使用 Google Fonts CDN -->
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet" />

合併與壓縮資源(Minify & Bundle)

使用打包工具如 Webpack、Vite,可以:

  • 將 JS / CSS 壓縮(Minify)
  • 移除註解與空白
  • 合併多個檔案減少 HTTP 請求數量

範例(Webpack 設定簡略):

// webpack.config.js
module.exports = {
mode: 'production', // 自動啟用壓縮
entry: './src/index.js',
output: {
filename: 'bundle.js',
},
};

二、圖片與多媒體優化

適當圖片格式

  • 使用 WebPAVIF 取代 JPEG / PNG,可減少檔案體積 25% 以上
  • SVG 適用於圖示與 icon,解析度不會失真

延遲載入圖片(Lazy Loading)

<img src="thumbnail.jpg" loading="lazy" alt="延遲載入圖片" />

或搭配 JavaScript 實現滾動載入。


三、有效使用 Cache(快取)

設定 Cache-Control 標頭

在伺服器上設定靜態資源快取策略:

Cache-Control: max-age=31536000, immutable

適用於版本化的資源檔案(如 main.123abc.js),可快取一年不變。


四、精簡 CSS 與 JavaScript

移除未使用的 CSS(Tree Shaking)

使用工具如 PurgeCSSTailwindCSS JIT Mode 可自動剔除沒用到的樣式。

PurgeCSS 使用方式(簡略):

const purgecss = require('@fullhuman/postcss-purgecss');

module.exports = {
plugins: [
purgecss({
content: ['./**/*.html'],
}),
],
};

延遲載入 JS(Defer / Async)

<script src="main.js" defer></script>
  • defer: 等 DOM 解析完才執行,不阻塞渲染
  • async: 載入完成即執行,適合非必要腳本(如 GA)

五、避免過度重排與重繪

使用 class 切換取代 style 修改

重複直接操作 DOM style 屬性會導致效能下降,改用 CSS class 控制樣式較佳。

// 不推薦
element.style.width = '100px';
element.style.height = '50px';

// 推薦
element.classList.add('resized');
.resized {
width: 100px;
height: 50px;
}

使用 transformopacity 進行動畫

避免透過 topleftwidth 等影響 layout 的屬性來做動畫。

/* 推薦做法:使用 transform */
.card {
transition: transform 0.3s ease;
}
.card:hover {
transform: scale(1.05);
}

六、最佳化 DOM 結構與渲染

  • 減少過深的 DOM 巢狀結構
  • 使用虛擬滾動(Virtual Scroll)載入大量列表
  • 避免頻繁操作 DOM,應該一次性改動(使用 DocumentFragment 或 requestAnimationFrame)

七、使用開發工具檢查效能

Chrome DevTools

  1. Lighthouse:提供整體效能建議
  2. Performance Panel:檢查 JS 執行、動畫、Layout shift 等問題
  3. Network Panel:觀察資源大小、載入順序與快取狀態

總結與建議實作順序

若你剛開始進行專案的效能優化,可以依照以下順序著手:

  1. 壓縮與合併 JS / CSS
  2. 圖片格式轉換與 Lazy Load
  3. CDN 部署靜態資源
  4. 移除未使用樣式與延遲載入腳本
  5. 改善動畫與 DOM 操作
  6. 導入快取策略
  7. 使用 Lighthouse 檢查並優化問題

效能優化並非一次性工作,而是一個持續調整的過程。建議我們可以從專案開始就納入效能考量,將它當成基本開發原則來實踐。

參考文件

  1. Core Web Vitals: An everyday explanation (Taiwanese with English subtitles)

Web 資訊安全入門教學筆記 | 學習筆記

· 閱讀時間約 4 分鐘
kdchang

在現代網頁應用中,資安問題層出不窮,從簡單的跨站攻擊(XSS)到複雜的憑證竊取、身份偽造(CSRF),都可能導致個資外洩、系統遭入侵甚至企業商譽受損。

本篇筆記將從實務角度出發,介紹幾種常見 Web 資安風險及其防範策略,讓你能以最基本的方式保護網站與使用者安全。


一、常見 Web 資安威脅類型

1. XSS(Cross-Site Scripting,跨站腳本攻擊)

原理:攻擊者將惡意腳本注入至網站,當其他使用者瀏覽該頁面時,惡意腳本便會在其瀏覽器上執行,例如竊取 cookie、冒充使用者操作等。

實例:

<!-- 攻擊者輸入的留言內容 -->
<script>alert('你被 XSS 攻擊了');</script>

若網站未正確處理輸入,這段 JavaScript 就會直接被執行。

防範方式:

  • 對所有輸入進行 轉義(Escape)
  • 使用前端框架自動編碼機制(如 React 的 JSX)
  • 避免使用 innerHTML 插入未清洗的資料

範例(JavaScript 轉義文字):

function escapeHtml(str) {
return str
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}

2. CSRF(Cross-Site Request Forgery,跨站請求偽造)

原理:攻擊者引導使用者點擊惡意連結或載入圖片,使其在未察覺情況下對已登入的網站發送請求,進而竄改資料或觸發操作。

實例:

<!-- 攻擊者網站中隱藏圖片,觸發某網站的轉帳請求 -->
<img src="https://bank.com/transfer?amount=1000&to=attacker" />

如果使用者已登入 bank.com 且未防範 CSRF,就可能無意間轉帳。

防範方式:

  • 後端驗證 CSRF Token
  • 使用 SameSite Cookie 屬性
  • 僅允許 POST / PATCH / DELETE 操作變更狀態
  • 驗證 Referer / Origin 標頭(有風險)

範例(Express + CSRF Token):

const csrf = require("csurf");
const cookieParser = require("cookie-parser");

app.use(cookieParser());
app.use(csrf({ cookie: true }));

app.get("/form", (req, res) => {
res.render("form", { csrfToken: req.csrfToken() });
});

3. SQL Injection(SQL 注入)

原理:透過惡意輸入拼接 SQL 查詢語句,導致資料庫查詢異常,甚至刪除資料。

實例:

-- 假設未使用參數化查詢
SELECT * FROM users WHERE username = '' OR 1=1;

攻擊者輸入 ' OR 1=1; -- 可繞過認證邏輯,取得所有帳戶資料。

防範方式:

  • 使用 ORM 或預處理語句(Prepared Statement)
  • 不拼接 SQL 字串,改用參數綁定
  • 限制資料庫帳號權限

範例(Node.js + MySQL):

const username = req.body.username;
const password = req.body.password;

const query = "SELECT * FROM users WHERE username = ? AND password = ?";
connection.query(query, [username, password], function (err, results) {
// 安全地查詢
});

4. 資料傳輸未加密(缺少 HTTPS)

原理:若網站使用 HTTP,使用者資料(如帳號密碼、金流資訊)在傳輸過程中可能被中間人攔截(Man-in-the-Middle attack)。

防範方式:

  • 強制使用 HTTPS(導入憑證)
  • 使用 HSTS(HTTP Strict Transport Security)
  • 移除 HTTP 存取(使用 301 重導)

範例(NGINX 強制 HTTPS):

server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}

5. 檔案上傳風險

原理:攻擊者透過檔案上傳功能傳入惡意腳本(如 .php.jsp),若伺服器未阻擋,可能導致遠端代碼執行。

防範方式:

  • 限制可上傳的檔案類型與副檔名
  • 不讓使用者可直接存取上傳目錄
  • 使用 UUID 改名,避免原檔名執行

附加安全性強化機制

HTTP 安全標頭設定(Security Headers)

使用如 Helmet(Express.js 中間件)快速加入以下標頭:

  • Content-Security-Policy:防止 XSS 和資源注入
  • X-Frame-Options:防止點擊劫持(Clickjacking)
  • X-Content-Type-Options:避免 MIME 類型混淆
  • Strict-Transport-Security:強制 HTTPS

範例(Node.js + Helmet):

const helmet = require("helmet");
app.use(helmet());

總結與建議實作順序

如果剛開始建立 Web 專案,可以按照以下步驟檢查安全性:

  1. 輸入驗證與輸出轉義,防範 XSS
  2. 加入 CSRF Token 機制
  3. 資料庫查詢全面使用預處理語句
  4. 部署 HTTPS 並強制重導
  5. 使用 Helmet 加強安全標頭
  6. 定期檢查依賴套件漏洞(如 npm audit

資訊安全並非一勞永逸,而是一種持續維護的工作。建議我們可以將資安意識融入日常開發流程中,隨時更新資安知識與工具。

Django CRUD(不使用 ModelForm)入門教學筆記 | 學習筆記

· 閱讀時間約 4 分鐘
kdchang

在 Django 中,ModelForm 提供了一個快速建立表單與驗證的工具,但在某些情境下,我們可能希望自己掌控表單結構與驗證流程。這篇筆記將示範如何不依賴 ModelForm,手動實作一套 CRUD 系統,幫助你更深入理解 Django 表單處理的基本原理。

我們將製作一個簡單的「書籍管理系統」,支援新增(Create)、讀取(Read)、更新(Update)與刪除(Delete)書籍資訊。

1. 建立 Django 專案與應用

首先,安裝 Django 並建立新的專案與應用:

pip install django
django-admin startproject myproject
cd myproject
python manage.py startapp books

註冊 books 應用於 myproject/settings.pyINSTALLED_APPS

INSTALLED_APPS = [
...
'books',
]

2. 定義模型(Model)

books/models.py 中定義一個簡單的書籍模型:

from django.db import models

class Book(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
published_date = models.DateField()

def __str__(self):
return self.title

遷移資料庫:

python manage.py makemigrations
python manage.py migrate

3. 撰寫 Views(不使用 ModelForm)

books/views.py 中撰寫手動處理的 CRUD 功能。

新增書籍(Create)

from django.shortcuts import render, redirect
from .models import Book
from django.utils.dateparse import parse_date

def create_book(request):
if request.method == 'POST':
title = request.POST.get('title')
author = request.POST.get('author')
published_date_str = request.POST.get('published_date')
published_date = parse_date(published_date_str)

if title and author and published_date:
Book.objects.create(title=title, author=author, published_date=published_date)
return redirect('book_list')
else:
error = "所有欄位皆為必填"
return render(request, 'books/book_form.html', {'error': error})
return render(request, 'books/book_form.html')

讀取書籍(Read)

def book_list(request):
books = Book.objects.all()
return render(request, 'books/book_list.html', {'books': books})

更新書籍(Update)

from django.shortcuts import get_object_or_404

def update_book(request, pk):
book = get_object_or_404(Book, pk=pk)
if request.method == 'POST':
title = request.POST.get('title')
author = request.POST.get('author')
published_date_str = request.POST.get('published_date')
published_date = parse_date(published_date_str)

if title and author and published_date:
book.title = title
book.author = author
book.published_date = published_date
book.save()
return redirect('book_list')
else:
error = "所有欄位皆為必填"
return render(request, 'books/book_form.html', {'book': book, 'error': error})
return render(request, 'books/book_form.html', {'book': book})

刪除書籍(Delete)

def delete_book(request, pk):
book = get_object_or_404(Book, pk=pk)
if request.method == 'POST':
book.delete()
return redirect('book_list')
return render(request, 'books/book_confirm_delete.html', {'book': book})

4. 設定 URL 路由

books/urls.py 中設定對應的路由:

from django.urls import path
from . import views

urlpatterns = [
path('', views.book_list, name='book_list'),
path('create/', views.create_book, name='create_book'),
path('update/<int:pk>/', views.update_book, name='update_book'),
path('delete/<int:pk>/', views.delete_book, name='delete_book'),
]

並在 myproject/urls.py 引入 books 路由:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('books/', include('books.urls')),
]

5. 建立模板(Templates)

手動撰寫簡單的 HTML 表單與顯示畫面。

book_list.html

<h1>書籍列表</h1>
<a href="{% url 'create_book' %}">新增書籍</a>
<ul>
{% for book in books %}
<li>
{{ book.title }} - {{ book.author }} - {{ book.published_date }}
<a href="{% url 'update_book' book.id %}">編輯</a>
<a href="{% url 'delete_book' book.id %}">刪除</a>
</li>
{% endfor %}
</ul>

book_form.html

<h1>{% if book %}編輯書籍{% else %}新增書籍{% endif %}</h1>

{% if error %}
<p style="color:red;">{{ error }}</p>
{% endif %}

<form method="post">
{% csrf_token %}
<p>
標題:<input type="text" name="title" value="{{ book.title|default_if_none:'' }}">
</p>
<p>
作者:<input type="text" name="author" value="{{ book.author|default_if_none:'' }}">
</p>
<p>
出版日期(格式 yyyy-mm-dd):<input type="text" name="published_date" value="{{ book.published_date|default_if_none:'' }}">
</p>
<button type="submit">儲存</button>
</form>

<a href="{% url 'book_list' %}">返回列表</a>

book_confirm_delete.html

<h1>刪除書籍</h1>
<p>確定要刪除 "{{ book.title }}" 嗎?</p>
<form method="post">
{% csrf_token %}
<button type="submit">確定刪除</button>
</form>
<a href="{% url 'book_list' %}">取消</a>

6. 啟動伺服器測試

啟動 Django 開發伺服器:

python manage.py runserver

在瀏覽器開啟 http://127.0.0.1:8000/books/,你將可以新增、查詢、編輯和刪除書籍。


總結

這篇教學示範了在 不使用 ModelForm 的情況下,手動撰寫表單處理與資料驗證,完整實作了 Django 的 CRUD 功能。

這種方式的優點在於靈活度高,你可以完全控制表單的結構、驗證邏輯與錯誤處理,非常適合需要客製化表單行為或前後端分離的專案。不過,相較於使用 ModelForm,開發成本略高,也容易產生重複程式碼,因此適時選擇工具是重要的工程判斷。

進一步的優化方向包括:

  • 加入更完整的資料驗證
  • 增加欄位格式錯誤提示
  • 使用 JavaScript 增強表單互動
  • 將表單資料與邏輯封裝成 Class-Based Views(CBV)

透過本篇範例,希望你對 Django 低階處理表單與 CRUD 流程有更深入的理解。

FastAPI 入門教學筆記:打造現代 Python Web API 的入門教學筆記 | 學習筆記

· 閱讀時間約 3 分鐘
kdchang

什麼是 FastAPI?

FastAPI 是一個現代、快速(高效能)、基於 Python 3.7+ 類型提示的 Web 框架,用於建構 API。其核心優勢包含:

  • 自動生成文件:內建 OpenAPI 與 Swagger UI 支援
  • 高效能:基於 Starlette 和 Pydantic,效能可媲美 Node.js 與 Go
  • 開發快速:強大的 IDE 支援與自動補全功能
  • 自動驗證與序列化:透過 Pydantic 型別自動完成

FastAPI 適合快速構建 RESTful API,尤其在開發微服務、機器學習模型部署、或任何 API 後端都非常合適。


快速開始:環境準備與安裝

建議使用虛擬環境管理專案依賴。

python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install fastapi uvicorn
  • fastapi:核心框架
  • uvicorn:ASGI Server,用來啟動應用程式

第一個 FastAPI 程式:Hello API

# main.py

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
return {"message": "Hello, FastAPI!"}

啟動應用程式:

uvicorn main:app --reload
  • --reload:啟用熱重載,開發時會自動重新載入程式

訪問 http://127.0.0.1:8000/,你會看到:

{
"message": "Hello, FastAPI!"
}

自動生成的互動式 API 文件

FastAPI 自動提供兩個 API 文件頁面:

  • Swagger UI:http://127.0.0.1:8000/docs
  • Redoc:http://127.0.0.1:8000/redoc

這些文件會根據程式中的路由與型別提示自動生成,方便前後端協作與測試。


使用路由參數與查詢參數

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}

範例請求:

GET /items/42?q=fastapi

回應結果:

{
"item_id": 42,
"q": "fastapi"
}
  • item_id 是路由參數,會自動轉換為 int
  • q 是查詢參數,預設為 None

接收與驗證請求資料:使用 Pydantic 模型

from pydantic import BaseModel

class Item(BaseModel):
name: str
description: str = None
price: float
in_stock: bool = True

@app.post("/items/")
def create_item(item: Item):
return {"message": "Item created", "item": item}

發送 POST 請求:

POST /items/
{
"name": "Laptop",
"description": "A powerful device",
"price": 1299.99,
"in_stock": true
}

回應:

{
"message": "Item created",
"item": {
"name": "Laptop",
"description": "A powerful device",
"price": 1299.99,
"in_stock": true
}
}
  • Pydantic 會自動進行資料驗證與轉換
  • FastAPI 可根據模型自動生成 API 文件

表單與檔案上傳支援

from fastapi import Form, UploadFile, File

@app.post("/submit/")
def submit_form(username: str = Form(...), file: UploadFile = File(...)):
return {
"username": username,
"filename": file.filename,
"content_type": file.content_type
}

這對於處理使用者上傳檔案與表單資料非常方便。


回傳自定義 HTTP 狀態碼與錯誤處理

from fastapi import HTTPException

@app.get("/users/{user_id}")
def read_user(user_id: int):
if user_id != 1:
raise HTTPException(status_code=404, detail="User not found")
return {"user_id": user_id, "name": "Alice"}

這會回傳:

{
"detail": "User not found"
}

並帶有 HTTP 404 錯誤。


小結與下一步學習方向

FastAPI 提供了一種現代化且優雅的方式來構建 API:

  • 強大的型別檢查與 IDE 支援
  • 直覺的程式結構與文件生成
  • 高效能適合用於生產環境

建議學習方向:

  1. 路由分割與模組化管理
  2. 使用依賴注入(Depends)
  3. 整合資料庫(如 SQLAlchemy)
  4. JWT 身份驗證與 OAuth2
  5. 測試與部署(例如 Docker、Gunicorn)

如果你是從 Flask 或 Django REST Framework 轉過來,會發現 FastAPI 提供了相當先進的開發體驗與高效能,是非常值得學習與投入的框架。

參考文件

  1. fastapi API

10 key terms related to backend engineering

· 閱讀時間約 1 分鐘
kdchang

Here are 10 key terms related to backend engineering, covering essential skills, tools, and work methodologies:

  1. Node.js / Python / Java / Ruby / PHP – Common backend programming languages used to build server-side applications.

  2. Database – Includes SQL (e.g., MySQL, PostgreSQL) and NoSQL (e.g., MongoDB, Redis) for data storage, management, and optimization.

  3. REST API / GraphQL – Designing and implementing server-side APIs to support frontend data requests.

  4. Authentication & Authorization – Technologies like OAuth, JWT, and session management to ensure user security and data protection.

  5. Docker / Kubernetes – Containerization and orchestration tools for application deployment and resource management.

  6. Cloud Services – Platforms like AWS, Google Cloud, and Microsoft Azure for cloud-based application hosting and operations.

  7. Microservices – Architectural style for designing modular and independently deployable services.

  8. Message Queues – Tools like RabbitMQ and Kafka for asynchronous communication in distributed systems.

  9. Version Control – Systems like Git/GitHub for code management and team collaboration.

  10. Performance Optimization – Techniques for improving server and database performance to enhance system efficiency.

These key concepts form the foundation of a backend engineer’s work and career growth. By continuously gaining experience and developing projects, one can become a more proficient software engineer.

關於 Web 網頁後端工程師 Backend Engineer 的 10 個關鍵字

· 閱讀時間約 2 分鐘
kdchang

以下整理了後端工程師相關的 10 個關鍵字,涵蓋技能、工具與工作方式:

  1. Node.js / Python / Java / Ruby / PHP:常見的後端程式語言,用於構建伺服器端應用程式。

  2. Database(資料庫):包括 SQL(如 MySQL, PostgreSQL)NoSQL(如 MongoDB, Redis) 的操作與優化。

  3. REST API / GraphQL:設計與實現伺服器端 API 以支援前端資料請求。

  4. Authentication & Authorization(認證與授權):如 OAuth、JWT、Session,確保使用者安全與數據保護。

  5. Docker / Kubernetes:容器化與編排工具,用於應用部署與資源管理。

  6. Cloud Services:如 AWS、Google Cloud、Microsoft Azure,支援應用程式的雲端部署與運行。

  7. Microservices(微服務架構):設計可拆分且可獨立部署的服務模組。

  8. Message Queues(訊息佇列):如 RabbitMQ、Kafka,用於分布式系統的非同步通訊。

  9. Version Control(版本控制):如 Git / GitHub,用於團隊協作與程式碼管理。

  10. Performance Optimization(效能優化):針對伺服器與資料庫的效能調優,提升系統效率。

以上關鍵字為後端工程師平常工作或是職涯的核心工作內容和技能樹,透過不斷累積相關經驗和專案開發能力,可以讓自己成為更優秀的軟體工程師。

關於 Web 網頁前端工程師 Frontend Engineer 的 10 個關鍵字

· 閱讀時間約 2 分鐘
kdchang

以下整理了前端工程師相關的 10 個關鍵字,涵蓋技能、工具與工作方式:

  1. HTML:前端結構的基礎語言,用於定義網頁的內容和結構。

  2. CSS:用於設計網頁的樣式,包括佈局、配色和字體。

  3. JavaScript:前端開發的核心語言,為網頁添加互動性。

  4. React / Vue / Angular:主流的前端框架和函式庫,用於構建動態、模組化的應用程式。

  5. Responsive Design(響應式設計):確保網站在不同裝置和螢幕大小下的最佳顯示效果。

  6. REST API / GraphQL:前端與後端通訊的重要工具,用於前後端資料請求與傳輸。

  7. Webpack / Vite / Parcel:模組打包工具,用於構建和優化前端資源。

  8. Git / GitHub / GitLab:版本控制工具,用於協作開發與代碼管理。

  9. Cross-Browser Compatibility(跨瀏覽器相容性):確保網站在不同瀏覽器上的一致性表現。

  10. UI/UX Design(使用者介面/使用者體驗設計):理解使用者需求,優化網頁的易用性與美觀度。

以上關鍵字為前端工程師平常工作或是職涯的核心工作內容和技能樹,透過不斷累積相關經驗和專案開發能力,可以讓自己成為更優秀的軟體工程師。

Web 資訊安全(Security)簡明入門教學指南

· 閱讀時間約 7 分鐘
kdchang

隨著越來越多的服務和資料連上網路,Web 資訊安全已經是 Web 開發中一個重要的環節,然而許多開發者往往希望專注在應用程式的研發,而忽略了資訊安全的重要性。不過若是沒有嚴謹地考慮資訊安全的問題,等到事情發生後反而會造成更嚴重的財務和名譽上的損失。本文希望整理一些 Web 常見資訊安全(Security)的議題和學習資源和讀者一起教學相長,下次建構網路服務時可以更留心 Web 的資訊安全,甚至努力成為一個好的白帽駭客(White Hat Hacker)。

常見 Web 資訊安全(Security)議題

一般而言 Web 資訊安全(Security)需要符合三點安全要素:

  1. 保密性:透過加密等方法確保資料的保密性
  2. 完整性:要求使用者取得的資料是完整不可被竄改的
  3. 可用性:保證網站服務的持續可訪問性

以下列出常見影響 Web 資訊安全(Security)的攻擊手法:

  1. SQL Injection

    使用惡意的 SQL 語法去影響資料庫內容:

    // -- 為忽略掉後面的 SQL
    /user/profile?id=1";DROP TABLE user--

    SELECT * FROM USER WHERE id = "1"; DROP TABLE user--

    使用者登入:

    // password" AND 1=1--
    SELECT * FROM USER WHERE username = "Mark"; AND 1=1-- AND PASSWORD="1234"

    簡易防範方式:不信任使用者輸入的資料,確保使用者輸入都要 escape 掉,目前許多成熟 Web 框架都有支援 ORM 服務,大部分都基本防範了 SQL Injection。

  2. XSS(Cross-Site Scripting) XSS 亦即將惡意程式碼注入到網頁,讓看到網頁的使用者會受影響,常見的受災戶包括論壇、討論區等網路服務。事實上 XSS 概念很簡單,透過表單輸入建立一些惡意網址、惡意圖片網址或是 JavsScript 程式碼在 HTML 中注入,當使用者觀看頁面時即會觸發。

    <img src="" onerror="alert('XSS')" />

    更多關於 XSS 資料可以參考 XSS Filter Evasion Cheat Sheet。另外也有簡體中文版

    簡易防範方式:不信任使用者輸入的資料,將所有輸入內容編碼並過濾。

  3. CSRF

    CSRF 跨站請求偽造 又被稱為 one-click attack 或者 session riding,通常縮寫為 CSRF 或者 XSRF, 是一種挾制用戶在當前已登入的 Web 應用程式上執行非本意的操作的攻擊方法。

    舉維基百科上的例子:假如一家銀行用以執行轉帳操作的 URL 地址如下:

    http://www.examplebank.com/withdraw?account=AccoutName&amount=10000&for=PayeeName

    那麼,一個惡意攻擊者可以在另一個網站上放置如下代碼:

    <img src="http://www.examplebank.com/withdraw?account=Mark&amount=10000&for=Bob">

    若是使用者的登入資訊尚未過期的話就會損失 10000 元的金額。

    簡易防範方式:

    1. 檢查 Referer 欄位 這是比較基本的驗證方式,通常 HTTP 標頭中有一個 Referer 欄位,其應該和 Request 位置在同一個網域下,因此可以透過驗證是否是在同一個網域來驗證是否為惡意的請求,但會有被更改偽裝的可能。

    2. 添加驗證 token 一般現在許多的 Web Framework 都有提供在表單加入由 Server 生成的隨機驗證 CSRF 的碼,可以協助防止 CSRF 攻擊。

  4. DoS Dos 阻斷式攻擊(Denial of Service Attack)又稱為洪水攻擊,是一種網路攻擊手法,其目的在於使目標電腦的網路或系統資源耗盡,使服務暫時中斷或停止,導致真正的使用者無法使用服務。

    根據維基百科:DoS 攻擊可以具體分成兩種形式:頻寬消耗型 以及 資源消耗型,它們都是透過大量合法或偽造的請求占用大量網路以及器材資源,以達到癱瘓網路以及系統的目的。

    頻寬消耗攻擊又分洪泛攻擊或放大攻擊:洪泛攻擊的特點是利用殭屍程式傳送大量流量至受損的受害者系統,目的在於堵塞其頻寬。放大攻擊和洪泛攻擊類似,是通過惡意放大流量限制受害者系統的頻寬;其特點是利用殭屍程式通過偽造的源 IP(即攻擊目標)向某些存在漏洞的伺服器傳送請求,伺服器在處理請求後向偽造的源 IP 傳送應答,由於這些服務的特殊性導致應答包比請求包更長,因此使用少量的頻寬就能使伺服器傳送大量的 Response 到目標主機上。

    資源消耗型又分為協定分析攻擊(SYN flood,SYN 洪水)、LAND attack、CC 攻擊、殭屍網路攻擊、Application level floods(應用程式級洪水攻擊)等。

    簡易防範方式:

    1. 防火牆 設定規則阻擋簡單攻擊

    2. 交換機 大多交換機有限制存取控制功能

    3. 路由器 大多路由器有限制存取控制功能

    4. 黑洞啟動 將請求轉到空介面或是不存在的位置

  5. 檔案上傳漏洞 許多網路應用程式可以讓使用者上傳檔案到伺服器端,由於我們不知道使用者會上傳什麼類型的檔案,若不留意就會造成很大的問題。

    簡單防範方式:

    1. 阻止非法文件上傳

      • 設定檔名白名單
      • 文件標頭判斷
    2. 阻止非法文件執行

      • 存儲目錄與 Web 應用分離
      • 存儲目錄無執行權限
      • 文件重命名
      • 圖片壓縮
  6. 加密安全 有許多的網路服務有提供會員註冊的服務,當使用者使用註冊時注意不要將密碼明碼存入資料庫。若是你使用的服務會在忘記密碼時寄明碼密碼給你很有可能該服務就是使用明碼加密,此時就很容易會榮登我的密碼沒加密的網站。不過儘管將密碼加密也未必安全,像是網路上就存在一些破解網站彩虹表 可以破解加密的密碼。所以通常我們會針對不同使用者使用隨機產生的 salt 字串來加鹽後加密的方式來提高密碼的強健性。

    sha3(salt + gap + password)

簡易資安入侵流程

  1. 偵查(Reconnaissance) 攻擊者準備攻擊之前進行的調查,使用 Google 或是社交工程找尋目標的相關資訊,以利之後的攻擊

  2. 掃描(Scanning) 掃描目標主機的弱點,取得主機作業系統、服務和運作狀況等相關資訊

  3. 取得權限(Gaining Access) 利用系統弱點取得主機權限

  4. 維持權限(Maintaining Access) 維持目前取得的權限,以便日後再次存取而不需繁雜的步驟

  5. 清除足跡(Clearing Tracks) 清除入侵的痕跡

總結

以上整理一些 Web 常見資訊安全(Security)的議題和學習資源和讀者一起教學相長,成為一個好的白帽駭客(White Hat Hacker)。隨著網路科技的發展,資訊安全的議題只會越來越重要,當下次當有產品要上線到正式環境時,不妨使用 The Security Checklist 確認一下有哪些資安注意事項是我們沒有注意到的。

延伸閱讀

  1. Web Security 網站安全基礎篇(一)
  2. Web Security 網站安全基礎篇(二)
  3. 3 個免費的 Web 資訊安全自動化測試工具
  4. HITCON 2016 投影片 - Bug Bounty 獎金獵人甘苦談 那些年我回報過的漏洞
  5. FallibleInc/security-guide-for-developers
  6. [資訊安全]防範 Cross-Site-Scripting(XSS)
  7. 網站防範 XSS 攻擊的關鍵思考