Mã hóa và giải mã thực thể HTML: ký tự nào phải thoát và thoát ở đâu
Công cụ chuyển hai chiều giữa ký tự thật và thực thể HTML. Chiều giải mã dùng chính bộ phân tích của trình duyệt nên đọc được cả tên thực thể lẫn mã số. Chiều mã hóa thoát năm ký tự có ý nghĩa cú pháp, giữ nguyên chữ tiếng Việt có dấu để nội dung vẫn đọc được trong mã nguồn.
Tính năng nổi bật
- Chế độ giải mã đổi thực thể về ký tự gốc, hiểu cả dạng tên như và dạng mã số thập phân, thập lục phân
- Chế độ mã hóa thoát năm ký tự có ý nghĩa cú pháp là và, dấu nhỏ hơn, dấu lớn hơn, nháy kép và nháy đơn
- Giữ nguyên chữ tiếng Việt có dấu khi mã hóa, không biến chúng thành dãy mã số khó đọc
- Nút hoán đổi lấy kết quả đưa ngược lên ô nhập và tự chuyển chế độ, tiện khi cần kiểm tra vòng tròn
- Bảng tra mười hai thực thể hay gặp kèm ký tự thật và tên gọi để đối chiếu nhanh
- Ô nhập có sẵn ví dụ một thẻ đã bị mã hóa hoàn toàn, dùng để thử ngay khi mở trang
- Nút sao chép kết quả cho cả hai chiều
- Chạy trong trình duyệt, đoạn mã bạn dán vào không được gửi lên máy chủ
Vì sao ba ký tự tưởng vô hại lại phá vỡ cả trang
Trong HTML, dấu nhỏ hơn mở đầu một thẻ và dấu và mở đầu một tham chiếu ký tự. Bộ phân tích không đoán ý bạn: nó thấy dấu nhỏ hơn là bắt đầu tìm tên thẻ, thấy dấu và là bắt đầu tìm tên thực thể. Vì vậy một câu văn bình thường chứa công thức toán học, một đoạn mã minh họa, hay một tên công ty có dấu và ở giữa đều có thể khiến trình duyệt hiểu sai cấu trúc tài liệu. Hậu quả nhẹ là mất một đoạn chữ, hậu quả nặng là cả phần còn lại của trang bị hút vào trong một thẻ chưa đóng và biến mất. Nghiêm trọng hơn nữa là khi chuỗi đó đến từ người dùng: một đoạn nhập liệu chứa thẻ kịch bản mà bạn đưa thẳng vào trang sẽ chạy trên trình duyệt của mọi người khác. Chuyển những ký tự đó thành thực thể là cách nói với bộ phân tích rằng đây là chữ để hiển thị, không phải ký hiệu cú pháp.
Lợi ích khi sử dụng
- Đọc lại được nội dung thật từ những chuỗi đã bị mã hóa nhiều lớp trong nhật ký hay trong tệp xuất dữ liệu
- Chuẩn bị chuỗi an toàn khi cần chèn ví dụ mã nguồn vào bài viết mà không phá vỡ bố cục trang
- Chiều giải mã dùng bộ phân tích thật của trình duyệt nên nhận được hàng nghìn tên thực thể, không chỉ vài tên phổ biến
- Chữ tiếng Việt được giữ nguyên khi mã hóa, nên mã nguồn vẫn đọc được bằng mắt
- Nút hoán đổi giúp kiểm tra vòng tròn xem mã hóa rồi giải mã có ra đúng chuỗi ban đầu không
Cách dùng công cụ
- 1Chọn thẻ giải mã nếu bạn đang có một chuỗi đầy dấu và cùng tên thực thể và muốn đọc lại nội dung thật.
- 2Chọn thẻ mã hóa nếu bạn đang có văn bản thật và muốn nhúng nó an toàn vào tài liệu HTML.
- 3Dán nội dung vào ô bên trái rồi bấm nút tương ứng với chế độ đang chọn, vì kết quả không tự hiện khi gõ.
- 4Đọc kết quả ở ô bên phải và bấm nút sao chép để lấy chuỗi đưa vào mã nguồn của bạn.
- 5Nếu muốn kiểm tra chiều ngược, bấm nút hoán đổi để đưa kết quả lên ô nhập và tự đổi chế độ, rồi bấm lại nút chuyển.
Năm thực thể cơ bản và hai cách viết mã số
Có năm thực thể được định nghĩa sẵn ở mức nền tảng nhất: dấu và viết thành a m p, dấu nhỏ hơn viết thành l t, dấu lớn hơn viết thành g t, nháy kép viết thành q u o t, và nháy đơn viết thành a p o s. Mọi thực thể đều mở đầu bằng dấu và và kết thúc bằng dấu chấm phẩy; thiếu dấu chấm phẩy thì một số trường hợp trình duyệt vẫn đoán được nhưng nhiều trường hợp thì không, nên đừng bỏ. Ngoài dạng tên, còn hai dạng mã số dùng được cho mọi ký tự Unicode. Dạng thập phân viết dấu và, dấu thăng, rồi số thứ tự của ký tự; dấu nhỏ hơn có số thứ tự 60 nên viết là dấu và, dấu thăng, 60, dấu chấm phẩy. Dạng thập lục phân thêm chữ x sau dấu thăng; cùng ký tự đó viết là dấu và, dấu thăng, x, 3C, dấu chấm phẩy. Hai dạng mã số luôn hoạt động kể cả với ký tự không có tên riêng, nên chúng là lựa chọn an toàn khi bạn không chắc. Một lưu ý đáng nhớ: thực thể tên a p o s không được công nhận trong phiên bản HTML cũ, nên khi cần chắc chắn tuyệt đối thì dùng dạng mã số 39 cho nháy đơn.
Ký tự nào bắt buộc thoát, tùy vị trí đặt chuỗi
Không phải lúc nào cũng cần thoát cả năm ký tự, và biết đúng chỗ giúp mã nguồn dễ đọc hơn. Trong phần nội dung văn bản giữa hai thẻ, chỉ có dấu và cùng dấu nhỏ hơn là thật sự bắt buộc; dấu lớn hơn và hai loại nháy nằm ở đây vẫn hiển thị bình thường. Trong giá trị của một thuộc tính đặt giữa nháy kép, bạn bắt buộc phải thoát dấu nháy kép và dấu và; nếu dùng nháy đơn bao ngoài thì đổi lại phải thoát nháy đơn. Trường hợp nguy hiểm nhất là giá trị thuộc tính không được bao bởi dấu nháy nào, khi đó chỉ cần một dấu cách trong dữ liệu là kẻ tấn công chèn thêm được thuộc tính mới; vì vậy hãy luôn bao giá trị thuộc tính bằng dấu nháy. Trong phần nội dung của thẻ kịch bản và thẻ định kiểu, quy tắc khác hẳn: những vùng này không xử lý thực thể, nên mã hóa vào đó không những vô ích mà còn làm hỏng mã. Đó là lý do việc thoát ký tự phải làm theo ngữ cảnh nơi chuỗi sẽ nằm, chứ không phải làm một lần rồi dùng khắp nơi.
Lỗi mã hóa hai lần và cách nhận ra
Dấu hiệu là bạn nhìn thấy trên trang một chuỗi dạng dấu và, chữ a m p, dấu chấm phẩy, rồi ngay sau đó là chữ l t. Nguyên nhân là chuỗi đã đi qua hai lớp mã hóa: lớp đầu biến dấu nhỏ hơn thành thực thể l t, lớp sau lại biến dấu và của chính thực thể đó thành a m p. Kết quả là người đọc thấy đúng cái tên thực thể chứ không thấy dấu nhỏ hơn. Đây là lỗi rất phổ biến ở những dự án có nhiều tầng: khung ứng dụng đã tự thoát ký tự khi kết xuất, nhưng lập trình viên thoát thêm một lần nữa vì không biết. Cách sửa không phải là dán thêm bộ giải mã ở tầng hiển thị, vì làm vậy sẽ mở lại đúng lỗ hổng mà việc thoát ký tự sinh ra để bịt. Cách đúng là tìm ra tầng nào đang thoát rồi bỏ bớt một tầng, theo nguyên tắc chỉ thoát đúng một lần và thoát ở tầng gần nơi xuất ra nhất. Bạn có thể dùng công cụ này để kiểm chứng: dán chuỗi vào chế độ giải mã, nếu bấm một lần chưa ra chữ gốc mà phải bấm hai lần mới ra, thì chắc chắn nội dung đang bị mã hóa chồng lớp.
Khoảng trắng không ngắt và những rắc rối nó gây ra
Thực thể n b s p tạo ra một ký tự nhìn giống dấu cách nhưng thực chất là một ký tự khác hẳn, có mã riêng trong bảng Unicode. Nó có hai đặc tính: trình duyệt không ngắt dòng tại vị trí đó, và nhiều dấu liên tiếp không bị gộp lại thành một như dấu cách thường. Dùng đúng thì rất hữu ích, chẳng hạn giữ cho con số và đơn vị không bị tách ra hai dòng, hay giữ tên riêng gồm hai từ luôn nằm cùng dòng. Dùng sai thì gây phiền toái dai dẳng. Trường hợp hay gặp nhất là nội dung sao chép từ trình soạn thảo văn bản vào hệ quản trị nội dung mang theo hàng loạt ký tự này, khiến các đoạn chữ không xuống dòng đúng chỗ trên điện thoại và bị tràn ra khỏi khung. Trường hợp khác là chuỗi tìm kiếm không khớp vì người dùng gõ dấu cách thường trong khi dữ liệu chứa ký tự không ngắt. Khi gặp hiện tượng chữ bị tràn hay tìm kiếm không ra dù nhìn giống hệt, hãy dán đoạn đó vào chế độ mã hóa để soi xem có ký tự lạ nào không.
Thoát ký tự là cần nhưng chưa đủ để chặn tấn công chèn mã
Cần nói rõ để bạn không yên tâm quá sớm. Chuyển năm ký tự thành thực thể ngăn được nhóm tấn công phổ biến nhất, nhưng chỉ khi chuỗi đó nằm trong phần nội dung văn bản hoặc trong giá trị thuộc tính thông thường. Có những vị trí mà việc thoát này hoàn toàn vô tác dụng. Nếu chuỗi của người dùng được đưa vào một thuộc tính đường dẫn, kẻ tấn công dùng giao thức giả để chạy mã mà không cần bất kỳ ký tự nào trong năm ký tự trên. Nếu chuỗi được nhúng vào trong đoạn mã kịch bản, quy tắc thoát phải theo cú pháp của ngôn ngữ đó chứ không phải theo HTML. Nếu chuỗi rơi vào thuộc tính xử lý sự kiện thì gần như không có cách thoát nào an toàn. Vì vậy cách làm đúng là lọc theo ngữ cảnh, dùng hàm thoát chuyên biệt của khung ứng dụng thay vì tự viết, kiểm tra đường dẫn theo danh sách giao thức cho phép, và thiết lập chính sách bảo mật nội dung ở tầng máy chủ như một lớp phòng thủ thứ hai. Công cụ này giúp bạn hiểu và kiểm tra chuỗi, nó không phải là giải pháp bảo mật.
Câu hỏi thường gặp (FAQ)
Thực thể HTML là gì?
Là cách viết thay thế cho một ký tự, mở đầu bằng dấu và và kết thúc bằng dấu chấm phẩy. Nó tồn tại để bạn hiển thị được những ký tự vốn mang ý nghĩa cú pháp trong HTML, chẳng hạn dấu nhỏ hơn vốn dùng để mở thẻ. Ngoài dạng tên, mọi ký tự Unicode đều viết được bằng dạng mã số thập phân hoặc thập lục phân.
Những ký tự nào bắt buộc phải thoát?
Trong phần nội dung văn bản, chỉ dấu và cùng dấu nhỏ hơn là thật sự bắt buộc. Trong giá trị thuộc tính bao bởi nháy kép thì phải thoát thêm dấu nháy kép. Công cụ thoát cả năm ký tự cho an toàn, nhưng biết đúng chỗ giúp bạn không mã hóa thừa và giữ mã nguồn dễ đọc hơn.
Vì sao trên trang tôi thấy chuỗi dạng dấu và kèm chữ amp?
Đó là dấu hiệu nội dung bị mã hóa hai lần. Lớp đầu biến ký tự thành thực thể, lớp sau lại mã hóa chính dấu và của thực thể đó. Cách sửa là tìm tầng nào đang thoát rồi bỏ bớt một tầng, chứ không phải thêm bộ giải mã ở tầng hiển thị vì làm vậy sẽ mở lại đúng lỗ hổng mà việc thoát sinh ra để bịt.
Dạng tên và dạng mã số nên dùng cái nào?
Dạng tên dễ đọc hơn nhiều nên hợp cho các ký tự thông dụng. Dạng mã số hoạt động với mọi ký tự Unicode kể cả những ký tự không có tên riêng, và không phụ thuộc vào việc trình duyệt có biết tên đó hay không. Khi làm việc với XML thuần, chỉ năm tên cơ bản được công nhận nên các ký tự khác buộc phải dùng dạng mã số.
Chữ tiếng Việt có dấu có cần mã hóa không?
Không cần, miễn là tài liệu của bạn khai báo bảng mã UTF-8. Chữ có dấu không mang ý nghĩa cú pháp nào nên để nguyên vẫn hiển thị đúng, và mã nguồn dễ đọc hơn nhiều. Công cụ này cố ý giữ nguyên chúng khi mã hóa. Chỉ nên đổi sang dạng mã số trong những hệ thống cũ bắt buộc dùng bảng mã một byte.
Vì sao chữ tiếng Việt hiển thị thành ký tự lạ?
Đó thường không phải vấn đề thực thể mà là vấn đề bảng mã: nội dung được lưu bằng một bảng mã nhưng đọc bằng bảng mã khác. Kiểm tra thẻ khai báo bảng mã trong phần đầu tài liệu, kiểm tra tiêu đề phản hồi của máy chủ, và kiểm tra bảng mã của cột trong cơ sở dữ liệu. Giải mã thực thể không sửa được lỗi này.
Khoảng trắng không ngắt khác dấu cách thường ra sao?
Nó là một ký tự riêng, trình duyệt không ngắt dòng tại đó và nhiều ký tự liên tiếp không bị gộp lại thành một. Dùng đúng thì giữ được con số và đơn vị nằm cùng dòng. Dùng sai, thường do sao chép từ trình soạn thảo văn bản, sẽ khiến chữ không xuống dòng đúng chỗ và tràn ra khỏi khung trên điện thoại.
Thoát ký tự có đủ để chặn tấn công chèn mã không?
Không đủ. Nó chỉ hiệu quả khi chuỗi nằm trong nội dung văn bản hoặc thuộc tính thông thường. Với thuộc tính đường dẫn, thuộc tính xử lý sự kiện, hay chuỗi nhúng vào mã kịch bản thì cần cách xử lý khác hẳn. Hãy dùng hàm thoát theo ngữ cảnh của khung ứng dụng, kiểm tra giao thức trong đường dẫn, và bật chính sách bảo mật nội dung.
Chế độ giải mã có nguy hiểm không khi tôi dán mã lạ vào?
Chuỗi được đặt vào một vùng chỉ nhận văn bản thô nên các thẻ trong đó không được tạo ra và không có mã nào chạy; chỉ các tham chiếu ký tự được chuyển về ký tự thật. Tuy vậy hãy cẩn thận với kết quả: đừng lấy chuỗi vừa giải mã rồi chèn thẳng vào trang của bạn mà không kiểm tra lại.
Vì sao thực thể của nháy đơn hay bị khuyến cáo tránh dùng?
Vì tên gọi của nó không được công nhận trong phiên bản HTML cũ, chỉ có trong XML và các phiên bản HTML sau này. Một số trình duyệt đời trước hiển thị nguyên chuỗi thay vì dấu nháy. Khi cần chắc chắn tuyệt đối, hãy dùng dạng mã số thập phân 39 thay cho dạng tên.
Kết quả có tự cập nhật khi tôi gõ không?
Không, bạn phải bấm nút chuyển đổi tương ứng với chế độ đang chọn. Nút hoán đổi ở bên cạnh làm một việc khác: nó đưa kết quả hiện tại lên ô nhập và tự đảo chế độ, tiện khi bạn muốn kiểm tra xem mã hóa rồi giải mã có trả về đúng chuỗi ban đầu hay không.
Nội dung tôi dán vào có bị gửi lên máy chủ không?
Không. Cả hai chiều đều chạy bằng JavaScript trong trình duyệt của bạn, chiều giải mã còn dùng chính bộ phân tích có sẵn của trình duyệt. Không có yêu cầu mạng nào mang theo nội dung, nên bạn dán được cả đoạn mã nội bộ hay dữ liệu chưa công bố.
Từ khóa liên quan
- html entities là gì
- giải mã html entities
- encode ký tự đặc biệt html
- escape html online
- amp lt gt quot apos
- mã số ký tự html
- lỗi double encoding html
- nbsp là gì
- khoảng trắng không ngắt dòng
- hiển thị dấu nhỏ hơn trong html
- chèn code vào bài viết html
- xss escape html
- chuỗi bị mã hóa hai lần
- utf-8 tiếng việt bị lỗi font
- html decode online free
- chuyển ký tự sang mã html
- bảng tra html entities
- thoát ký tự trong thuộc tính html
- content security policy xss
- công cụ encode decode html miễn phí
