
Cảnh báo bảo mật: Tại sao việc kiểm tra JWT Expiry của bạn có thể đang sai lệch 1000 lần?
Một sai lầm phổ biến khi xử lý NumericDate trong JWT có thể khiến hệ thống xác thực của bạn bị vô hiệu hóa hoặc lỗ hổng bảo mật nghiêm trọng. Tìm hiểu cách khắc phục lỗi sai lệch 1000x giữa giây và mili giây.
Bài viết được dịch và tổng hợp từ tin tức gốc. Bạn có thể đọc bài viết gốc bằng tiếng Anh tại đây.
Điểm tin nhanh:
- JWT sử dụng chuẩn NumericDate (số giây kể từ Epoch), trong khi nhiều hệ thống JavaScript lại mặc định sử dụng mili giây.
- Sai lệch 1000 lần giữa giây và mili giây dẫn đến việc token bị coi là hết hạn ngay lập tức hoặc không bao giờ hết hạn.
- Cần kiểm tra kỹ đơn vị thời gian khi so sánh
expclaim vớiDate.now()để tránh lỗ hổng bảo mật trong hệ thống xác thực.
Bạn đã bao giờ tự hỏi tại sao hệ thống xác thực của mình lại từ chối mọi yêu cầu hợp lệ ngay sau khi đăng nhập, hoặc tệ hơn, tại sao các token lại tồn tại mãi mãi bất chấp cấu hình thời gian hết hạn? Đây không phải là lỗi logic phức tạp, mà là một cái bẫy kinh điển liên quan đến cách xử lý thời gian trong JSON Web Token (JWT). Nếu bạn đang làm việc với các hệ thống xác thực, việc nắm vững cách quản lý thời gian là yếu tố sống còn để đảm bảo tính bảo mật, tương tự như cách bạn cần hiểu rõ về kiểm soát quyền truy cập Shell cho AI Agent để bảo vệ hệ thống của mình.
Hiểu về NumericDate trong JWT
Theo đặc tả RFC 7519, giá trị exp (Expiration Time) trong JWT được định nghĩa là một NumericDate. Đây là số giây kể từ thời điểm Epoch (1970-01-01T00:00:00Z UTC) cho đến thời điểm hết hạn.

Tuy nhiên, trong môi trường JavaScript, hàm Date.now() lại trả về giá trị tính bằng mili giây. Khi bạn so sánh trực tiếp hai giá trị này mà không thực hiện phép chia cho 1000, bạn sẽ rơi vào tình trạng sai lệch 1000 lần.
Bảng so sánh đơn vị thời gian
| Đơn vị | Hệ thống sử dụng | Giá trị mẫu (tại thời điểm 2026) |
|---|---|---|
| Giây | JWT (NumericDate) | 1770000000 |
| Mili giây | JavaScript (Date.now()) | 1770000000000 |
Tại sao sai lệch 1000 lần lại nguy hiểm?
Khi bạn thực hiện kiểm tra if (Date.now() > token.exp), nếu token.exp là 1770000000 (giây) và Date.now() là 1770000000000 (mili giây), điều kiện này sẽ luôn trả về true. Kết quả là mọi token đều bị coi là đã hết hạn ngay lập tức, dẫn đến lỗi xác thực hàng loạt. Ngược lại, nếu bạn thực hiện phép tính sai ở chiều ngược lại, token của bạn có thể tồn tại lâu hơn hàng nghìn lần so với dự kiến, tạo ra lỗ hổng bảo mật nghiêm trọng.
Lưu ý: Luôn luôn chuẩn hóa đơn vị thời gian về cùng một hệ quy chiếu trước khi thực hiện bất kỳ phép so sánh nào. Đây là nguyên tắc cơ bản trong bảo mật hệ thống, giống như cách bạn cần xây dựng công cụ phân tích Read-Only trước khi trao quyền hành động cho AI Agent để tránh các thao tác ghi dữ liệu trái phép.
Cách khắc phục triệt để
Để tránh lỗi này, bạn nên sử dụng các thư viện đã được kiểm chứng như jsonwebtoken hoặc jose. Nếu phải tự viết logic kiểm tra, hãy áp dụng quy tắc sau:
// Cách kiểm tra đúng
const currentTimestampInSeconds = Math.floor(Date.now() / 1000);
if (currentTimestampInSeconds > token.exp) {
throw new Error('Token expired');
}
Việc quản lý thời gian chính xác không chỉ quan trọng với JWT mà còn là chìa khóa trong các hệ thống phức tạp khác, chẳng hạn như khi bạn tối ưu hóa quy trình kiểm thử với Hook để đảm bảo các kịch bản kiểm thử chạy đúng thời điểm.
Đánh giá & Lời khuyên Thực tiễn
Ưu điểm
- NumericDate là chuẩn quốc tế, giúp JWT có thể tương tác giữa nhiều ngôn ngữ lập trình khác nhau (Node.js, Python, Go, Java).
Nhược điểm
- Dễ gây nhầm lẫn cho lập trình viên làm việc trong môi trường JavaScript/TypeScript do sự khác biệt về đơn vị thời gian.
Lời khuyên cho Production
- Không bao giờ tự viết logic xử lý token nếu không cần thiết. Hãy sử dụng các thư viện chuẩn.
- Luôn thêm
nbf(Not Before) vàiat(Issued At) để kiểm soát vòng đời token chặt chẽ hơn. - Khi hệ thống của bạn mở rộng, hãy cân nhắc việc xây dựng hệ thống giám sát cá nhân để phát hiện sớm các lỗi xác thực bất thường.
Câu hỏi thường gặp (FAQ)
Tại sao JWT lại dùng giây thay vì mili giây?
Việc sử dụng giây giúp tiết kiệm không gian lưu trữ trong header/payload của token, đồng thời đủ độ chính xác cho hầu hết các yêu cầu xác thực web.
Tôi có nên dùng thư viện bên thứ ba để xử lý JWT không?
Chắc chắn là có. Các thư viện như jsonwebtoken đã xử lý các trường hợp biên và lỗi NumericDate một cách an toàn, giúp bạn tránh được các lỗ hổng bảo mật không đáng có.
Làm sao để biết token của tôi đã bị lỗi 1000x?
Nếu bạn nhận thấy lỗi Token expired ngay sau khi tạo token, hoặc token không bao giờ hết hạn dù đã cấu hình, đó là dấu hiệu rõ ràng của việc sai lệch đơn vị thời gian.
Kết luận
Sai lầm về NumericDate là một ví dụ điển hình cho thấy những chi tiết kỹ thuật nhỏ có thể gây ra hậu quả lớn trong bảo mật. Bằng cách hiểu rõ cơ chế hoạt động của JWT và duy trì sự cẩn trọng trong code, bạn sẽ xây dựng được hệ thống bền vững hơn. Nếu bạn quan tâm đến việc tối ưu hóa các quy trình phát triển chuyên sâu, hãy theo dõi hi_dev để cập nhật thêm nhiều kiến thức kỹ thuật giá trị.
Do you like this post?
Upvote to push this post higher on the community feed





