AILapTrinh.comAI Lập Trình
An toàn mã nguồn và khoá bí mật

Kiểm tra đầu vào và chống XSS trong mã AI viết: biểu mẫu, tải tệp lên và xuất ra HTML

Mã AI viết hay tin dữ liệu người dùng: không kiểm ở máy chủ, chèn thẳng vào HTML, nhận tệp tải lên lỏng. Nguyên lý kiểm đầu vào, mã hoá đầu ra và rà nhanh.

Web developer pair working at a cafe table in Quy Nhon, one laptop open with a dimmed blank screen, sticky notes without writing, ocean light through a window, hands visible

Mã web do AI viết hay mắc hai lỗi đi liền nhau: tin dữ liệu người dùng gửi lên mà không kiểm ở phía máy chủ, và đưa dữ liệu đó ra trang HTML mà không mã hoá, mở đường cho tấn công chèn mã kịch bản chéo trang (XSS). Cách phòng chuẩn là kiểm đầu vào theo danh sách cho phép ở máy chủ, mã hoá đầu ra đúng ngữ cảnh khi hiển thị, và xử lý tệp tải lên như dữ liệu không tin cậy từ đầu tới cuối.

Bài này giải thích ba lớp đó theo cách áp dụng được khi rà mã, chỉ ra những chỗ AI hay viết sai trong JavaScript phía trình duyệt, PHP và các khuôn mẫu giao diện, kèm quy trình xử lý tệp tải lên và câu lệnh mẫu để nhờ AI viết đúng. Bài chỉ ở góc phòng thủ.

Kiểm đầu vào: phía máy chủ, theo danh sách cho phép

Kiểm tra ở trình duyệt, như thuộc tính bắt buộc của ô nhập hay đoạn JavaScript báo lỗi định dạng, chỉ để người dùng trải nghiệm tốt hơn. Bất kỳ ai cũng gửi được yêu cầu thẳng tới máy chủ mà không qua trình duyệt, nên mọi kiểm tra có ý nghĩa bảo mật phải lặp lại ở máy chủ. AI rất hay viết biểu mẫu có kiểm tra kỹ phía trình duyệt rồi để phía máy chủ nhận nguyên giá trị.

Kiểm theo danh sách cho phép nghĩa là mô tả cái hợp lệ, từ chối mọi thứ còn lại: mã sản phẩm là số nguyên dương, trạng thái thuộc bốn giá trị cố định, số điện thoại gồm chữ số với độ dài trong khoảng cho trước, ghi chú là chuỗi không quá năm trăm ký tự. Cách ngược lại, tìm và loại bỏ ký tự “nguy hiểm”, luôn sót, vì danh sách ký tự nguy hiểm phụ thuộc vào nơi dữ liệu sẽ đi tới.

Một điểm hay bị bỏ qua là chuẩn hoá trước khi kiểm. Chuỗi tiếng Việt có thể được gõ bằng các dạng mã hoá ký tự có dấu khác nhau, trông giống hệt nhưng so sánh thì khác. Nếu dữ liệu được dùng để so khớp, tìm kiếm hay kiểm trùng, chuẩn hoá về một dạng trước. Kiểm đầu vào cũng không thay thế được truy vấn tham số hay mã hoá đầu ra; nó là lớp đầu, không phải lớp duy nhất.

Mã hoá đầu ra theo ngữ cảnh

XSS xảy ra khi dữ liệu người dùng được trình duyệt hiểu là mã. Cách chặn là mã hoá dữ liệu theo đúng nơi nó được đặt vào. Mỗi ngữ cảnh có quy tắc riêng.

