Skip to main content
Hậu trường
Hậu trườngSecurityPremium

Cuộc kiểm tra hệ thống thanh toán của chính chúng tôi đã phát hiện ra điều gì

Hai phát hiện nghiêm trọng, và không cái nào nằm ở chỗ chúng tôi sẽ tìm. Một báo cáo công khai về những sai sót đã được khắc phục.

Đăng ngày bởi AlphaCloud6 phút đọc

Vào tháng 8 năm 2026, chúng tôi rà soát hệ thống thanh toán của mình từ gốc. Không phải vì đã có chuyện gì xảy ra, mà vì nó vừa đi vào hoạt động không lâu trước đó và chúng tôi muốn biết mình đã bỏ sót những gì.

Chúng tôi đã bỏ sót khá nhiều. Bài viết này nêu tên các phát hiện. Mọi thứ được mô tả ở đây đều đã được khắc phục, và phần lớn vốn đã có trong nhật ký thay đổi công khai.

Lỗi mô hình hóa sinh ra cả hai phát hiện nghiêm trọng

Khi ai đó mua Premium của chúng tôi, một hồ sơ khách hàng được tạo tại nhà cung cấp dịch vụ thanh toán. Chúng tôi đã lưu hồ sơ đó theo ID máy chủ, vì dù sao Premium cũng rơi vào một máy chủ.

Đó chính xác là mô hình sai, và nó là gốc rễ của hai phát hiện nghiêm trọng nhất.

Một hồ sơ khách hàng thuộc về một người mua. Nó mang phương thức thanh toán của họ, lịch sử hóa đơn của họ và, ngay khi ai đó trả tiền cho hai máy chủ, nhiều gói đăng ký. Dùng ID máy chủ làm khóa nghĩa là nhiều người cùng trỏ vào một dòng dữ liệu.

Phát hiện 1: Dữ liệu khách hàng của người khác, có thể ghi đè mà không cần trả tiền

Bất kỳ thành viên nào của một máy chủ cũng có thể mua, và hàm lấy hoặc tạo hồ sơ khách hàng chạy trước khi thanh toán. Nó tìm dòng dữ liệu theo ID máy chủ và lặng lẽ ghi đè nó sang người mua tiềm năng mới, bao gồm cả địa chỉ email của họ tại nhà cung cấp dịch vụ thanh toán.

Trên thực tế điều đó có nghĩa là: chỉ một cú nhấp trên một máy chủ mà từng có người mua là đủ. Sau đó, hóa đơn của mọi gói đăng ký của người mua ban đầu đó sẽ được gửi đến địa chỉ email của người lạ. Không thanh toán, không xác nhận.

Đã khắc phục bằng cách kiểm tra, trước mọi lần dùng lại, xem hồ sơ có thực sự thuộc về tài khoản này không. Nếu không khớp, một hồ sơ riêng sẽ được tạo và hồ sơ kia được để nguyên.

Phát hiện 2: Cổng thanh toán để lộ gói đăng ký của người khác

Cùng lỗi mô hình hóa đó, sâu thêm một tầng. Bước kiểm tra quyền sở hữu áp dụng cho gói đăng ký của máy chủ, nhưng phiên cổng thanh toán lại được mở cho hồ sơ khách hàng, thứ mà theo thiết kế có thể mang nhiều máy chủ.

Vì vậy, bất kỳ ai mua hợp lệ trên một máy chủ đều có thể xem và quản lý các gói đăng ký mà cùng hồ sơ đó mang cho các máy chủ khác.

Đã khắc phục bằng cách xác định hồ sơ khách hàng từ giao dịch mua cụ thể thay vì từ dòng dữ liệu của máy chủ.

Hai phát hiện mà mã nguồn mâu thuẫn với chính điều khoản của chúng tôi

Đây là loại khiến chúng tôi khó chịu nhất, vì nó không mang tính kỹ thuật.

Danh sách đen lấy mất thời gian đã trả tiền. Điều khoản của chúng tôi nói một gói đăng ký kết thúc vào cuối kỳ hạn hiện tại. Nhưng khi chặn một máy chủ, mã nguồn lại yêu cầu hủy ngay lập tức: không hoàn tiền, và không có dịch vụ kể từ thời điểm đó cho một khoảng thời gian đã được trả tiền. Mã nguồn làm một việc khác với những gì chúng tôi đã cam kết bằng văn bản. Giờ thì kỳ hạn đã trả tiền sẽ chạy hết.

