Get in touch
or send us a question?
CONTACT

Silent và Incident với iOS

Mở đầu
Hôm nay, chúng ta cùng chia sẻ một case study thực tế về việc mã hóa token trong UserDefaults – một task tưởng chừng đơn giản nhưng đã gây ra incident trong production.
Case Study: Silent Push và KeyChain Accessibility
Bối cảnh
Team nhận được task security: mã hóa các tokens (accessToken, refreshToken…) đang được lưu plain text trong UserDefaults. Developer đã implement solution:

  • Sử dụng ChaChaPoly để mã hóa tokens
  • Lưu encrypted tokens vào UserDefaults với key mới
  • Lưu encryption key trong KeyChain với mode kSecAttrAccessibleWhenUnlocked

Solution này pass QA testing và được release. Disaster bắt đầu sau đó.

Incident
Triệu chứng: Hàng loạt users bị logout sau khi để app background một thời gian.
Root cause: Khi app ở background nhận silent push notification và cần gọi API, app không thể truy cập encryption key từ KeyChain (do device bị locked), dẫn đến không decrypt được accessToken → accessToken = nil → force logout.

Phân Tích Sâu Root Causes
1. Thiếu Hiểu Biết Về KeyChain Accessibility Modes
Đây là lỗi technical nghiêm trọng nhất. Developer không hiểu bản chất của các accessibility modes:
KeyChain Accessibility Modes và Impact

Best practice: Với data cần truy cập trong background (như encryption keys cho tokens), PHẢI sử dụng kSecAttrAccessibleAfterFirstUnlock hoặc tương đương.
2. Thiếu Kiến Thức Về App Lifecycle và Background Modes
Developer không nắm được đặc thù của dự án:
Background Execution Contexts

3. Code Review Không Hiệu Quả
Reviewer đã không catch được:

Sự không tương thích giữa accessibility mode và use case
Thiếu test coverage cho background scenarios
Không có handling cho decryption failure

Solutions và Best Practices
1. Correct Implementation

2. Migration Strategy (Quan Trọng!)

3. Comprehensive Testing Checklist

4. AI-Assisted Code Review Prompts

5. Code Review Guidelines Enhancement

Lessons Learned
1. Security Features Are Double-Edged Swords
Security improvements có thể tạo ra các lỗi nghiêm trọng nếu không được implement cẩn thận. Principle: Every security enhancement phải được test kỹ với ALL app execution contexts.
2. Documentation Is Not Enough
Đọc Apple documentation về KeyChain không đủ. Developer cần:

Hiểu bản chất của từng option
Biết khi nào option nào applicable
Test thực tế với device states khác nhau

3. Background Execution Is a Different World
Code chạy trong foreground và background là hai thế giới khác nhau. Never assume rằng code work trong foreground sẽ work trong background với device locked.
4. AI Can Help, But Needs Right Questions
AI tools (ChatGPT, GitHub Copilot…) có thể catch bugs, nhưng cần:

Provide đủ context (app background modes, use cases…)
Ask specific questions về edge cases
Don’t just accept code, ask about implications

5. Gradual Rollout for Security Changes
Security changes nên được rollout dần:

Beta testing với real users
Phased rollout (10% → 50% → 100%)
Monitoring và alerting sẵn sàng
Rollback plan rõ ràng

Action Items cho Team
Immediate Actions

Hotfix: Update accessibility mode sang kSecAttrAccessibleAfterFirstUnlock
Monitoring: Add logging cho decryption failures
Fallback: Implement graceful degradation thay vì force logout

Short-term (1-2 sprints)

Testing: Tạo device state test suite
Documentation: Document app background behaviors
Training: iOS background execution workshop cho team
CI/CD: Add automated tests cho background scenarios

Long-term (Quarterly)

Process: Update code review checklist
Knowledge: Regular security best practices sharing
Tools: Integrate AI code review vào workflow
Culture: Encourage “what if device locked?” thinking

Kết Luận
Incident này là bài học đắt giá về việc một implementation “an toàn” có thể trở thành disaster nếu không hiểu rõ iOS fundamentals. Key takeaways:

Context matters: Accessible mode phụ thuộc vào execution context
Test real scenarios: Đặc biệt các scenarios “khó xảy ra” như device locked
Fail gracefully: Security code PHẢI có proper error handling
Review carefully: Security changes cần extra scrutiny
Use tools wisely: AI có thể giúp, nhưng không thay thế critical thinking

Remember: Code that looks correct trong ideal conditions có thể fail spectacularly trong real-world conditions. Always ask: “What happens when device is locked?”