Nơi đặt dữ liệuCách đúngLỗi AI hay viết
Nội dung giữa các thẻ HTMLDùng cơ chế tự mã hoá của khuôn mẫu, hoặc hàm mã hoá ký tự đặc biệt HTML; trong PHP là htmlspecialchars với cờ ENT_QUOTES và bảng mã UTF-8Nối chuỗi HTML có biến, hoặc in biến thô bằng echo
Giá trị thuộc tính HTMLMã hoá như trên và luôn đặt giá trị trong dấu nháyThuộc tính không có dấu nháy, chỉ mã hoá dấu nhỏ hơn và lớn hơn
Đường dẫn trong href hoặc srcKiểm giao thức theo danh sách cho phép, chỉ nhận https và đường dẫn tương đối, rồi mới mã hoáNhận mọi chuỗi người dùng nhập làm đường dẫn, kể cả giao thức javascript
Dữ liệu trong JavaScriptTruyền dữ liệu qua thuộc tính data hoặc khối JSON được mã hoá đúng, rồi đọc bằng mãChèn biến vào giữa đoạn kịch bản nội tuyến bằng nối chuỗi
Cập nhật trang bằng JavaScriptGán vào textContent hoặc dùng hàm tạo phần tửGán chuỗi có dữ liệu người dùng vào innerHTML

Các khuôn khổ giao diện hiện đại thường tự mã hoá khi hiển thị biến, nhưng đều có lối thoát để chèn HTML thô, mang những cái tên cố tình đáng sợ hoặc cú pháp đặc biệt. Khi rà mã AI viết, tìm các lối thoát đó trước tiên. AI hay dùng chúng khi cần hiển thị chữ in đậm hay xuống dòng trong nội dung người dùng nhập.

Nếu thật sự cần cho người dùng nhập một ít định dạng, dùng thư viện làm sạch HTML có danh sách thẻ cho phép đã được kiểm chứng, không tự viết biểu thức chính quy để lọc thẻ.

Xử lý tệp tải lên an toàn

Tải tệp lên là chỗ AI hay viết lỏng nhất vì phiên bản đơn giản chạy được ngay. Quy trình dưới đây áp dụng cho ảnh đại diện, tài liệu đính kèm, tệp nhập dữ liệu.

  1. Giới hạn dung lượng ở cả máy chủ web và mã ứng dụng, từ chối sớm tệp quá lớn.
  2. Kiểm loại tệp theo nội dung thật, như đọc phần đầu tệp hoặc dùng thư viện nhận diện, đối chiếu danh sách loại cho phép. Không tin phần mở rộng tên tệp và không tin loại nội dung trình duyệt khai báo.
  3. Đặt tên mới cho tệp do máy chủ sinh, ví dụ chuỗi ngẫu nhiên kèm phần mở rộng chuẩn theo loại đã kiểm. Không dùng tên người dùng gửi lên làm đường dẫn lưu.
  4. Lưu tệp ngoài thư mục web có thể chạy mã, hoặc trên dịch vụ lưu trữ riêng; phục vụ tệp qua một đường dẫn kiểm quyền.
  5. Với ảnh, xử lý lại bằng thư viện ảnh, như đổi kích thước, để loại bỏ dữ liệu nhúng thừa, đồng thời xoá thông tin vị trí nếu có.
  6. Khi trả tệp về cho người dùng tải, đặt loại nội dung chính xác và chỉ thị tải về cho loại tệp không cần hiển thị trực tiếp.
  7. Ghi nhật ký ai tải lên tệp nào, lúc nào.

Bước bốn quan trọng hơn vẻ ngoài: nếu tệp tải lên nằm trong thư mục mà máy chủ web chạy được mã kịch bản, một tệp đội lốt ảnh có thể trở thành cửa sau. Nhiều mã mẫu cũ lưu thẳng vào thư mục uploads trong thư mục web, và AI hay tái tạo đúng mẫu đó.

Những lớp phòng thủ bổ sung

Chính sách bảo mật nội dung. Phần đầu phản hồi Content Security Policy cho trình duyệt biết được phép chạy kịch bản từ đâu. Cấu hình chặt, không cho phép kịch bản nội tuyến, giúp giảm thiệt hại khi lỡ có chỗ sót mã hoá. Áp dụng cho dự án đang chạy cần làm dần vì dễ làm hỏng tính năng; bắt đầu ở chế độ chỉ báo cáo.