Việc từ bỏ quyền rút lại hợp đồng không chứng minh được. Trước khi mua, bạn phải xác nhận rằng dịch vụ bắt đầu ngay lập tức. Xác nhận đó chỉ tồn tại trong trình duyệt, chưa bao giờ được gửi đi và chưa bao giờ được lưu ở đâu cả. Nghĩa vụ chứng minh thuộc về chúng tôi, và chúng tôi đơn giản là không có bằng chứng. Giờ sự đồng ý là một trường bắt buộc của luồng thanh toán, được lưu kèm dấu thời gian và nội dung có đánh phiên bản, và chính nội dung đó được quản lý theo phiên bản: một văn bản hiện có không bao giờ bị sửa, luôn tạo một phiên bản mới, nếu không các bản ghi cũ sẽ không còn tái hiện được.

Vòng thứ hai còn tệ hơn vòng đầu

Sau 21 phát hiện đầu tiên, vài tuần sau chúng tôi xem xét lại. Đó là quyết định đúng, vì phát hiện nghiêm trọng nhất chỉ lộ ra lúc đó.

Một lần hoàn tiền trên máy chủ B đã xóa giấy phép trọn đời đã trả tiền của máy chủ A. Thông báo hoàn tiền và bồi hoàn chỉ nêu một khoản thanh toán, không nêu máy chủ. Chúng tôi xác định chúng thông qua hồ sơ khách hàng. Sau khi ở vòng một đã xác lập đúng rằng một hồ sơ thuộc về một người mua trên nhiều máy chủ, chính cách xác định đó không còn rõ ràng nữa. Một người đã trả tiền cho hai máy chủ và nhận hoàn tiền cho một máy chủ có thể mất giấy phép trọn đời của máy chủ còn lại.

Giờ việc xác định đi qua bốn bước chính xác, và bất cứ thứ gì không thể xác định rõ ràng sẽ được báo cáo thay vì đoán.

Thắng một vụ bồi hoàn cũng không khôi phục được gì. Khi có bồi hoàn, mã nguồn xóa dòng dữ liệu giao dịch mua, bằng chứng duy nhất cho thấy máy chủ này từng có giấy phép trọn đời. Thắng vụ việc sau đó cũng không thể đảo ngược. Giờ nó đánh dấu thay vì xóa.

Chính sách lưu giữ dữ liệu xóa luôn máy chủ đã trả tiền. Khi bot rời một máy chủ, dữ liệu của máy chủ đó bị xóa sau 30 ngày. Việc dọn dẹp đó chưa bao giờ hỏi xem có gói đăng ký nào đang chạy gắn với máy chủ hay không.

Điều chúng tôi rút ra

Lỗi không nằm trong mã thanh toán. Không một phát hiện nghiêm trọng nào liên quan đến số tiền, đơn vị tiền tệ hay phép tính. Tất cả đều nằm trong mô hình phía sau: ai sở hữu một hồ sơ khách hàng, ai sở hữu một khoản thanh toán, ai sở hữu một máy chủ. Ai kiểm tra một hệ thống thanh toán bằng cách nhìn vào số tiền là đang nhìn ra xa khỏi phần nguy hiểm.

Một cuộc kiểm tra cần vòng thứ hai. Phát hiện nghiêm trọng nhất là hệ quả trực tiếp của một bản sửa từ vòng đầu. Đó không phải ngẫu nhiên: sửa một mô hình sẽ làm mất hiệu lực những giả định vẫn còn đúng ở chỗ khác.

"Điều khoản của chúng tôi nói vậy" là một câu có thể kiểm chứng. Hai phát hiện là sự sai lệch giữa những gì chúng tôi đã cam kết bằng văn bản và những gì mã nguồn làm. Điều đó đọc được, và chẳng ai làm, vì nó trông giống luật hơn là kỹ thuật.

Toàn bộ điều khoản mua hàng có trong điều khoản dịch vụ của chúng tôi, quyền rút lại hợp đồng có tại rút lại hợp đồng.

Bài viết khác