Chuyển tới nội dung chính

3 bài viết được gắn thẻ "Bảo mật"

Phân quyền, IDOR, HTTPS và các lỗ hổng phổ biến theo phân loại OWASP.

Xem tất cả thẻ

Forward header trong ASP.NET Core: vì sao 'forward hết' là một lỗi kiến trúc

· 13 phút để đọc
Nguyễn Huỳnh Minh Tiến
Fullstack Developer @ Utop.io
Tóm tắt

Vòng lặp copy mọi header từ request đi vào sang request đi ra là một anti-pattern, và nó hỏng theo ba hướng khác nhau: sai về tính đúng đắn (một giá trị non-ASCII làm HttpClient ném exception), sai về bảo mật (bạn tin và chuyển tiếp dữ liệu do client tự đặt), và sai về kiến trúc (header do hạ tầng chèn trở thành một phần hợp đồng của ứng dụng). Cách sửa là allowlist — khai tường minh danh sách header được phép đi qua — đặt trong một DelegatingHandler dùng chung. Khi viết handler đó, cẩn thận một cái bẫy: nó không sống trong scope của request.

Bài này khép lại cụm ba bài bắt đầu từ một sự cố production trên nền tảng loyalty khoảng ba triệu khách hàng, nơi header cf-ipcity: Hồ Chí Minh do Cloudflare chèn làm hỏng một lời gọi nội bộ. Bài đầu kể sự cố, bài hai giải thích vì sao header không mang được tiếng Việt. Bài này trả lời câu hỏi còn lại: viết lại chỗ đó thế nào cho đúng.

Traefik + Cloudflare: vì sao cert hết hạn đồng loạt sau 60 ngày?

· 19 phút để đọc
Nguyễn Huỳnh Minh Tiến
Fullstack Developer @ Utop.io
Tóm tắt

Khi domain bật proxy Cloudflare (mây cam) với SSL mode Full (strict), ACME HTTP-01 không dùng được: Let's Encrypt gọi http://domain/.well-known/acme-challenge/... ở cổng 80, Cloudflare nhận rồi gọi ngược về origin bằng HTTPS:443 — nơi bộ xử lý challenge của Traefik không có mặt. Bạn cần cert để qua được Cloudflare, mà cần qua Cloudflare mới lấy được cert. Lách lần đầu bằng cách tạm tắt mây cam thì được, nhưng lần gia hạn tự động sau ~60 ngày sẽ trượt âm thầm và mọi site hết hạn cùng lúc. Lối ra là DNS-01: xác thực bằng bản ghi TXT qua API Cloudflare, không request nào chạm origin. Đổi lại, cert chỉ cấp được cho những zone mà API token nhìn thấy.

Trên VPS này đang có 14 container chung một reverse proxy: 10 site WordPress, một API .NET, một app Angular, một web app sự kiện, và Traefik. Mười ba hostname, tất cả nằm sau Cloudflare, tất cả cần HTTPS và không ai muốn gia hạn cert bằng tay.

Phần kiến trúc thì đơn giản đến mức nhàm. Phần thú vị nằm ở chỗ Cloudflare và Let's Encrypt, mỗi bên làm đúng việc của mình, nhưng ghép lại thì tạo ra một vòng luẩn quẩn mà bạn chỉ phát hiện vào ngày cert hết hạn — tức là hai tháng sau khi mọi thứ trông có vẻ đã xong.

Đổi id trên URL ra dữ liệu người khác? Chặn IDOR ở một tầng duy nhất

· 15 phút để đọc
Nguyễn Huỳnh Minh Tiến
Fullstack Developer @ Utop.io
Tóm tắt

IDOR xảy ra khi endpoint nhận id từ request rồi nạp thẳng bản ghi, chỉ kiểm tra người gọi đã đăng nhập chứ không kiểm tra người gọi có quyền trên đúng bản ghi đó. Đổi id sang GUID hay mã hoá id không sửa được lỗi, vì id vẫn rò ra ở chỗ khác. Cách sửa là bắt buộc mọi truy vấn phải đi qua một tầng ràng buộc quyền sở hữu ở server, thay vì rải lệnh kiểm tra trong từng controller.

Bạn có một endpoint rất đỗi bình thường: GET /api/orders/1043 trả về chi tiết đơn hàng. Nó nằm sau [Authorize], token hợp lệ mới gọi được, và trên giao diện thì người dùng chỉ bấm được vào đơn của chính họ.

Rồi một người đăng nhập bằng tài khoản thật của họ, sửa 1043 thành 1044 và bấm gửi. Nếu server trả về đơn hàng của người khác thì đó là Insecure Direct Object Reference, gọi tắt là IDOR. Không có payload, không có kỹ thuật gì, chỉ là một con số bị đổi.