Cookie phiên có cờ bảo vệ. Cookie phiên đăng nhập nên có cờ HttpOnly để kịch bản không đọc được, cờ Secure để chỉ gửi qua kết nối mã hoá, và thuộc tính SameSite phù hợp. AI viết phần đăng nhập đôi khi bỏ sót hoặc đặt sai các cờ này.

Giới hạn độ dài ở mọi nơi. Mỗi trường đều có độ dài tối đa ở cả biểu mẫu, mã kiểm và cột cơ sở dữ liệu. Dữ liệu dài bất thường là dấu hiệu sớm của việc dò tìm lỗ hổng.

Thông báo lỗi không phản chiếu nguyên dữ liệu. Câu báo lỗi kiểu “giá trị X không hợp lệ” mà in lại X không mã hoá là một chỗ XSS kinh điển. Mã hoá X hoặc không in lại.

Vì sao XSS đáng lo hơn một trang hiển thị lỗi

Nhiều người nghĩ XSS chỉ làm hiện một hộp thông báo vô hại. Thực tế, kịch bản chạy được trong trang của bạn có cùng quyền như chính trang đó trong trình duyệt người dùng: đọc được nội dung trang, gửi yêu cầu thay người dùng đang đăng nhập, thay đổi giao diện để dẫn người dùng nhập mật khẩu vào chỗ khác. Với trang quản trị, một lỗi XSS ở chỗ hiển thị góp ý của khách có thể dẫn tới việc tài khoản quản trị bị lợi dụng khi người quản trị mở trang xem góp ý.

Có hai dạng hay gặp trong mã AI viết. Dạng phản chiếu: dữ liệu từ tham số đường dẫn hay biểu mẫu được in thẳng lại trong phản hồi, như ô tìm kiếm hiển thị “kết quả cho từ khoá…”. Dạng lưu trữ: dữ liệu được lưu vào cơ sở dữ liệu rồi hiển thị cho người khác, như bình luận, tên hiển thị, ghi chú đơn hàng. Dạng lưu trữ nguy hiểm hơn vì một lần chèn ảnh hưởng mọi người xem.

Còn một dạng nằm hoàn toàn trong trình duyệt: mã JavaScript đọc giá trị từ phần sau dấu thăng hay tham số của đường dẫn rồi chèn vào trang bằng innerHTML. Máy chủ không thấy gì, công cụ quét phía máy chủ cũng không. Đây là kiểu AI hay viết khi bạn nhờ làm trang một tệp có lọc, tìm kiếm phía trình duyệt.

Câu lệnh mẫu và cách rà mã AI trả về

Khi nhờ AI viết biểu mẫu hay trang hiển thị dữ liệu người dùng, nêu ràng buộc ngay từ đầu. Câu lệnh mẫu: “Viết trang PHP nhận biểu mẫu góp ý gồm họ tên, email, nội dung, rồi hiển thị danh sách góp ý. Yêu cầu: kiểm tra đầu vào ở máy chủ theo danh sách cho phép với độ dài tối đa từng trường; dùng truy vấn tham số PDO; mọi chỗ in dữ liệu ra HTML dùng htmlspecialchars với ENT_QUOTES và UTF-8; có mã chống giả mạo yêu cầu; không dùng innerHTML ở phía trình duyệt. Liệt kê ở cuối các giả định bảo mật.”

Khi rà mã trả về, tìm theo từ khoá: mọi chỗ echo hoặc in biến, mọi chỗ gán innerHTML, mọi lối thoát HTML thô của khuôn mẫu, mọi chỗ đọc tham số yêu cầu. Với mỗi chỗ, hỏi dữ liệu này từ đâu tới và đã được kiểm hay mã hoá ở dòng nào.

Thử bằng tay với dữ liệu đặc biệt nhưng vô hại: tên có dấu nháy đơn và dấu nháy kép, nội dung có dấu nhỏ hơn và lớn hơn, chuỗi tiếng Việt có dấu dài. Trang hiển thị đúng nguyên văn các ký tự đó dưới dạng chữ, không vỡ bố cục, nghĩa là phần mã hoá đang hoạt động. Khi dán mã hay dữ liệu thử vào chatbot để hỏi, dùng dữ liệu giả, không dùng góp ý thật của khách.

