Lập trình 22/09/2026 6 phút

XSS: khi dữ liệu người dùng biến thành mã, và vì sao html/template tự escape theo ngữ cảnh

XSS xảy ra khi dữ liệu người dùng được nhúng vào trang mà không mã hoá, biến thành mã JavaScript chạy trong trình duyệt nạn nhân. Bài này đo thật trong Go: text/template để nguyên thẻ script (lỗ hổng), html/template tự mã hoá thành text vô hại; và cùng một chuỗi được escape KHÁC nhau tuỳ ngữ cảnh — HTML dùng <, JavaScript dùng \u003c, URL dùng %3c. Mã hoá đúng ngữ cảnh là chìa khoá chống XSS.

Lập trình 22/09/2026 6 phút

CSRF: vì sao cookie xác thực không đủ, và token chặn request giả mạo từ site khác

Trình duyệt tự động đính kèm cookie cho mọi request tới một domain — kể cả request do một trang độc khác kích hoạt. Đó là gốc rễ của CSRF: nếu server chỉ dựa vào cookie, kẻ tấn công khiến trình duyệt nạn nhân tự gửi request hợp lệ. Bài này tái hiện thật trong Go: một bank chỉ dựa cookie bị chuyển tiền (số dư 1000→900) từ request cross-site; thêm CSRF token, cùng request đó bị chặn (403, số dư không đổi). Cookie xác thực AI gửi; token xác thực request đến TỪ ĐÂU.

Lập trình 22/09/2026 7 phút

JWT: chữ ký bảo vệ token khỏi sửa đổi, và bẫy alg=none biến verifier thành kẻ phản bội

JWT cho phép server tin một token mà không cần tra DB — nhờ chữ ký. Nhưng chữ ký chỉ bảo vệ khi bạn verify đúng. Bài này tự cài JWT HS256 trong Go và tái hiện thật: sửa payload role=admin mà không có secret để ký lại thì bị phát hiện ngay (chữ ký không khớp); nhưng một verifier ngây thơ TIN trường alg trong token sẽ bị bẫy alg=none qua mặt — chấp nhận token giả không chữ ký. Verify đúng phải ép thuật toán mong đợi.

Lập trình 22/09/2026 6 phút

Command injection và path traversal: khi input biến thành lệnh shell hoặc thoát khỏi thư mục

Cùng gốc với SQL injection: khi input người dùng được ghép vào một lệnh shell, nó biến thành lệnh chạy trên server; khi được ghép vào đường dẫn file, ../ cho phép đọc file ngoài thư mục cho phép. Bài này tái hiện thật trong Go: shell nối chuỗi chạy lệnh thứ hai sau dấu chấm phẩy, còn exec.Command tách tham số coi input là một đối số vô hại; nối đường dẫn thô đọc được file bí mật ngoài baseDir, còn làm sạch + kiểm thuộc baseDir thì từ chối.

Lập trình 22/09/2026 6 phút

Brute-force và rate limiting: biến thời gian dò mật khẩu từ 15 giờ thành 380.000 năm

Một endpoint đăng nhập không giới hạn số lần thử là lời mời brute-force: kẻ tấn công cứ thử mật khẩu đến khi trúng. Bài này đo thật trong Go: không giới hạn, kẻ tấn công thử 18 triệu lần/giây (dò hết không gian 10^12 trong 15 giờ); thêm rate limit 5 lần sai/phút, 99.995/100.000 request bị chặn và thời gian brute-force vọt lên 380.000 năm. Kèm các đánh đổi: DoS khoá tài khoản, IP chung, và vì sao CAPTCHA/MFA mạnh hơn.

Lập trình 22/09/2026 6 phút

TLS/HTTPS: InsecureSkipVerify biến HTTPS thành vô dụng — mã hoá mà không xác thực là vô nghĩa

HTTPS làm hai việc: mã hoá dữ liệu VÀ xác thực bạn đang nói chuyện với đúng server. Tắt phần xác thực (InsecureSkipVerify) giữ lại mã hoá nhưng vứt bỏ sự an toàn. Bài này tái hiện thật trong Go: client mặc định từ chối cert tự ký với lỗi x509, nhưng InsecureSkipVerify=true chấp nhận bất kỳ cert nào — mở cửa cho kẻ người-đứng-giữa. Cách đúng khi cần tin cert riêng là thêm vào RootCAs, không bao giờ tắt verify.