Chương 2: HTTP Fundamentals
Khái niệm
HTTP (HyperText Transfer Protocol — Giao thức Truyền tải Siêu văn bản) là nền tảng của mọi giao tiếp trên web. Hiểu HTTP là hiểu cách hacker "nhìn" vào ứng dụng của bạn.
Với Security, HTTP quan trọng vì:
- Mọi cuộc tấn công web đều thực hiện qua HTTP
- Lỗ hổng thường nằm trong cách xử lý headers, parameters, cookies
- Biết cấu trúc HTTP giúp bạn đọc và phân tích traffic khi điều tra
Cách hoạt động
HTTP hoạt động theo mô hình Request-Response:
Client (Browser) Server (Nginx/App)
│ │
│──── HTTP Request ─────►│
│ │ (xử lý)
│◄─── HTTP Response ─────│
│ │
HTTP là stateless (không trạng thái) — mỗi request độc lập, server không nhớ request trước. Vì vậy mới cần cookies và sessions để duy trì trạng thái đăng nhập.
Cấu trúc HTTP Request
POST /api/login HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer eyJhbGc...
Cookie: session=abc123
User-Agent: Mozilla/5.0 ...
Content-Length: 45
{"username": "admin", "password": "secret"}
Giải thích từng phần:
- Request line:
POST /api/login HTTP/1.1— Method + Path + Version - Headers: Metadata của request
- Blank line: Ngăn cách headers và body
- Body: Dữ liệu gửi lên (chỉ có với POST/PUT/PATCH)
Cấu trúc HTTP Response
HTTP/1.1 200 OK
Content-Type: application/json
Set-Cookie: session=xyz789; HttpOnly; Secure; SameSite=Strict
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Content-Security-Policy: default-src 'self'
Content-Length: 89
{"status": "success", "token": "eyJhbGc..."}
Giải thích:
- Status line:
HTTP/1.1 200 OK— Version + Status Code + Reason - Headers: Metadata response, security headers
- Body: Dữ liệu trả về
HTTP Methods
| Method | Mục đích | An toàn? | Idempotent? |
|---|---|---|---|
| GET | Lấy dữ liệu | Có | Có |
| POST | Tạo dữ liệu | Không | Không |
| PUT | Cập nhật toàn bộ | Không | Có |
| PATCH | Cập nhật một phần | Không | Không |
| DELETE | Xóa | Không | Có |
| HEAD | Như GET nhưng không có body | Có | Có |
| OPTIONS | Hỏi server hỗ trợ methods gì | Có | Có |
Security notes:
- GET không nên có side effects — nhưng nhiều app sai điều này, dẫn đến CSRF qua URL
- OPTIONS thường leak thông tin về CORS policy
- PUT/DELETE phải được kiểm soát access chặt chẽ
HTTP Status Codes quan trọng
2xx — Thành công
200 OK
201 Created
204 No Content
3xx — Chuyển hướng
301 Moved Permanently
302 Found (temporary redirect)
304 Not Modified (cached)
4xx — Lỗi phía Client
400 Bad Request
401 Unauthorized (chưa xác thực)
403 Forbidden (đã xác thực nhưng không có quyền)
404 Not Found
429 Too Many Requests (rate limiting)
5xx — Lỗi phía Server
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
Security note: Sự khác nhau giữa 401 và 403 rất quan trọng:
401→ chưa đăng nhập, cần xác thực403→ đã đăng nhập nhưng không có quyền
Nhiều app sai: trả 404 thay vì 403 để ẩn sự tồn tại của resource — đây là security through obscurity, không phải biện pháp bảo mật thực sự.
HTTP Headers quan trọng về Security
Request Headers
Authorization:
Authorization: Bearer <jwt-token>
Authorization: Basic <base64(user:pass)>
Tấn công: steal token, weak token, token không expire.
Cookie:
Cookie: session=abc123; csrf_token=xyz
Tấn công: session hijacking, CSRF.
Host:
Host: example.com
Tấn công: Host header injection — attacker thay đổi Host để poison cache hoặc reset password link.
X-Forwarded-For:
X-Forwarded-For: 1.2.3.4
Dùng để xác định IP thực của client qua proxy/load balancer. Tấn công: IP spoofing nếu app tin tưởng header này mù quáng.
Content-Type:
Content-Type: application/json
Content-Type: multipart/form-data; boundary=----
Content-Type: text/xml
Tấn công: content-type confusion — gửi XML khi app expect JSON để trigger XXE.
Response Headers (Security Headers)
Content-Security-Policy (CSP):
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; object-src 'none'
Kiểm soát browser chỉ load resources từ nguồn được phép. Phòng chống XSS hiệu quả nhất.
X-Frame-Options:
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
Ngăn trang bị nhúng vào iframe. Phòng chống Clickjacking.
Strict-Transport-Security (HSTS):
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Bắt buộc browser dùng HTTPS trong tương lai. Phòng chống SSL stripping.
X-Content-Type-Options:
X-Content-Type-Options: nosniff
Ngăn browser "đoán" content-type. Phòng chống MIME sniffing attacks.
Referrer-Policy:
Referrer-Policy: strict-origin-when-cross-origin
Kiểm soát thông tin Referer gửi khi navigate. Ngăn leak thông tin nhạy cảm trong URL.
Permissions-Policy:
Permissions-Policy: camera=(), microphone=(), geolocation=()
Kiểm soát quyền truy cập browser APIs. Phòng chống abuse camera/mic/GPS.
Cookies — Chi tiết
Cookie là cơ chế chính để duy trì session. Hiểu cookie attributes là bắt buộc:
Set-Cookie: session=abc123;
Path=/;
Domain=example.com;
Expires=Wed, 09 Jun 2024 10:18:14 GMT;
HttpOnly;
Secure;
SameSite=Strict
Giải th ích từng attribute:
| Attribute | Ý nghĩa | Nếu thiếu |
|---|---|---|
HttpOnly | JS không đọc được cookie | XSS có thể đánh cắp cookie |
Secure | Chỉ gửi qua HTTPS | Dễ bị sniff qua HTTP |
SameSite=Strict | Không gửi trong cross-site request | CSRF attack dễ hơn |
SameSite=Lax | Gửi khi navigate, không khi fetch | Cân bằng UX và security |
SameSite=None | Luôn gửi (cần Secure) | CSRF attack dễ hơn |
Domain | Cookie áp dụng cho domain nào | Mặc định: chỉ domain hiện tại |
Path | Cookie áp dụng cho path nào | Mặc định: path hiện tại |
Expires/Max-Age | Thời gian sống của cookie | Session cookie (xóa khi đóng tab) |
HTTPS và TLS
TLS (Transport Layer Security — Bảo mật Tầng Truyền tải) mã hóa traffic giữa client và server. HTTPS = HTTP + TLS.
TLS Handshake đơn giản:
Client Server
│──── ClientHello ───────────►│ (TLS version, cipher suites)
│◄─── ServerHello ────────────│ (chọn cipher suite)
│◄─── Certificate ────────────│ (server certificate)
│──── Key Exchange ──────────►│
│◄─── Finished ───────────────│
│──── Finished ──────────────►│
│════ Encrypted Data ══════════│
Các vấn đề TLS thường gặp:
- Expired certificate: App down hoặc user bypass warning
- Self-signed certificate: Dễ bị MITM attack
- Weak cipher suites: SSL 3.0, TLS 1.0 đã bị deprecate
- Certificate pinning bypass: Mobile app security issue
- Mixed content: HTTPS page load HTTP resource — dễ bị tấn công
Kiểm tra TLS config:
# Dùng testssl.sh
./testssl.sh https://example.com
# Hoặc online: ssllabs.com/ssltest/
HTTP/2 và HTTP/3
HTTP/2 (2015):
- Multiplexing: nhiều request trên 1 connection
- Header compression (HPACK)
- Server push
- Binary protocol thay vì text
HTTP/3 (2022):
- Dùng QUIC (UDP-based) thay vì TCP
- Giảm latency đáng kể
- Built-in encryption (TLS 1.3)
Security implications:
- HTTP/2 Request Smuggling có cách exploit khác HTTP/1.1
- HTTP/3 QUIC có attack surface mới
- Nhiều WAF chưa handle HTTP/3 đúng cách
URL Structure
https://user:pass@example.com:8443/api/v2/users?id=123&role=admin#section
│─────│ │───────│ │──────────│ │──│ │──────────│ │──────────────│ │─────│
scheme credentials hostname port path query fragment
Security issues với URL:
- Credentials trong URL bị log trong server access log, browser history, Referer header
- Query parameters thường bị log — không để sensitive data trong URL
- Fragment (
#) không gửi lên server, nhưng JavaScript có thể đọc
HTTP trong DevOps context
Nginx security headers
server {
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'" always;
add_header Permissions-Policy "camera=(), microphone=()" always;
# Ẩn Nginx version
server_tokens off;
}
Traefik (Kubernetes Ingress)
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: security-headers
spec:
headers:
stsSeconds: 31536000
stsIncludeSubdomains: true
frameDeny: true
contentTypeNosniff: true
referrerPolicy: "strict-origin-when-cross-origin"
customResponseHeaders:
X-Robots-Tag: "noindex, nofollow"
Server: "" # Ẩn server info
Logging HTTP traffic đúng cách
# Không log password trong URL
log_format security '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time';
# Mask sensitive headers trong access log
Ví dụ thực tế: Đọc HTTP traffic
Khi dùng Burp Suite hoặc Wireshark, bạn sẽ thấy traffic như sau:
GET /api/users/profile?userId=1337 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEzMzcsInJvbGUiOiJ1c2VyIn0.abc123
Cookie: _ga=GA1.2.123; _session=xyz
User-Agent: Mozilla/5.0 (X11; Linux x86_64)
Nhìn vào request này, một hacker sẽ chú ý:
userId=1337trong query parameter — thử thay thànhuserId=1để xem có IDOR không- JWT token trong Authorization — decode ra để xem payload
- Không có
X-CSRF-Token— có thể dính CSRF
Kịch bản tấn công: Host Header Injection
POST /forgot-password HTTP/1.1
Host: attacker.com ← Hacker thay đổi header này
Content-Type: application/x-www-form-urlencoded
email=victim@example.com
Nếu server dùng Host header để tạo link reset password:
Click here to reset: https://attacker.com/reset?token=abc123
Victim nhận email, click link, token bị hacker capture.
Phòng chống:
# Sai: dùng Host header từ request
reset_url = f"https://{request.headers['Host']}/reset?token={token}"
# Đúng: hardcode domain trong config
reset_url = f"https://{settings.BASE_URL}/reset?token={token}"
Tóm tắt
- HTTP là text-based, request-response, stateless.
- Mọi cuộc tấn công web đều đi qua HTTP — hiểu cấu trúc là bắt buộc.
- Security headers (CSP, HSTS, X-Frame-Options) là hàng rào đầu tiên — dễ implement, hiệu quả cao.
- Cookie attributes (HttpOnly, Secure, SameSite) bảo vệ session — thiếu một cái là lỗ hổng.
- Không bao giờ để sensitive data trong URL query parameters.
- Host header không đáng tin — luôn hardcode domain trong config.
- TLS mạnh: TLS 1.2+, không dùng weak cipher suites.
Câu hỏi ôn tập
- Sự khác nhau giữa HTTP 401 và 403 là gì? Tại sao điều này quan trọng về mặt security?
- Cookie attribute nào quan trọng nhất để phòng chống XSS? Tại sao?
- HSTS là gì và nó ngăn chặn loại tấn công nào?
- Tại sao không nên đặt sensitive data trong URL query string?
- Content-Security-Policy header hoạt động như thế nào để ngăn chặn XSS?