Danh sách rà nhanh cho trang có biểu mẫu

Dùng danh sách dưới mỗi khi một yêu cầu gộp mã thêm biểu mẫu hay trang hiển thị nội dung người dùng.

  • Mọi trường có kiểm ở máy chủ, theo kiểu, độ dài và danh sách giá trị khi có.
  • Mọi chỗ hiển thị dữ liệu người dùng đều qua mã hoá đúng ngữ cảnh hoặc cơ chế tự mã hoá của khuôn mẫu.
  • Không có innerHTML hay lối thoát HTML thô nhận dữ liệu người dùng; nếu có, phải qua thư viện làm sạch.
  • Đường dẫn do người dùng nhập được kiểm giao thức.
  • Biểu mẫu thay đổi dữ liệu có mã chống giả mạo yêu cầu.
  • Tệp tải lên theo đủ quy trình bảy bước ở trên.
  • Thông báo lỗi không in lại dữ liệu thô.

Danh sách này không dài, nhưng một lượt rà theo nó thường bắt được phần lớn lỗi mà mã AI viết để lại ở tầng giao diện.

Câu hỏi thường gặp

Khuôn khổ đang dùng đã tự mã hoá thì còn cần lo XSS không?

Vẫn cần, ở ba chỗ: lối thoát chèn HTML thô, đường dẫn do người dùng nhập, và mã JavaScript tự cập nhật trang bằng innerHTML. Cơ chế tự mã hoá chỉ bảo vệ những chỗ dùng đúng cú pháp hiển thị thông thường của khuôn mẫu.

Lọc bỏ thẻ script khỏi dữ liệu nhập có đủ chống XSS không?

Không đủ. Có nhiều cách chạy kịch bản không cần thẻ đó, như thuộc tính sự kiện hay đường dẫn đặc biệt. Mã hoá đầu ra theo ngữ cảnh là cách đúng; nếu cần cho phép định dạng, dùng thư viện làm sạch đã kiểm chứng.

Có nên lưu dữ liệu đã mã hoá HTML vào cơ sở dữ liệu không?

Thường không nên. Lưu dữ liệu gốc đã kiểm, mã hoá khi hiển thị theo đúng ngữ cảnh. Lưu bản đã mã hoá dễ dẫn tới mã hoá hai lần khi hiển thị, hoặc sai khi dùng dữ liệu đó ở nơi khác như xuất tệp hay gửi thư.

Kiểm loại tệp bằng phần mở rộng có đủ không?

Không đủ, vì người gửi tự đặt tên tệp. Kiểm theo nội dung thật, đặt tên mới do máy chủ sinh và lưu ngoài thư mục chạy mã. Với ảnh, xử lý lại bằng thư viện ảnh là thêm một lớp an toàn.

Nhờ AI viết biểu thức chính quy kiểm email có ổn không?

Được, nhưng biểu thức kiểm email hoàn hảo rất phức tạp và hay sai. Nhiều ngôn ngữ có hàm kiểm định dạng email sẵn; dùng hàm đó, rồi xác nhận email bằng cách gửi thư kích hoạt. Kiểm định dạng chỉ là lọc thô.

Content Security Policy có thay được mã hoá đầu ra không?

Không. Đó là lớp giảm thiệt hại khi có chỗ sót. Mã hoá đầu ra vẫn là lớp chính; chính sách bảo mật nội dung đi kèm như dây an toàn.

Cần tư vấn cụ thể cho trường hợp của bạn?

Chúng tôi sẽ liên hệ trong vòng 24 giờ.

Đăng ký tư vấn ngay

Bài viết liên quan

Bạn cần hỗ trợ thêm?

Để lại thông tin, chúng tôi sẽ liên hệ trong 24 giờ.

hoặc
Gọi ngay 0926 138 138