Hãy để tôi chỉ cần nhập vài con số thôi
(gendignoux.com/blog)- Ô nhập mã xác thực email 6 chữ số của hệ thống đăng nhập chính phủ Thụy Sĩ AGOV không xử lý được việc nhập số trên bàn phím AZERTY kiểu Pháp, khiến bản thân việc đăng ký tài khoản cũng bị chặn
- JavaScript của ô nhập đã chặn thao tác gõ phím và lưu mã xác thực vào một biến riêng, đồng thời bỏ qua phím Shift, nên trên thực tế đã chặn bố cục AZERTY nơi cần Shift để nhập số
- Cùng một lỗi xuất hiện trên nhiều tổ hợp Firefox·Chromium·Chrome·Safari và Linux·macOS, nhưng hoạt động bình thường trên bàn phím QWERTY, qua đó thu hẹp nguyên nhân không phải trình duyệt hay hệ điều hành mà là bố cục bàn phím
- Hỗ trợ chính thức cũng chỉ dùng được sau khi vượt qua cùng bước xác thực email đó, và không có phương án thay thế như email hay điện thoại, nên người dùng không đăng nhập được thậm chí cũng không thể báo lỗi đăng nhập
- Khi dùng logic xử lý phím phức tạp thay vì trường nhập native, đồng thời buộc sản phẩm và kênh hỗ trợ dùng chung một quy trình xác thực, thì cả khả năng truy cập lẫn ứng phó sự cố đều sụp đổ; vì vậy cần ô nhập đơn giản dựa trên DOM và các kênh hỗ trợ độc lập
AGOV đã trở thành hạ tầng nhận dạng số
- Nhận dạng số gần đây đã nổi lên như một chủ đề tranh cãi lớn trên web, kéo theo nhiều phụ thuộc lẫn tranh cãi
- Luật xác minh độ tuổi ảnh hưởng tới tính ẩn danh trực tuyến
- Tại Anh, Wikipedia có thể phải xác minh danh tính người dùng
- Vấn đề ví định danh số phụ thuộc vào iOS và Android chính thức như các nền tảng bắt buộc để hoạt động
- Một trường hợp tài khoản số tại Mỹ bị hủy chỉ vì là thẩm phán của Tòa án Hình sự Quốc tế
- Hệ thống đăng nhập chính phủ Thụy Sĩ AGOV đã đi vào hoạt động từ năm 2024, và số tài khoản đã đạt 1,6 triệu
- Nó đang được mở rộng làm phương thức đăng nhập cho nhiều nghiệp vụ chính phủ, gồm cả bảo hiểm thất nghiệp và khai thuế bắt buộc
- Tại bang Zurich, đây là phương thức đăng nhập duy nhất để truy cập đơn xin nhập quốc tịch
Đăng ký dừng lại ở bước xác thực email
- Quy trình đăng ký AGOV bắt đầu bằng việc gửi địa chỉ email rồi nhập mã xác thực 6 chữ số
- Giao diện mã xác thực gồm tổng cộng 6 ô nhập, mỗi ô cho một chữ số
- Dù nhập số thì con trỏ cũng không chuyển sang ô tiếp theo
- Số tiếp tục dồn vào ô hiện tại và chuyển sang trạng thái lỗi màu đỏ
- Ngay cả khi tự chuyển từng ô để nhập, cuối cùng vẫn hiện lỗi
field required
- Khi thử sửa trực tiếp giá trị DOM bằng công cụ cho nhà phát triển thì không thấy giá trị form nào rõ ràng, và console web cũng không ghi lỗi
- Kết quả vẫn như vậy dù dùng địa chỉ email khác hay địa chỉ giả như
test@example.comexample.comlà tên miền được dành riêng theo RFC 6761
Loại trừ khả năng do trình duyệt và hệ điều hành
- Ban đầu người viết nghi ngờ tổ hợp Firefox và Linux không được hỗ trợ hoặc CAPTCHA bị lỗi
- Ngay trước khi form mã xác thực hiện ra, trang kết nối tới
eu-api.friendlycaptcha.eu - Tài liệu yêu cầu chính thức chỉ ghi Windows và macOS là hệ điều hành được hỗ trợ
- Trong khi đó, hướng dẫn khóa bảo mật lại nói Linux và Firefox cũng được hỗ trợ
- Ngay trước khi form mã xác thực hiện ra, trang kết nối tới
- Cùng một lỗi xuất hiện trên cả 6 tổ hợp môi trường sau
- Firefox, Chromium, Chrome trên Linux
- Firefox, Safari, Chrome trên macOS
- Trên laptop công việc, sau khi nhập thì con trỏ tự chuyển sang ô kế tiếp, và lỗi
Code entered is incorrectcho mã sai nhưng không rỗng cũng hiển thị bình thường - Trên máy macOS của một người bạn, cả ba trình duyệt đều chấp nhận mã xác thực
- Không thể phụ thuộc vào máy tính do công ty cấp để tương tác lâu dài với dịch vụ chính phủ; ngay cả nếu đăng ký được trên máy công việc, vẫn còn khả năng không thể đăng nhập trên laptop cá nhân
Cấu trúc hỗ trợ còn chặn cả việc báo lỗi
- Hỗ trợ chính thức chỉ được cung cấp qua form web, và form này cũng yêu cầu nhập mã xác thực email trước
- FAQ nêu rõ hỗ trợ từ các cơ quan tham gia chỉ được cung cấp trong giờ làm việc thông qua việc tạo ticket trực tuyến
- Ngoài địa chỉ bưu điện của Swiss Federal Chancellery thì không có email hay số điện thoại nào
- Tính năng phản hồi để gửi lời khen, phê bình hay yêu cầu cho AGOV cũng đòi hỏi đăng nhập bằng AGOV hoặc tài khoản tương đương
- Người dùng thất bại ở bước xác thực email rơi vào một vòng phụ thuộc lặp kín: không thể báo lỗi cũng vì cùng quy trình xác thực đó
-
AGOV Access và các thiết bị được hỗ trợ
- Ứng dụng AGOV Access Android có điểm đánh giá 1,4, nhưng trong review trên Google Play không thấy cùng vấn đề mã xác thực này
- Các review có nhiều yêu cầu hỗ trợ GrapheneOS, một biến thể Android tập trung vào bảo mật và quyền riêng tư
- Theo FAQ chính thức, ứng dụng không hoạt động vì framework tăng cường chống sửa đổi trái phép không tương thích với GrapheneOS
- Federal Chancellery đã chỉ đạo nhà cung cấp đảm bảo khả năng tương thích
- Hiện tại, phương thức xác thực hai yếu tố cho đăng ký và đăng nhập là smartphone iOS·Android tiêu chuẩn được chấp nhận hoặc khóa bảo mật, và dù là cách nào thì cũng phải vượt qua bước xác thực email trước
Nguyên nhân được tìm thấy trong JavaScript
- Tài nguyên mà trang tải về không nhiều, nhưng file JavaScript chính ở dạng minify nhưng không bị làm rối có kích thước 2,4MB, và nếu bung ra thì vượt quá 100.000 dòng
- Tìm chuỗi
field requiredđã lần ra logic đặt trạng thái mã xác thực- Nếu không có biến mã xác thực thì trạng thái được đặt là
REQUIRED - Nếu độ dài khác với độ dài mã yêu cầu thì bị xử lý là
WRONG - Nếu độ dài khớp thì dùng
VALIDhoặc trạng thái lỗi theo kết quả xác thực email từ máy chủ
- Nếu không có biến mã xác thực thì trạng thái được đặt là
- Hàm
verificationCodeEnteredchặn thao tác gõ phím và thu thập mã xác thực vào một biến JavaScriptEnterchạy callback xác thựcBackspacexóa giá trị hiện tại- Phím mũi tên và
Tabdi chuyển giữa các ô nhập - Các phím thông thường được đổi thành số bằng
Number(S.key)rồi lưu vào mã - Các phím như
Control,Meta,Shift,v,rbị bỏ qua và hàm trả về
- Vì khi gửi form nó không đọc giá trị DOM, nên dù sửa ô nhập bằng công cụ cho nhà phát triển hay tiện ích mở rộng trình duyệt, trạng thái do JavaScript quản lý riêng cũng không được cập nhật
Vì sao số chỉ bị chặn trên AZERTY
- Bố cục AZERTY tiêu chuẩn của Pháp cần phím Shift để nhập số
- Vì code bỏ qua thao tác nhấn Shift nên trên AZERTY bản thân chữ số không thể được lưu vào mã xác thực
- Máy công việc dùng bố cục QWERTY tiếng Anh, và trong những người hỗ trợ xác minh vấn đề thì không có ai là người Pháp
- Kết quả là trong các thiết bị đã thử, chỉ hai laptop cá nhân trông như bị lỗi
- Khi đổi bố cục bàn phím trong hệ điều hành sang bố cục khác thì việc nhập trên laptop cá nhân hoạt động lại bình thường
- Ngược lại, khi chuyển một thiết bị vốn hoạt động bình thường sang bố cục kiểu Pháp, cùng lỗi lại được tái hiện
- Bàn phím tiếng Pháp tiêu chuẩn ở Thụy Sĩ thuộc họ QWERTZ, phổ biến ở Trung Âu
- Nó cho phép nhập tiếng Pháp và tiếng Đức hiệu quả, và không cần Shift để nhập số nên không gặp cùng lỗi này
- Theo Swiss Federal Statistical Office, có khoảng 171.000 cư dân mang quốc tịch Pháp tại Thụy Sĩ; con số này còn chưa tính người lao động qua biên giới phải tương tác với chính phủ Thụy Sĩ
Hạn chế điều tra trước khi mã nguồn được công khai
- Theo FAQ của AGOV, mã nguồn AGOV dự kiến sẽ được công khai vào tháng 12/2026 để đáp ứng yêu cầu pháp lý
- Điều 9 EMBAG yêu cầu các cơ quan liên bang công khai mã nguồn phần mềm do họ trực tiếp phát triển hoặc đặt phát triển để thực hiện nhiệm vụ
- Ngoại lệ được áp dụng nếu quyền của bên thứ ba hoặc lý do an ninh cản trở hay hạn chế việc công khai
- Đối tượng công khai là phiên bản AGOV đã đạt mục tiêu dự án, bao gồm AGOV e-ID Verifier; các phiên bản về sau sẽ được công khai kèm release note chuẩn bị sau khi phát hành
- Dù một số dịch vụ đã bắt buộc dùng AGOV để đăng nhập, mã nguồn vẫn chưa được công khai, khiến người dùng khó báo lỗi trực tiếp cho nhà phát triển hoặc chia sẻ cách lách tạm thời
Phạm vi xác minh danh tính được kiểm tra sau khi đăng ký
- Sau khi đổi bố cục bàn phím, người viết đã xác thực địa chỉ email và hoàn tất đăng ký bằng khóa bảo mật
- Trong quá trình đăng ký có nhập tên, số điện thoại và ngày sinh, nhưng các thông tin này không được xác minh
- Ở bước đăng ký cơ bản chỉ có hai điều được xác nhận
- Địa chỉ email thực sự tồn tại
- Phương thức xác thực hai yếu tố là khóa bảo mật thuộc mẫu được chấp nhận, hoặc ứng dụng AGOV Access chạy trên thiết bị Android·iOS được chấp nhận
- AGOV có khả năng chống chiếm đoạt tài khoản do phishing từ xa tốt, nhưng ở bước đăng ký cơ bản không ngăn được việc người khác tạo tài khoản bằng tên và thông tin danh tính của người khác
- Kiểm tra thêm cho thấy, khi truy cập các dịch vụ được phân loại là nhạy cảm thì cần xác minh danh tính
- Ngay sau khi đăng ký, người viết vẫn chưa truy cập loại dịch vụ đó
- Đã báo lỗi qua form hỗ trợ nhưng không nhận được phản hồi
Bài học rút ra từ thiết kế
-
Thiết kế nhập liệu và hỗ trợ thiếu độ bền vững
- Cách làm UI cầu kỳ bằng 6 ô nhập và logic JavaScript phức tạp là không bền vững
- Tốt hơn là dùng một trường nhập native của trình duyệt rồi chỉ trang trí hình thức bằng CSS
- Khi tách hoàn toàn logic form khỏi DOM thì lúc submit không thể đọc giá trị DOM, và người dùng nâng cao hay tiện ích mở rộng trình duyệt cũng không thể sửa giá trị nhập
- Nếu chỉ có một kênh hỗ trợ, khi chính kênh đó hỏng thì sẽ không còn cách liên hệ; vì vậy cần kênh thứ hai như email hoặc điện thoại
- Nếu áp dụng cùng một logic đăng nhập cho cả sản phẩm lẫn kênh hỗ trợ thì sẽ bỏ lỡ báo lỗi từ những người không thể đăng nhập
- Đây cũng là lý do nhiều dịch vụ Internet đặt trang trạng thái ở một tên miền riêng
- Đặt yêu cầu hỗ trợ sau bước xác thực email có thể giảm spam, nhưng cũng làm giảm cả báo cáo sự cố từ người dùng thật
- Nếu chỉ công khai mã nguồn sau khi một số hệ thống đã bắt buộc sử dụng thì khả năng tự giải quyết vấn đề, chia sẻ bug và cách lách của người dùng sẽ bị hạn chế
- Việc công khai mã nguồn theo luật không chỉ là một hạng mục tuân thủ mà còn hữu ích cho điều tra sự cố thực tế
-
Web mở đã giúp việc điều tra
- Vì logic JavaScript liên quan không bị làm rối, chỉ cần vài lần tìm chuỗi là đã tìm ra nguyên nhân
- Không cần decompiler cao cấp hay LLM đắt tiền
- Nếu mã bị làm rối hoặc được biên dịch thành WebAssembly thì sẽ mất nhiều thời gian hơn rất nhiều để xác định nguyên nhân
- Mã không chỉ được phân phối trên các hệ điều hành đóng đã được phê duyệt mà được cung cấp qua web mở, nên vẫn có thể tải về để điều tra dù chỉ ở dạng minify
-
Những điều kiện giúp xác định nguyên nhân
- Có thể so sánh nhiều laptop dùng các bố cục bàn phím khác nhau, qua đó sớm giảm khả năng lỗi theo trình duyệt hoặc lỗi mạng
- Tuy vậy, để xác nhận đây không phải lỗi thao tác của người dùng, tác giả đã phải chụp màn hình một cách có hệ thống ở từng tổ hợp trình duyệt trong giai đoạn thu thập bằng chứng ban đầu, nên vẫn tốn thời gian
1 bình luận
Ý kiến trên Lobste.rs
Một trong những thói quen tôi đặc biệt ghét trên Internet là các website chặn thao tác gõ phím rồi tự xử lý theo ý mình, thay vì chuyển nguyên vẹn cho trình duyệt Các trang cấm sao chép/dán vào trường mật khẩu phổ biến hơn nhiều, nhưng việc này cũng cùng một kiểu và có lẽ còn có vẻ nghiêm trọng hơn
Cách làm mỗi ký tự một ô nhập giống như một dịch bệnh Một công ty nào đó thấy trông hay ho nên áp dụng, và giờ ai cũng tự triển khai phiên bản riêng của mình
Một ví dụ liên quan là Medium once had a bug like this which prevented entering the character 'Ś'
Tôi đã nghĩ thử các cách triển khai khác, nhưng cuối cùng vẫn không tìm được cách nào tốt hơn `` bình thường Ngay cả việc trang trí bằng CSS để nó trông quá khác ô nhập thông thường cũng khiến tôi do dự. Có thể sao chép giá trị nhập để hiển thị trong các ô lớn, nhưng khi người dùng nhập nhiều hơn độ dài cho phép thì xử lý ra sao, cùng đủ loại vấn đề khác cần trả lời; lợi ích không đủ lớn để đáng công. Nhiều nhất tôi chỉ đổi phông chữ và kích thước của ô nhập
1224thay vì1234Cách sửa nhanh nhất là nhấp vào số2thứ hai rồi nhấn3, nhưng chỉ với HTML+CSS thì không thể triển khai được** để về mặt thị giác trông như sáu ô hay không Cách dễ hơn là để người dùng nhập vào một ô văn bản duy nhất, rồi JavaScript vẽ sáu ô ở vị trí khác trong DOM và cập nhật bằng sự kiện `input` phát sinh mỗi khi nhấn phím Khó chắc cách nào tốt hơn về khả năng tiếp cận. Từ góc nhìn trình đọc màn hình, phương án sau — mộtbình thường kèmchỉ để trang trí — có thể còn tốt hơn, và thao tác bàn phím cũng không trở nên kỳ quặc. Nhưng với người dùng sử dụng công cụ hỗ trợ ngoài trình đọc màn hình, việc ẩnvề mặt thị giác có thể trở thành thảm họa về khả năng tiếp cận, nên phải cực kỳ thận trọngCũng có thể, như nhiều dịch vụ khác, cung cấp cả mã lẫn liên kết kích hoạt trong email
Tridactyl cũng có đúng vấn đề y hệt https://github.com/tridactyl/tridactyl/issues/3257 Vấn đề này được báo cáo lần đầu vào năm 2019; không biết liệu sự việc lần này có khiến họ xấu hổ mà sửa nó không
Điều này một lần nữa cho thấy việc tạo ra một website hỏng hoặc chậm tốn nhiều công sức hơn hẳn so với một website cứ thế hoạt động bình thường