Top 20 Web Vulnerabilities
Thuật ngữ
Ý nghĩa
OWASP
Tổ chức phi lợi nhuận chuyên xếp hạng các lỗ hổng web nguy hiểm nhất thế giới. Giống “Bảng xếp hạng Billboard” nhưng dành cho lỗi bảo mật.
CVE (Common Vulnerabilities and Exposures)
Mã số định danh quốc tế cho mỗi lỗi bảo mật đã được công bố (VD: CVE-2021-44228 = lỗi Log4Shell). Giống “biển số xe” của lỗ hổng.
CWE (Common Weakness Enumeration)
Phân loại chủng loại lỗ hổng (VD: CWE-89 = SQL Injection). Nếu CVE là “biển số xe”, thì CWE là “loại xe” (sedan, SUV...).
CVSS (Common Vulnerability Scoring System)
Thang điểm đánh giá mức độ nguy hiểm từ 0.0 (vô hại) đến 10.0 (thảm họa).
RCE (Remote Code Execution)
Hacker chạy được lệnh trên máy chủ của bạn từ xa — tương đương với việc kẻ trộm nắm toàn bộ chìa khóa nhà bạn. Đây là mức độ nghiêm trọng nhất.
ATO (Account Takeover)
Chiếm đoạt tài khoản người dùng — hacker đăng nhập được vào tài khoản của bạn.
Session / Session ID
“Thẻ ra vào” tạm thời mà website cấp cho bạn sau khi đăng nhập. Ai có thẻ này đều được website coi là “chủ nhân”.
Cookie
File nhỏ mà website lưu trên trình duyệt của bạn. Thường chứa Session ID (thẻ ra vào).
Token
Chuỗi ký tự ngẫu nhiên đại diện cho quyền truy cập. Giống mã OTP hay vé xem phim — chỉ dùng 1 lần hoặc có thời hạn.
Payload
“Viên đạn” — đoạn mã độc mà hacker gửi vào hệ thống để khai thác lỗ hổng.
WAF (Web Application Firewall)
Tường lửa chuyên bảo vệ ứng dụng web. Giống “bảo vệ cổng” kiểm tra mọi người ra vào.
SIEM (Security Information and Event Management)
Hệ thống giám sát an ninh tập trung — giống “phòng điều khiển camera” của toàn bộ hạ tầng.
Brute Force
Thử mật khẩu bằng cách thử hết tất cả tổ hợp có thể — giống thử từng chìa khóa trong bó 10.000 chìa.
Hash / Hashing
Thuật toán biến mật khẩu thành chuỗi ký tự lộn xộn không thể đảo ngược. VD: password123 -> ef92b778.... Dùng để lưu mật khẩu an toàn.
Salt
Chuỗi ngẫu nhiên trộn vào mật khẩu trước khi hash , để 2 người cùng đặt pass 123456 sẽ cho ra 2 hash khác nhau.
Parameterized Query
Cách viết truy vấn Database an toàn: tách biệt hoàn toàn “câu lệnh” và “dữ liệu người dùng nhập”. Giống việc in sẵn form có ô trống — người điền không thể sửa nội dung form.
Bypass
Kỹ thuật lách luật, vượt qua hàng rào bảo mật.
Bug Bounty
Chương trình treo thưởng tiền mặt cho ai tìm được lỗ hổng bảo mật. HackerOne, Bugcrowd là 2 nền tảng lớn nhất.
Pentesting / Penetration Testing
Kiểm thử xâm nhập — thuê hacker mũ trắng tấn công thử hệ thống của bạn để tìm lỗ hổng trước khi kẻ xấu làm.
PoC (Proof of Concept)
Bằng chứng chứng minh lỗ hổng tồn tại thật, thường là một đoạn mã/video demo khai thác thành công.
1. Injection (CWE-89, CWE-78)
Các bước khai thác:
Kẻ tấn công gửi input chứa ký tự đặc biệt lách luật (ví dụ: ' OR 1=1 --).
Web Server lấy thẳng input này ghép vào câu lệnh SQL mà không kiểm tra.
Database bắt buộc thực thi câu lệnh đã bị bóp méo (1=1 luôn đúng).
Dữ liệu nhạy cảm toàn bộ bảng bị trả về do sai lệch logic.
Không sử dụng Parameterized Queries .
Nối chuỗi trực tiếp dữ liệu người dùng vào câu lệnh SQL, lệnh hệ điều hành, v.v.
Thiếu Input Validation chặt chẽ phía server.
1.2 Phân loại và Khai thác
Injection rất đa dạng, phổ biến nhất là SQL Injection (SQLi) và OS Command Injection .
Kỹ thuật SQLi
Giải thích giản lược
Union-based
Dùng toán tử UNION gộp kết quả bảng khác (ví dụ: gộp bảng password vào danh sách sản phẩm).
Boolean-based / Blind
Hỏi database các câu hỏi Đúng/Sai để mò từng chữ cái của mật khẩu.
Time-based Blind
Bắt database SLEEP(10). Nếu phản hồi chậm 10 giây, thao tác inject đã thành công.
1.3 Rủi ro & Case Study thực tế
Mức độ: CRITICAL (9.0 - 10.0 CVSS).
Có thể dẫn đến chiếm đoạt toàn bộ cơ sở dữ liệu hoặc thực thi lệnh hệ điều hành (RCE ).
Hậu quả toàn diện:
Đọc / Sửa / Xóa toàn bộ Database.
Leo quyền từ User thường lên Admin.
Chạy lệnh hệ điều hành từ xa (RCE), đọc file cấu hình, tạo backdoor.
Case Study / Bug Bounty:
Equifax (2017): Apache Struts2 CVE-2017-5638 — OGNL Expression Injection dẫn tới RCE.
HackerOne Report (Uber): SQL Injection trong UUID parameter, bypass filter và đọc được email/số điện thoại.
Sony Pictures (2011): SQLi đơn giản làm lộ 1 triệu tài khoản do lưu mật khẩu dạng plaintext.
Quy tắc vàng: Không bao giờ nối chuỗi tạo truy vấn. Sử dụng Parameterized Queries .
Ngôn ngữ
Code lỗi (nối chuỗi)
Code an toàn (Parameterized)
Python
cursor.execute("SELECT * FROM users WHERE id=" + id)
cursor.execute("SELECT * FROM users WHERE id=?", (id,))
PHP
$db->query("SELECT * WHERE name='".$_GET['n']."'");
$stmt=$db->prepare("SELECT * WHERE name=?"); $stmt->execute([$_GET['n']]);
Java
stmt.executeQuery("SELECT * WHERE id=" + id);
PreparedStatement ps = conn.prepareStatement("SELECT * WHERE id=?"); ps.setInt(1, id);
Node.js
db.query(`SELECT * WHERE id=${id}`)
db.query("SELECT * WHERE id=$1", [id])
Biện pháp bổ sung:
Dùng ORM: Django ORM, SQLAlchemy, Eloquent, Sequelize.
Input Validation: ép kiểu dữ liệu đầu vào nghiêm ngặt.
Least Privilege: tài khoản DB chỉ nên có quyền tối thiểu.
WAF: dùng ModSecurity hoặc Cloudflare WAF làm lớp bổ sung.
Công cụ
Manual Testing
SQLMap, Burp Suite Active Scan, ZAP
Thử chèn dấu ', ", hoặc ; sleep 10; vào tất cả tham số (URL, Body, Header).
2. Broken Authentication (CWE-287)
Workflow: Credential Stuffing / Brute Force
Kẻ tấn công dùng công cụ tự động thử hàng ngàn cặp email/mật khẩu lộ từ vụ rò rỉ khác.
Web App nhận và kiểm tra từng cặp tài khoản.
Hầu hết thất bại, nhưng vô tình trúng cặp nạn nhân xài chung mật khẩu.
Web App xác nhận thành công, cấp Session Token, tài khoản bị chiếm đoạt.
Không giới hạn số lần thử đăng nhập (Rate Limiting ).
Cho phép đặt mật khẩu quá đơn giản.
Quản lý Session ID kém.
Thiếu MFA.
2.2 Phân loại và Khai thác
Kỹ thuật
Mô tả
Brute Force
Thử hàng triệu tổ hợp mật khẩu.
Credential Stuffing
Dùng mật khẩu lộ từ web A để thử đăng nhập web B.
Session Hijacking
Ăn cắp Session ID để dùng ké phiên đăng nhập.
2.3 Rủi ro & Case Study thực tế
Mức độ: CRITICAL.
Dẫn tới Account Takeover (ATO) .
Hậu quả toàn diện:
Chiếm đoạt tài khoản quản trị.
Rò rỉ dữ liệu cá nhân hàng loạt.
Dùng tài khoản bị chiếm để phát tán mã độc / lừa đảo.
Case Study:
Starbucks: Bypass Rate Limit bằng xoay vòng IP và chèn khoảng trắng vào email.
Dropbox (2012): 68 triệu tài khoản bị lộ do tái sử dụng mật khẩu.
a) Hash mật khẩu đúng cách
Ngôn ngữ
Code hash an toàn
Python
from bcrypt import hashpw, gensalthashed = hashpw(password.encode(), gensalt(rounds=12))
PHP
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
Node.js
const hash = await bcrypt.hash(password, 12);
Nginx: limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
Dùng thư viện như express-rate-limit, django-ratelimit, throttle.
Khóa tài khoản tạm 15–30 phút sau 5 lần sai liên tiếp.
c) Quản lý Session an toàn
Session ID dùng CSPRNG, tối thiểu 128-bit.
Cookie: HttpOnly=true; Secure=true; SameSite=Lax; Max-Age=3600.
Regenerate Session ID sau khi đăng nhập thành công.
Dùng TOTP hoặc WebAuthn/FIDO2, đặc biệt với tài khoản admin.
Công cụ
Manual Testing
Hydra, Burp Suite Intruder
Bắt request đăng nhập, lặp lại nhiều lần xem máy chủ có trả HTTP 429 Too Many Requests hay không.
3. Sensitive Data Exposure / Cryptographic Failures (CWE-311, CWE-327)
Workflow: Man-In-The-Middle do thiếu HTTPS
Người dùng kết nối Wi‑Fi công cộng.
Truy cập web HTTP không mã hóa và gửi thông tin đăng nhập.
Hacker dùng Wireshark bắt gói tin.
Mật khẩu lộ hoàn toàn dưới dạng plaintext.
Giao tiếp qua HTTP thay vì HTTPS.
Lưu dữ liệu nhạy cảm không mã hóa trong database.
Dùng thuật toán lỗi thời như MD5, SHA1.
Hardcode API keys, DB password trong mã nguồn.
3.2 Phân loại và Khai thác
Data in Transit : thiếu TLS/SSL, bị sniffing.
Data at Rest : database bị dump, hash yếu dễ crack.
3.3 Rủi ro & Case Study thực tế
Mức độ: HIGH tới CRITICAL.
Có thể bị phạt nặng theo quy định như GDPR, HIPAA.
Case Study:
Twitch (2021): lộ mã nguồn và API key do cấu hình kho lưu trữ sai.
Rất nhiều report lộ API Key AWS/Google Maps trên GitHub nhận bounty từ $500 - $5,000.
a) Mã hóa dữ liệu truyền tải
Bắt buộc HTTPS (TLS 1.2+, khuyến nghị TLS 1.3).
HSTS:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
Tự động chuyển hướng HTTP → HTTPS.
Hash mật khẩu bằng Bcrypt/Argon2.
Mã hóa dữ liệu nhạy cảm bằng AES-256-GCM.
Không dùng MD5, SHA1 cho mật khẩu.
Lưu vào .env hoặc Secret Manager.
Thêm .env vào .gitignore.
Dùng TruffleHog, git-secrets để chặn commit lộ key.
Rotate key định kỳ.
Công cụ
Manual Testing
TruffleHog, GitLeaks, TestSSL.sh
View Source để tìm API keys. Kiểm tra chứng chỉ SSL/TLS bằng SSL Labs.
4. XXE - XML External Entity (CWE-611)
Kẻ tấn công gửi XML chứa thực thể ngoại lai, ví dụ: SYSTEM "file:///etc/passwd".
XML Parser phân tích cú pháp và thực thi lệnh đọc tài nguyên ngoài.
Máy chủ mở file bí mật của hệ điều hành.
Response XML trả lại nội dung file nhạy cảm.
XML Parser để mặc định, không vô hiệu hóa External Entities và DTD .
4.2 Phân loại và Khai thác
In-band XXE : nội dung file được trả thẳng trong response.
Blind / OOB XXE : server tạo request ra ngoài kèm dữ liệu đọc được.
Billion Laughs Attack : entity lồng nhau gây DoS.
4.3 Rủi ro & Case Study thực tế
Mức độ: HIGH tới CRITICAL.
Có thể rò rỉ file mã nguồn, file mật khẩu hệ thống, SSRF nội bộ.
Case Study:
Google: upload CV định dạng SVG dính XXE, đính kèm file:///etc/hostname, bounty $10,000.
Ngôn ngữ
Cấu hình vô hiệu hóa XXE
Java
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
PHP
libxml_disable_entity_loader(true); (PHP < 8.0). PHP 8.0+ đã tắt mặc định.
Python
Dùng defusedxml thay vì xml.etree.
.NET
settings.DtdProcessing = DtdProcessing.Prohibit;
Nếu không cần XML, chuyển sang JSON.
Với SVG/DOCX/XLSX, parse bằng thư viện chuyên dụng.
Công cụ
Manual Testing
Burp Suite Active Scan
Tìm mọi request XML, chèn payload XXE cơ bản xem response có báo lỗi hoặc trả file không.
5. Broken Access Control (CWE-284)
Workflow: IDOR Attack
Kẻ tấn công đăng nhập tài khoản quyền thấp (User ID=10).
Nhận ra link hóa đơn có biến ?id=10.
Tự sửa thành ?id=11.
Server truy vấn DB nhưng không kiểm tra quyền sở hữu.
Trả về dữ liệu hóa đơn của người khác.
Backend không kiểm tra quyền sở hữu tài nguyên.
Phân quyền chỉ ở UI, không kiểm tra ở API.
5.2 Phân loại và Khai thác
Loại
Giải thích
IDOR
Sửa User_ID, Order_ID trên URL để truy xuất dữ liệu người khác.
Vertical Privilege Escalation
Leo quyền từ User → Admin.
Horizontal Privilege Escalation
User A truy cập dữ liệu của User B.
5.3 Rủi ro & Case Study thực tế
Mức độ: CRITICAL.
Là lỗ hổng đứng số 1 trong OWASP Top 10 (2021) .
Ngôn ngữ
Code kiểm tra quyền
Python (Django)
invoice = Invoice.objects.get(id=id)if invoice.owner != request.user: return HttpResponseForbidden()
PHP (Laravel)
$this->authorize('view', $invoice);
Node.js
if (invoice.userId !== req.user.id) return res.status(403).json({error: 'Forbidden'});
Django: @permission_required('admin')
Express.js: requireRole('admin')
Laravel: middleware role
Dùng UUID v4 thay vì ID tăng dần.
Mặc định chặn tất cả, chỉ mở quyền khi cần.
Công cụ
Manual Testing
AuthMatrix, Autorize
Dùng 2 tài khoản khác nhau, lấy API người A sang người B xem có truy cập được không.
6. Security Misconfiguration (CWE-16)
Kẻ tấn công quét Internet tìm cổng mặc định 8080.
Bắt gặp Tomcat chưa đổi cấu hình mặc định.
Đăng nhập /manager/html bằng tomcat/tomcat.
Upload webshell dạng WAR.
Chiếm toàn quyền hệ thống.
Để nguyên mật khẩu mặc định.
Bật debug mode ở production.
Không cập nhật OS/framework/DB.
Bật directory listing.
6.2 Phân loại và Khai thác
Loại lỗi cấu hình
Mô tả & Khai thác
Debug Mode On
Lộ DB password, API keys, đường dẫn hệ thống.
Default Accounts
Đăng nhập bằng admin/admin.
Directory Listing
Thấy toàn bộ danh sách file nhạy cảm như .git, .env.
6.3 Rủi ro & Case Study thực tế
Mức độ: HIGH tới CRITICAL.
Nếu lộ file .env hoặc cho phép upload file, hậu quả có thể là RCE .
Framework
Cấu hình Production
Laravel
.env: APP_DEBUG=false, APP_ENV=production
Django
DEBUG = False, ALLOWED_HOSTS = ['yourdomain.com']
Express.js
NODE_ENV=production
Spring Boot
server.error.include-stacktrace=never
Nginx: autoindex off;
Apache: Options -Indexes
Nginx: location ~ /\.(env|git|htaccess|svn) { deny all; return 404; }
d) Security Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Dùng CSP thay cho X-XSS-Protection
Công cụ
Manual Testing
Nikto, Nessus, Nmap, DirBuster
Thử /admin, /.env, /.git, hoặc cố tình nhập sai URL để xem thông báo lỗi có lộ cấu hình không.
7. XSS - Cross-Site Scripting (CWE-79)
Kẻ tấn công chèn <script>...</script> vào phần bình luận.
Máy chủ lưu thẳng vào database.
Nạn nhân mở bài viết.
Trình duyệt chạy script độc.
Cookie / session bị gửi về máy của hacker.
Render dữ liệu người dùng lên trình duyệt mà không encode / escape.
7.2 Phân loại và Khai thác
Loại XSS
Mô tả
Mức độ
Stored XSS
Payload lưu vĩnh viễn trong DB.
Cao nhất
Reflected XSS
Payload nằm trong URL, cần lừa nạn nhân click.
Cao
DOM-based XSS
Payload chèn trực tiếp vào DOM bằng JS.
Trung bình
Blind XSS
Payload nổ trên giao diện admin.
Cao nhất
Polyglot XSS
Payload đa hình, bypass nhiều ngữ cảnh.
Biến thiên
7.3 Rủi ro & Case Study thực tế
Mức độ: HIGH đến CRITICAL.
Không chỉ ăn cắp cookie mà còn có thể:
chiếm tài khoản,
giả mạo form đăng nhập,
keylogger,
tự lan truyền như sâu mạng,
leo thang thành RCE trên Electron apps.
Case Study:
Samy Worm trên MySpace (2005)
Twitter onmouseover Worm (2010)
Discord RCE (2020)
Framework
Cách tự động chống XSS
React
Tự escape biến trong JSX. Nguy hiểm: dangerouslySetInnerHTML.
Angular
Tự sanitize. Nguy hiểm: [innerHTML], bypassSecurityTrust*.
Laravel Blade
Dùng {{ $var }}. Nguy hiểm: {!! $var !!}.
Django
Template tự escape.
PHP thuần
htmlspecialchars($input, ENT_QUOTES, 'UTF-8')
b) CSP Header
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; object-src 'none'
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax
nodeIntegration: false
contextIsolation: true
Công cụ
Manual Testing
Dalfox, XSStrike, XSS Hunter, ZAP
Thử <, >, dấu nháy, hoặc <script>prompt(1)</script> xem có popup hay vỡ layout không.
8. Insecure Components / Known Vulnerabilities (CWE-1035)
Hacker xác định mục tiêu đang chạy thư viện lỗi thời.
Gửi payload đặc biệt, ví dụ ${jndi:ldap...} vào log.
Log4j tải nội dung từ server của hacker.
Mã độc được thực thi trên máy chủ (RCE).
Không cập nhật dependency.
Bỏ qua cảnh báo như GitHub Dependabot.
8.2 Phân loại và Khai thác
Đối tượng
Cách hacker đánh
Framework Modules
RCE chỉ qua một request đặc biệt.
Server/OS
Buffer overflow hoặc lỗi hệ thống cũ.
Frontend Libraries
DOM-based XSS hoặc xử lý DOM không an toàn.
8.3 Rủi ro & Case Study thực tế
Mức độ: từ vừa tới cực kỳ nghiêm trọng.
Log4Shell có CVSS 10.0 .
Hệ sinh thái
Lệnh quét
Node.js
npm audit, npm audit fix --force
Python
pip-audit, safety check
Java
mvn dependency-check:check
PHP
composer audit
Biện pháp bổ sung:
Dùng Snyk, Dependabot, Renovate.
Commit lock file.
Quét SCA định kỳ.
Công cụ
Manual Testing
Snyk, OWASP Dependency Check, Wappalyzer
Kiểm tra version công nghệ và plugin CMS có lỗi công khai hay không.
9. Insufficient Logging & Monitoring (CWE-778)
Hacker brute force rất chậm qua nhiều IP khác nhau.
Máy chủ không lưu log hoặc không alert.
Hacker vào được hệ thống và lấy DB.
Log cũ bị xóa hoặc không đủ dữ liệu để truy vết.
Log thiếu IP, timestamp, user ID.
Log lưu ngay trên server bị hack.
Có log nhưng không cảnh báo.
Đây thường là lỗ hổng “hỗ trợ” cho các lỗ hổng khác.
Doanh nghiệp có thể mất hàng trăm ngày mới phát hiện bị xâm nhập.
Structured logging: Timestamp, IP, User ID, Action, Result, Request ID.
Gửi log ra SIEM riêng: ELK, Splunk, Graylog, Wazuh.
Alert khi có hành vi bất thường.
Giữ log tối thiểu 90 ngày.
Không log dữ liệu nhạy cảm.
Công cụ
Manual Testing
Red Teaming / SOC Audit
Tạo payload tấn công kiểm tra xem đội vận hành có phát hiện và phản ứng hay không.
10. CSRF - Cross-Site Request Forgery (CWE-352)
Nạn nhân đang đăng nhập ở bank.com.
Mở web độc có form ẩn tự động gửi POST /transfer.
Trình duyệt tự kèm cookie của bank.com.
Ngân hàng tưởng request hợp lệ và thực hiện giao dịch.
Không có CSRF Token .
Cookie tự động được gửi theo request cross-site.
Không kiểm tra Origin / Referer.
10.2 Phân loại và Khai thác
Loại
Cách khai thác
Simple Form POST
Form ẩn tự submit.
GET Request Image
Dùng <img src="http://bank/change-pass?new=123" />.
Đổi email / mật khẩu.
Chuyển tiền, mua hàng trái phép.
Tạo admin mới.
Xóa dữ liệu.
Framework
Cách thêm CSRF Token
Laravel
@csrf trong form Blade
Django
{% csrf_token %} + CsrfViewMiddleware
Express.js
csurf
Spring
dùng _csrf.token mặc định
Set-Cookie: session=abc; SameSite=Lax; Secure; HttpOnly
c) Kiểm tra Origin/Referer
So sánh với domain hợp lệ trước khi xử lý.
Công cụ
Manual Testing
Burp Suite Pro, ZAP
Thu request đổi email, xóa CSRF token xem server có vẫn chấp nhận hay không.
11. Open Redirect (CWE-601)
Hacker tạo link dạng bank.com/login?redirect=https://evil.com.
Nạn nhân thấy domain đầu là bank.com nên tin tưởng.
Website chuyển nạn nhân sang evil.com.
Trang giả mạo hiện ra và thu thập mật khẩu.
App lấy URL đích từ tham số GET như next=, redirect_to= và redirect thẳng.
Dùng kiểm tra chuỗi đơn giản như .startsWith().
Kỹ thuật
Ví dụ
Dấu @
https://bank.com?ret=https://bank.com@evil.com
//evil.com
Trình duyệt tự hiểu là URL tuyệt đối
Không truyền URL đích trực tiếp, dùng mã định danh nội bộ.
Nếu bắt buộc dùng URL, parse bằng thư viện chuẩn và kiểm tra whitelist domain.
Ngôn ngữ
Code kiểm tra an toàn
Python
urlparse(redirect_url) rồi kiểm tra parsed.netloc
PHP
parse_url($url, PHP_URL_HOST)
Node.js
new URL(redirectUrl).hostname
Công cụ
Manual Testing
Burp Suite, kiểm tra thủ công
Đổi next= thành http://google.com xem có bị redirect hay không.
12. SSRF - Server-Side Request Forgery (CWE-918)
Lợi dụng tính năng “tải ảnh từ URL”.
Truyền URL tới 169.254.169.254 (AWS metadata).
Web server đứng trong mạng nội bộ nên gọi được.
Metadata và key bị lộ ra ngoài response lỗi.
Ứng dụng cho fetch URL nhưng không chặn IP nội bộ.
Không có outbound firewall.
12.2 Phân loại và Khai thác
Kỹ thuật
Cách thức
Basic SSRF
Kết quả trả thẳng ra màn hình.
Blind SSRF
Không có output, dùng Burp Collaborator hoặc time delay để dò.
DNS Rebinding
Qua mặt kiểm tra IP bằng DNS đổi IP sau khi kiểm tra.
Bypass URL Scheme
Dùng hex/octal/decimal để biểu diễn IP nội bộ.
Lấy IAM Credentials.
Quét cổng nội bộ.
Truy cập dịch vụ Docker/Redis/MongoDB.
DoS nội bộ.
Chặn IP private/loopback và 169.254.169.254.
Chặn scheme nguy hiểm như file://, gopher://, dict://.
Resolve DNS trước khi fetch và kiểm tra IP đích.
Dùng firewall chặn outbound tới mạng nội bộ.
Bật AWS IMDSv2.
Công cụ
Manual Testing
SSRFMap, Burp Collaborator
Dùng chức năng import/download bằng link, thử http://localhost:22 hoặc collaborator URL.
13. SSTI - Server-Side Template Injection (CWE-1336)
Hacker nhập payload như {{ 7*7 }}.
Template engine thực thi và in ra 49.
Hacker tiếp tục khai thác chain để gọi lệnh hệ điều hành.
RCE thành công.
Dùng hàm như render_template_string(user_input) thay vì truyền dữ liệu qua context.
13.2 Phân loại và Khai thác
Ngôn ngữ / Framework
Payload thử nghiệm
Python / Jinja2
{{ 7*7 }}
Java / Freemarker
${7*7}
Ruby / ERB
<%= 7*7 %>
Mức độ: cực kỳ CRITICAL.
Có thể dẫn tới RCE toàn bộ máy chủ.
Framework
Code lỗi
Code an toàn
Flask/Jinja2
render_template_string(user_input)
render_template('page.html', name=user_input)
PHP/Twig
$twig->createTemplate($userInput)->render()
$twig->render('page.html', ['name' => $userInput])
User input chỉ được truyền như dữ liệu, không bao giờ như mã template.
Bật sandbox nếu cần cho phép custom template.
Ưu tiên logic-less templates như Mustache, Handlebars.
Công cụ
Manual Testing
Tplmap
Thử nhập {{ 4*4 }} hoặc [[ 5*5 ]] xem hệ thống có tính ra kết quả không.
14. Directory Traversal (CWE-22)
Web có chức năng đọc file qua ?file=avatar.jpg.
Hacker đổi thành ../../../../../../etc/passwd.
API ghép đường dẫn mà không sanitize.
Nội dung file hệ thống bị trả ra giao diện.
Ghép tên file từ user input với thư mục gốc mà không xử lý ../.
Kỹ thuật
Giải thích
URL Encoding
%2e%2e%2f
Double Encoding
%252e%252e%252f
Bypass xóa 1 lần
....//
Ngôn ngữ
Code chống Traversal
Python
safe_path = os.path.realpath(os.path.join(BASE_DIR, filename)) rồi kiểm tra startswith(BASE_DIR)
PHP
realpath(...) + basename()
Java
Paths.get(baseDir, fileName).normalize()
Dùng UUID cho tên file.
Không cho truy cập trực tiếp thư mục upload.
Công cụ
Manual Testing
DotDotPwn, Burp Intruder
Nhét wordlist traversal vào tham số file/download, xem có trả về root:x:0:0 không.
15. File Inclusion / LFI / RFI (CWE-98)
PHP include nội dung theo ?page=.
Hacker truyền php://filter/read=convert.base64-encode/resource=index.php.
PHP trả về source code đã base64 thay vì thực thi.
Hacker decode và lấy thông tin cấu hình nhạy cảm.
Dùng include() / require() với input từ user.
Bật allow_url_include=On.
15.2 Phân loại và Khai thác
Wrapper / Kỹ thuật
Mục đích
php://filter
Đọc source code dưới dạng text/base64
data://text/plain
Thực thi payload trực tiếp
php://input
Đọc dữ liệu từ request body
Log Poisoning
Ghim PHP vào log rồi include log để RCE
/proc/self/environ
Ghim payload vào User-Agent rồi include file môi trường
Session Poisoning
Tiêm payload vào session file rồi include
%00
Null byte bypass trên PHP cũ
LFI có thể leo thang thành RCE rất dễ.
<?php
$ allowed = ['home ' , 'about ' , 'contact ' ];
$ page = $ _GET ['page ' ] ?? 'home ' ;
if (in_array ($ page , $ allowed )) {
include ($ page . '.php ' );
} else {
include ('home.php ' );
}
?>
php.ini:
allow_url_include = Off
allow_url_fopen = Off
open_basedir = /var/www/html
Công cụ
Manual Testing
LFISuite, Burp Intruder
Thử page=, file=, view= với wrapper base64 xem có lộ source code không.
16. Insecure / Unrestricted File Upload (CWE-434)
Hacker tạo file như shell.php.jpg.
Hệ thống chỉ kiểm tra sơ sài đuôi file.
File được lưu trong thư mục có thể thực thi.
Truy cập URL của file là kích hoạt webshell.
Chỉ kiểm tra file ở client-side.
Lưu file trong webroot.
Không tắt thực thi code tại thư mục upload.
Kỹ thuật
Ý nghĩa
Thay Content-Type
Sửa thành image/jpeg dù file là PHP shell
Chèn đuôi
shell.php.jpg, .phtml, .php5
Ghép magic byte
Chèn GIF89a để giả làm ảnh
Mức độ: CRITICAL.
Có thể dẫn tới Full Server Compromise .
Lớp kiểm tra
Cách làm
Extension Whitelist
Chỉ cho .jpg, .png, .gif, .pdf
MIME Type Check
Kiểm tra Content-Type và magic bytes
Đổi tên file
Dùng UUID
Giới hạn kích thước
client_max_body_size 5M;
Biện pháp bổ sung:
Lưu file ngoài webroot.
Dùng S3/GCS với pre-signed URL.
Chặn thực thi .php trong /uploads/.
Re-encode ảnh để loại bỏ payload ẩn.
Công cụ
Manual Testing
Phân tích WAF logs / kiểm tra thủ công
Upload thử .pHp, .aspX, .jsp xem server có cho truy cập như file thực thi không.
17. Clickjacking / UI Redressing (CWE-1021)
Hacker dựng một trang “nhận quà”.
Chèn iframe trong suốt chứa trang thật.
Canh vị trí để nút giả trùng với nút nguy hiểm thật.
Nạn nhân click và vô tình thực hiện hành động nguy hiểm.
Thiếu X-Frame-Options hoặc CSP frame-ancestors.
Cookie không có SameSite phù hợp.
17.2 Phân loại và Khai thác
Likejacking / Sharejacking
Mouse-chasing
Overlay bằng z-index, opacity: 0, position: absolute
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'
Có thể thêm JS frame-busting như lớp phụ.
Công cụ
Manual Testing
Clickjacking PoC Tool, Burp, F12
Tạo file HTML có iframe trỏ tới mục tiêu. Nếu web vẫn hiện trong iframe, có khả năng dính lỗi.
18. CORS Misconfiguration (CWE-942)
API phản chiếu Origin quá thoải mái.
Hacker dựng evil.com với JavaScript fetch().
Trình duyệt nạn nhân gửi request kèm cookie.
API trả dữ liệu và trình duyệt cho phép evil.com đọc.
Dùng Access-Control-Allow-Origin: * hoặc reflect mọi origin.
Kết hợp sai với Access-Control-Allow-Credentials: true.
18.2 Phân loại và Khai thác
Cấu hình sai
Tại sao nguy hiểm
Origin Reflection
Server chấp nhận mọi Origin, hacker dùng withCredentials=true để lấy dữ liệu người dùng.
Trusting Subdomains
Regex quá lỏng, tin cả domain giả giống thật.
Trusting null
Hacker dùng file local hoặc iframe sandbox để lợi dụng Origin: null.
Framework
Cấu hình an toàn
Express.js
cors({ origin: ['https://app.mysite.com'], credentials: true })
Flask
CORS(app, origins=['https://app.mysite.com'], supports_credentials=True)
Django
CORS_ALLOWED_ORIGINS = ['https://app.mysite.com']
Nginx
Chỉ trả header cho $http_origin thuộc whitelist
Quy tắc vàng:
Không dùng * với credentials: true.
Không reflect origin nếu chưa whitelist.
Không tin null origin.
Công cụ
Manual Testing
Burp Suite, CORScanner
Thêm Origin: http://evil.com vào request và xem response có nhại lại không.
19. Host Header Attack (CWE-644)
Chức năng quên mật khẩu dùng thẳng giá trị Host từ request.
Hacker đổi Host: evil.com.
Email reset gửi tới nạn nhân chứa link domain giả.
Nạn nhân click và token reset bị lộ cho hacker.
Tạo URL bằng $_SERVER['HTTP_HOST'] hoặc tương đương.
Reverse proxy không lọc host lạ.
19.2 Phân loại và Khai thác
Biến thể
Rủi ro
Password Reset Poisoning
Link reset trỏ về domain hacker
Web Cache Poisoning
Cache 301/302 độc hại, ảnh hưởng nhiều người dùng
SSRF / Admin Access
Dùng host như localhost để vào luồng nội bộ
Hardcode BASE_URL.
Dùng ALLOWED_HOSTS / host whitelist.
Tạo default server block trả 444 hoặc chặn host lạ.
Framework
Cấu hình đúng
Laravel
.env: APP_URL=https://mybank.com
Django
ALLOWED_HOSTS = ['mybank.com']
Node.js
BASE_URL=https://mybank.com
Công cụ
Manual Testing
Burp Repeater
Đổi Host: evil.com trong luồng quên mật khẩu, rồi kiểm tra email reset sinh ra link domain nào.
20. Insecure Deserialization (CWE-502)
Ứng dụng dùng cookie/session serialized.
Hacker tạo payload có gadget chain độc.
Thay payload vào cookie.
Khi app deserialize, mã độc chạy và dẫn tới RCE.
Dùng pickle, unserialize, ObjectInputStream với dữ liệu từ user.
Không ký HMAC để chống sửa đổi.
20.2 Phân loại và Khai thác
Kỹ thuật
Ứng dụng
PHP POP Chain
Lợi dụng __wakeup(), __destruct()
Java Commons Collections
Dùng gadget chain, công cụ Ysoserial
Python Pickle RCE
Lợi dụng __reduce__() gọi os.system
Mức độ: cực kỳ CRITICAL.
Có thể dẫn tới RCE, cài backdoor, ransomware, lateral movement.
a) Dùng JSON thay cho native serialization
Không dùng pickle.loads(), unserialize(), ObjectInputStream với dữ liệu user.
Dùng json.loads(), json_decode(), Jackson/Gson.
b) Ký HMAC nếu bắt buộc phải serialize
Ngôn ngữ
Code ký và verify
Python
hmac.new(SECRET_KEY, data, hashlib.sha256).hexdigest()
PHP
hash_hmac('sha256', $data, $secret)
c) Java Deserialization Filter
ObjectInputFilter filter = ObjectInputFilter .Config .createFilter ("!*" );
Loại bỏ Apache Commons Collections cũ khỏi classpath.
Công cụ
Manual Testing
YsoSerial, PHPGGC, Burp Scanner
Nhận diện cookie serialized (O:4:"User":2, rO0AB, H4sIA...) rồi dùng payload DNS/time delay để kiểm tra.
#
Lỗ hổng
Mức độ
Biện pháp phòng chống chính
CWE
1
Injection
Critical
Parameterized queries, Input validation
CWE-89
2
Broken Authentication
Critical
MFA, Rate limiting, bcrypt hash
CWE-287
3
Sensitive Data Exposure / Cryptographic Failures
High
HTTPS, AES-256, HSTS
CWE-311, CWE-327
4
XXE
High
Disable DTD/External entities
CWE-611
5
Broken Access Control
Critical
RBAC, Server-side authorization
CWE-284
6
Security Misconfiguration
Medium–High
Hardening, Security headers
CWE-16
7
XSS
High
Output encoding, CSP
CWE-79
8
Known Vulnerabilities / Insecure Components
Variable
Dependency scanning, Patching
CWE-1035
9
Insufficient Logging
Medium
Centralized logging, SIEM
CWE-778
10
CSRF
Medium
CSRF token, SameSite cookie
CWE-352
11
Open Redirect
Medium
URL whitelist, Relative paths only
CWE-601
12
SSRF
High–Critical
URL/IP validation, Network firewall
CWE-918
13
SSTI
Critical
Template file separation, Sandbox
CWE-1336
14
Directory Traversal
High
Path canonicalization, chroot
CWE-22
15
File Inclusion
Critical
Whitelist includes, Disable URL include
CWE-98
16
File Upload
Critical
MIME check, Rename, Store outside webroot
CWE-434
17
Clickjacking
Medium
X-Frame-Options, CSP frame-ancestors
CWE-1021
18
CORS Misconfiguration
High
Origin whitelist, No wildcard with credentials
CWE-942
19
Host Header Attack
Medium–High
Host whitelist, Hardcode URLs
CWE-644
20
Insecure Deserialization
Critical
JSON instead of native serialization, HMAC
CWE-502