Think Like a Developer #11: Data Thinking - "Muốn build app? Hãy nghĩ như kẻ phá app"
Bạn vừa build xong app.
Login chạy.
Upload ảnh chạy.
Form submit được.
Payment sandbox pass.
AI code nhanh đến mức bạn cảm thấy mình như có superpower.
Bạn nhìn app, click vài vòng, thấy mọi thứ ổn.
Rồi câu quen thuộc xuất hiện:
"Ship thôi."
Developer thì ở đúng khoảnh khắc đó lại bắt đầu thấy lo.
Vì họ biết một sự thật rất khó chịu:
App chạy đúng không có nghĩa là app an toàn.
Đây là một trong những khác biệt lớn nhất giữa người build prototype và người build sản phẩm thật.
Người mới hỏi:
"Nó có chạy không?"
Developer hỏi:
"Nó có bị phá được không?"
Và đó chính là Security Thinking.
Happy Path là cái bẫy lớn nhất
AI cực kỳ giỏi build happy path.
Bạn nói:
"Làm login form."
AI làm login form.
Bạn nói:
"Thêm upload avatar."
AI thêm upload avatar.
Bạn nói:
"Cho user reset password."
AI thêm reset password flow.
Nhìn rất thuyết phục.
Vấn đề là:
AI thường optimize cho scenario mà bạn mô tả.
Tức là:
người dùng tốt
hành vi hợp lý
input đúng
flow đẹp
Ví dụ login:
User nhập email đúng
Password đúng
Click login một lần
Session hoạt động
Tuyệt.
Nhưng internet không chỉ có user như vậy.
Internet có:
bot brute force password
script spam request
người tò mò mở DevTools
attacker sửa payload
crawler quét endpoint tự động
kẻ copy exploit từ GitHub
Happy path chỉ là 10% câu chuyện.
90% còn lại là:
"Nếu có ai cố tình phá thì sao?"
Ví dụ thật: Upload avatar tưởng đơn giản
Tính năng:
"Cho user upload avatar."
Nghe dễ đúng không?
AI build xong trong vài phút.
Test:
Bạn upload file JPG 300KB.
Pass.
Ship?
Khoan.
Hãy nhìn như attacker.
Case 1 — File cực lớn
User upload ảnh 50MB.
Điều gì xảy ra?
Có thể:
server load file vào RAM
memory spike
request timeout
worker bị block
user khác lag theo
Bạn chỉ nghĩ:
"upload ảnh"
Attacker nghĩ:
"mình có thể làm server choke không?"
Case 2 — Path traversal
User đổi tên file thành:
../../../.env
Nếu code xử lý file path kém:
save(uploadDir + filename)
thì sao?
File có thể ghi đè nơi không nên ghi.
Worst case:
config bị overwrite
secrets bị lộ
system file bị ảnh hưởng
Case 3 — Fake file type
Tên file:
avatar.jpg
Nhưng nội dung thực tế:
HTML hoặc JavaScript độc hại.
Nếu app chỉ check extension ".jpg" thì attacker cười.
Case 4 — Spam concurrent upload
Một user gửi 100 request cùng lúc.
Nếu không có:
rate limit
queue
concurrency control
thì chúc may mắn.
Case 5 — Metadata leak
Ảnh điện thoại thường chứa EXIF:
GPS
device model
timestamp
Nếu bạn serve raw file:
user vô tình leak location.
Case 6 — API bypass
Frontend có validation:
"chỉ cho upload JPG dưới 5MB"
Attacker mở DevTools.
Gọi API trực tiếp.
Validation frontend biến mất.
Nếu backend không check lại?
Game over.
Một tính năng.
Rất nhiều cách fail.
Đây là Security Thinking.
Security không phải paranoia. Nó là realism.
Người mới đôi khi nghĩ:
"Mình app nhỏ thôi, ai thèm hack."
Sai mindset.
Phần lớn attack không phải vì bạn nổi tiếng.
Nó là automation.
Bot không quan tâm bạn là startup tỷ đô hay side project cuối tuần.
Nó scan:
open ports
exposed admin panels
leaked API keys
vulnerable packages
predictable endpoints
Bạn chỉ là một IP khác trong danh sách.
Sai lầm lớn nhất của vibe coding
AI làm việc kiểu này:
Bạn mô tả nhiệm vụ → AI hoàn thành nhiệm vụ.
Nếu prompt là:
"Build user login."
AI hiểu:
"Implement feature."
Không tự hiểu:
"Think adversarially."
Không mặc định nghĩ tới:
brute force
token expiry
replay attack
session hijacking
CSRF
privilege escalation
API key leakage
Không phải AI dở.
Mà vì bạn chưa yêu cầu đúng mindset.
Developer có một assumption khác
Developer assume:
user sẽ phá.
Không phải ghét user.
Mà vì internet dạy họ như vậy.
Ví dụ payment endpoint.
Người mới nghĩ:
"Frontend chỉ show nút thanh toán cho đúng user."
Developer nghĩ:
"Ẩn nút không phải security."
Vì attacker có thể gọi API trực tiếp.
Frontend không phải firewall.
Browser không phải trusted environment.
Những câu hỏi developer luôn hỏi
Authentication
Ai được vào?
Token lưu ở đâu?
Session sống bao lâu?
Logout có invalidate token không?
Authorization
Authentication là:
"Bạn là ai?"
Authorization là:
"Bạn được làm gì?"
Ví dụ:
User sửa request payload thành:
role = admin
Backend có check không?
Input validation
Không tin input nào từ client.
Không phải:
"Form mình có validation rồi."
Mà:
"Backend verify lại chưa?"
Rate limiting
Nếu endpoint bị gọi:
1000 lần/phút?
10,000 lần/phút?
Có throttle không?
Secret management
API key nằm đâu?
Nếu frontend chứa:
OPENAI_KEY = ...
thì coi như donate tiền.
Error handling
Production error:
Database connection failed
Stack trace
Internal config path
Attacker thích điều này.
Checklist bảo mật tối thiểu cho người vibe code
Không cần thành security engineer.
Chỉ cần checklist cơ bản.
1. Không bao giờ trust frontend
Frontend chỉ để UX.
Security phải enforce ở backend.
2. Không expose secrets
Không để:
API keys
DB passwords
service tokens
ở:
frontend bundle
GitHub repo
config public
3. Validate tất cả input
Check:
type
length
format
allowed values
Email phải là email.
Không phải chuỗi 5000 ký tự random.
4. Rate limit endpoint quan trọng
Đặc biệt:
login
password reset
upload
AI generation
payment
5. Permission check server-side
Không dựa vào:
"frontend không show nút"
Backend phải verify.
6. File upload paranoia
Check:
mime type
size
filename sanitization
storage isolation
metadata stripping
7. Generic error messages
Đừng leak internal details.
User chỉ cần:
"Something went wrong."
Không cần stack trace.
Prompt AI đúng kiểu security
Thay vì:
"Build login feature."
Hãy thử:
Build login feature. Think like a security engineer. Include brute force protection, secure session handling, backend validation, token expiry, and explain attack vectors this design prevents.
Hoặc:
Review this code like an attacker. Find security vulnerabilities, abuse paths, privilege escalation risks, and secret leaks.
Prompt khác.
Output khác.
Tư duy quan trọng nhất
Security không phải thứ thêm vào cuối.
Không phải:
"Ship xong rồi fix sau."
Vì fix security late thường cực đau.
Ví dụ:
Permissions model thiết kế sai.
Muốn sửa?
Có thể rewrite cả auth layer.
Kỷ nguyên AI làm chuyện này nguy hiểm hơn
Ngày xưa build app chậm.
Lỗ hổng sinh ra chậm.
Giờ AI giúp ship nhanh.
Lỗ hổng cũng ship nhanh.
Rất nhiều người lần đầu build app production vì AI.
Nhưng production không giống demo.
Demo cần:
"nó chạy"
Production cần:
"nó không bị abuse"
Kết luận
Think Like a Developer không phải học syntax.
Mà học mindset.
Và một mindset cực quan trọng là:
đừng chỉ nghĩ như builder.
Hãy nghĩ như attacker.
Không phải để trở nên paranoid.
Mà để build thứ sống sót ngoài đời thật.
Vì internet không chỉ có người tốt.
Và app của bạn rồi sẽ gặp người xấu.
Câu hỏi chỉ là:
bạn chuẩn bị trước chưa?