Pentest nói app tôi không an toàn

3 min read

Tôi từng nghĩ bảo mật là việc của mấy hệ thống ngân hàng hoặc app xử lý tiền.
App của tôi chỉ là một sản phẩm phục vụ người dùng thông thường, không thẻ tín dụng, không giao dịch tài chính — thì có gì mà không an toàn?

Cho đến ngày tôi nhận được file báo cáo pentest.

Gần 30 trang PDF.

Pentest không chỉ tìm bug – nó tìm thói quen xấu

Điều làm tôi sốc không phải là số lượng lỗi, mà là:

Hầu hết các lỗi đều đến từ những thứ tôi làm vì… tiện.

  • Lưu token để khỏi phải login lại
  • Cache API response cho app mượt hơn
  • Để client xử lý một phần logic cho nhanh

Tất cả đều “hợp lý” — cho đến khi nhìn từ góc độ attacker.

1. Insecure Local Storage – lỗi mà app mobile nào cũng từng dính

Pentest phát hiện gì?

  • Access token
  • Email
  • User ID

được lưu trong:

  • AsyncStorage (React Native)
  • Cache database trên iOS
  • SharedPreferences trên Android

Tất cả đều plain text.

“Nhưng user đâu có jailbreak?”

Pentest không quan tâm điều đó.
Họ chỉ cần khả năng, không cần xác suất cao.

  • Root / jailbreak
  • Backup iTunes
  • adb pull
    → Data nằm đó, đọc được.

Tôi đã fix như thế nào?

  • Tách data thành 3 nhóm:
    1. Sensitive: token, credential → Secure Storage
    2. Semi-sensitive: user profile → encrypt
    3. Public: config, UI state → cache bình thường
  • React Native:
    • Dùng react-native-encrypted-storage
  • Nguyên tắc mới:

Không có lý do gì để token nằm trong AsyncStorage

2. Cache – thứ giết bảo mật trong im lặng

Cache là con dao hai lưỡi.

Vấn đề pentest chỉ ra

  • Cache vẫn tồn tại sau khi logout
  • App mở lại vẫn đọc được data cũ
  • Một số API response chứa thông tin nhạy cảm

Về UX: ổn
Về security: thảm họa

Tôi đã thay đổi tư duy

  • Logout không còn là:
    • clear token
  • Mà là:
    • clear cache
    • reset persisted state
    • invalidate session backend

Nếu user logout mà data còn ở lại, thì logout chỉ là giả

3. Authentication không đủ – phải có Authorization

Một lỗi mà dev backend hay tự tin nhầm.

Trước đây

  • Check token hợp lệ
  • Tin rằng client gửi đúng ID

Pentest làm gì?

  • Dùng token hợp lệ
  • Gửi ID của user khác
  • Và… server trả data thật

Fix

  • Backend không bao giờ tin client
  • Mọi query đều gắn với request.user

Không còn:

get(id=xxx)

Mà là:

get(id=xxx, user=request.user)

Bài học:

Token chỉ chứng minh bạn là ai, không chứng minh bạn được phép làm gì

4. Obfuscation không phải phép màu

Tôi từng bật Proguard / R8 và nghĩ:

“OK, reverse chắc khó lắm rồi”

Pentest chứng minh điều ngược lại.

Họ vẫn:

  • Đọc được flow logic
  • Hiểu rule xử lý
  • Phát hiện hard-code

Tôi làm gì?

  • Đưa toàn bộ logic quan trọng về backend
  • Client chỉ còn:
    • hiển thị
    • gửi request
  • Không hard-code:
    • secret
    • rule đặc biệt
    • flag quan trọng

Client chỉ nên là người đưa thư, không phải người quyết định

5. File, video, binary – nơi bảo mật hay bị bỏ quên

Vấn đề

  • API trả URL trực tiếp
  • Không check quyền download
  • File có thể share tự do

Fix

  • API trả binary stream
  • Verify token trước khi trả
  • Token có expiry ngắn
  • Không public URL

Pentest comment một câu rất gắt:

“Any downloadable resource is data.”

6. Sau pentest, tôi mất gì và được gì?

Tôi mất:

  • Thời gian
  • Một ít performance
  • Code phức tạp hơn

Tôi được:

  • Tư duy bảo mật đúng
  • Kiến trúc sạch hơn
  • Ít phụ thuộc client
  • Và quan trọng nhất: yên tâm

Kết luận

Pentest không làm app tôi hoàn hảo.
Nhưng nó bóc trần những giả định sai lầm mà tôi tin suốt thời gian dài.

https://www.cloudflare.com/learning/security/glossary/what-is-penetration-testing

Avatar photo

Leave a Reply

Your email address will not be published. Required fields are marked *