← Về trang chính

App của tôi đã đủ an toàn để chạy thật chưa?

Bạn làm ra một thứ chạy được. Giờ bạn muốn đưa nó cho người khác dùng, mà chưa ai nói cho bạn biết như vậy có ổn không.

Đây là danh sách chúng tôi chạy qua mỗi khi có người hỏi câu đó. Không cần bạn là kỹ sư bảo mật, và mỗi mục đều viết sao cho bạn tự làm được trong một buổi chiều. Ba mục đầu là những mục thật sự thành sự cố — qua được ba mục đó là bạn đã đi qua phần nguy hiểm nhất.

  1. Người khác có đọc được API key của bạn không?

    Mọi thứ app gửi xuống trình duyệt đều là công khai — code, config, và từng chuỗi ký tự bên trong. Build tool quyết định cái gì được gửi ra bằng tiền tố: Vite lấy mọi biến tên VITE_, Next.js lấy mọi biến tên NEXT_PUBLIC_. Có những key vốn được thiết kế để nằm ngoài đó, anon key của Supabase là một ví dụ. Nhưng service_role key, OpenAI key hay Stripe secret key thì không — mà một con AI được nhờ 'làm cho cái API này chạy đi' sẽ rất sẵn lòng đẩy key ra frontend cho hết lỗi.

    Kiểm tra thế nào: Mở site đã deploy, xem source, rồi tìm trong file JavaScript các chuỗi service_role, sk- và secret. Thứ gì bạn tìm thấy ở đó thì cả internet cũng có. Rotate key trước khi làm bất cứ việc gì khác: key đã lộ là lộ vĩnh viễn, xóa code nhanh tới đâu cũng vậy.

    Tham khảo: Supabase: các loại API key và quyền của từng loại

  2. Database của bạn có đang mở cho tất cả mọi người không?

    Supabase và Firebase khác thường ở đúng chỗ này: trình duyệt nói chuyện thẳng với database, không có server nào của bạn ở giữa. Đó là lý do chúng dựng đồ nhanh, và cũng có nghĩa là luật ai được đọc dòng nào buộc phải nằm trong chính database. Ở Supabase, đó là row-level security. Một bảng tắt RLS cộng với anon key công khai là một bảng ai cũng tải về nguyên vẹn được — không cần hacker, chỉ cần tò mò và tab Network.

    Kiểm tra thế nào: Vào dashboard Supabase, mở table editor và tìm những bảng đang tắt RLS. Sau đó đăng xuất khỏi chính app của bạn rồi thử gọi lấy dữ liệu bảng đó xem. Nếu vẫn có dữ liệu trả về trong khi không ai đăng nhập, thì đó là cả bảng, cho bất kỳ ai.

    Tham khảo: Supabase: row level security

  3. Server có kiểm tra người gửi request là ai không?

    Ẩn một cái nút đi không phải là kiểm tra quyền. Rất hay gặp cảnh luật nằm ở giao diện — nút xóa chỉ hiện với admin — trong khi request phía sau thì ai gửi cũng nhận. Giao diện chỉ là gợi ý. Chỉ server hoặc database mới thật sự chặn được, và code do AI sinh ra thường viết phần gợi ý rồi bỏ qua phần chặn.

    Kiểm tra thế nào: Đăng nhập bằng một tài khoản thường rồi đổi một định danh: một con số trên URL, một trường trong request. Thử đọc hoặc sửa thứ thuộc về tài khoản khác. Nếu làm được thì chỗ đó chưa từng có kiểm tra. OWASP xếp đây là rủi ro số một của ứng dụng web từ năm 2021, và đây cũng là lỗi nghiêm trọng chúng tôi gặp nhiều nhất.

    Tham khảo: OWASP Top 10: broken access control

  4. Bạn có đang giữ nhiều hơn mức cần không?

    Mỗi trường dữ liệu bạn lưu là một thứ bạn sẽ phải giải thích nếu nó lộ ra. Số điện thoại, địa chỉ, ngày sinh, giấy tờ người dùng tải lên — thu thập thì dễ vì form builder làm sẵn, mà giữ thì phiền. Riêng mật khẩu thì bạn không nên lưu chút nào: đó là việc của nhà cung cấp auth, và nếu bảng của bạn có cột password thì có gì đó đã sai từ trước.

    Kiểm tra thế nào: Liệt kê hết các cột bạn lưu về một con người. Bên cạnh mỗi cột, ghi lý do bạn cần nó và chuyện gì xảy ra nếu nó lên internet. Xóa những cột trượt cả hai câu. Đây là mục duy nhất trong danh sách càng làm sớm càng nhẹ.

  5. App hỏng thì chuyện gì xảy ra?

    App sẽ hỏng. Vấn đề chỉ là bạn biết trước qua log, hay biết sau qua người dùng. Code do AI sinh ra có thói quen bắt lỗi, hiện một câu thông báo dễ chịu rồi vứt luôn nguyên nhân thật — dễ chịu cho tới buổi sáng thanh toán ngừng chạy và không còn gì để đọc.

    Kiểm tra thế nào: Cố tình làm hỏng một thứ trên bản sao của app: thu hồi key của một dịch vụ bên thứ ba, hoặc trỏ vào một database không tồn tại. Rồi nhìn hai điều. App có nói với người dùng một câu tử tế thay vì hiện màn hình trắng không, và ở đâu đó có ghi lại đúng chuyện gì đã hỏng không?

    Tham khảo: OWASP: nên log cái gì và không nên log cái gì

  6. Năm mươi người vào cùng lúc thì sao?

    Chạy được với bạn nghĩa là một người, đường truyền tốt, database gần như rỗng. Sập ngày launch thường rơi vào một trong ba thứ: một câu query chạy một lần cho mỗi dòng thay vì chạy một lần, một bảng không có index vốn vẫn ổn ở mức 200 dòng, hoặc một gói miễn phí dừng ở giới hạn kết nối mà chưa ai đọc tới.

    Kiểm tra thế nào: Đổ vào bản sao database một lượng dữ liệu thật — vài nghìn dòng, không phải năm dòng — rồi bấm thử quanh app. Cái gì chậm bây giờ thì ra ngoài sẽ chậm hơn. Nhân tiện, tra luôn giới hạn thật của gói bạn đang dùng.

  7. Bạn có quay lại được không?

    Ngày launch tệ nhất không phải ngày lộ lỗ hổng bảo mật. Là ngày một migration chạy nhầm môi trường và không có đường lùi. Backup ở gói miễn phí thường lùi được ít hơn nhiều người tưởng, còn một bản backup chưa ai từng restore thì mới là giả thuyết, chưa phải backup.

    Kiểm tra thế nào: Xem backup của bạn thật sự lùi được tới đâu, rồi restore thử một bản sang project nháp xem nó có lên được không. Làm tương tự với bản deploy: biết cách đưa phiên bản hôm qua trở lại, trước khi đó là thứ bạn cần gấp.

    Tham khảo: Supabase: backup và mức lùi của từng gói

Vậy rốt cuộc, an toàn chưa?

Không trang nào trả lời thay app của bạn được, và ai bán cho bạn một dấu tích xanh thì thứ họ bán chính là cái dấu tích. Việc của danh sách này là tách hai loại rủi ro ra. Ba mục đầu — key, row-level security, kiểm tra quyền — là loại kết thúc bằng việc dữ liệu người dùng nằm trong tay người khác, và nên sửa trước khi launch chứ không phải sau. Phần còn lại thì trả giá bằng một cuối tuần vất vả. Không mục nào đòi bạn có nền bảo mật. Chỉ đòi một buổi chiều.

Đây là hướng dẫn chung, viết ra từ những lần review chúng tôi làm. Nó không phải một cuộc audit cho app của bạn, không bao quát hết mọi thứ, và stack của bạn cụ thể ra sao vẫn rất quan trọng.

Muốn có thêm một cặp mắt nữa nhìn giúp?

Chúng tôi là hai kỹ sư phần mềm, làm việc này miễn phí, nói bằng ngôn ngữ dễ hiểu, cho những người đang làm sản phẩm bằng công cụ AI. Gửi cho chúng tôi thứ bạn đang làm, rồi cùng đi qua danh sách này — chỉ xem read-only, không tính phí, cuối buổi không chào bán gì cả.

Kể cho chúng tôi về dự án của bạn