DIY Pen Testing: How to Test Your Own App
The Call That Changed How I Think About Shipping
A friend of mine -- a talented designer who'd used AI tools to build a SaaS product for freelance photographers -- got a message from a stranger last spring. The message contained the email address, subscription tier, and invoice history of twenty of her customers. The stranger wasn't threatening her. He was a security researcher doing bug bounty work, and he'd found an IDOR vulnerability in her API in about four minutes.
She had never heard the word "IDOR" before that day.
She hadn't done anything reckless. She'd used a reputable AI coding assistant, followed tutorials, and deployed on a modern platform. But nobody had told her to test her own app before shipping it -- and she found out the hard way that her AI assistant had written perfectly functional code that was also perfectly exploitable.
This article is about making sure that doesn't happen to you.
Why You Should Test Your Own App First
Professional attackers are patient, methodical, and free. They have automated tools that scan thousands of applications per hour looking for the same handful of vulnerabilities. According to Recorded Future's H1 2025 threat report, Cross-Site Scripting (XSS) and SQL Injection remain the most common web vulnerability types -- the same issues that have been exploitable for two decades. Nearly 69% of actively exploited vulnerabilities in the first half of 2025 required no authentication at all.
The good news: if those are the common patterns, you can test for them yourself. You do not need a $15,000 security assessment to find the low-hanging fruit. You need 30 minutes and a few free tools.
There is one rule before we begin: only test applications you own or have explicit written permission to test. Running these tools against someone else's app -- even out of curiosity -- is illegal under the Computer Fraud and Abuse Act and equivalent laws worldwide. Every tool we cover includes this warning. Take it seriously.
Automated Scanning vs. Manual Testing
Think of automated scanning as a metal detector at the airport -- it finds obvious things fast and at scale. Manual testing is the security officer doing a targeted search because something looked suspicious. You want both.
Automated scanners like OWASP ZAP and Nuclei crawl your application, send crafted payloads, and flag known vulnerability patterns. They are excellent at finding misconfigured headers, exposed admin panels, and common injection points.
Manual testing is you thinking like an attacker: What happens if I change this number in the URL? What if I skip the login page entirely and go directly to /dashboard? What if I upload a .php file instead of a .jpg?
Automated tools catch the patterns. Manual testing catches the logic flaws. You need both.
Your Free Toolkit
1. OWASP ZAP (Zed Attack Proxy)
ZAP is the gold standard for beginner-friendly web application scanning. It is free, open source, and maintained by OWASP. According to OWASP's own getting-started guide, you can run a Quick Start Automated Scan by entering your app's URL and clicking "Attack" -- ZAP will spider your application and passively and actively scan every page it finds.
Download it at zaproxy.org, point it at your staging environment (never production for active scans), and let it run. The Alerts tab will show you findings ranked by severity: High, Medium, Low, and Informational. Start with the High alerts.
2. Nuclei
Nuclei, developed by ProjectDiscovery, is a template-based scanner with over 9,000 community-written detection templates covering CVEs, misconfigurations, exposed credentials, and IDOR patterns. It was recognized at RSAC 2025 as a standout open-source security tool. Install it with:
# Install via Go
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
# Run against your app
nuclei -u https://your-staging-app.com -t exposures/ -t misconfiguration/
The exposures/ template set is particularly useful for finding accidentally exposed API keys, .env files, and debug endpoints.
3. Browser DevTools
You already have this. Open your app in Chrome or Firefox, hit F12, and check:
- Network tab: Look at response headers. You want to see
Strict-Transport-Security,Content-Security-Policy,X-Frame-Options, andX-Content-Type-Options. Missing headers are flagged by SoftwareMill's OWASP Top 10 2025 audit of vibe-coded apps as one of the most common oversights in AI-assisted development. - Console tab: Any warnings about mixed content (loading HTTP resources on an HTTPS page)?
- Application tab: Are there API keys or secrets visible in
localStorageor cookies?
4. curl / httpie
These command-line tools let you poke at your API endpoints directly, without a browser hiding anything from you.
# Check your security headers
curl -I https://your-app.com
# Test an API endpoint without auth (should return 401)
curl https://your-app.com/api/users/me
# Test an authenticated endpoint with someone else's ID
curl -H "Authorization: Bearer YOUR_TOKEN" https://your-app.com/api/orders/1001
The 30-Minute Security Audit Workflow
Set a timer. Work through these in order.
1. Check your response headers (5 min)
Run curl -I https://your-staging-app.com and look at what comes back. You want Strict-Transport-Security, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, and a Content-Security-Policy header. If they are missing, ask your AI assistant to add them to your server configuration.
2. Test authentication bypass (5 min)
Copy a URL that should require login -- like /dashboard or /settings -- and paste it into a private/incognito window where you are not logged in. Does it redirect to login, or does it show the page anyway? Try this for every protected route.
3. Test authorization (IDOR) (10 min)
This is the test my designer friend's app failed. Log in as a normal user. Find any URL or API call that contains a numeric ID -- like /api/orders/1042 or /profile?user_id=55. Change that number. Try incrementing it, decrementing it, trying a random large number. Does the app return someone else's data, or does it return a 403 Forbidden?
According to Huntress's threat library, a recent IDOR in IBM InfoSphere (CVE-2025-14974) allowed unauthenticated attackers to access sensitive data simply by manipulating object identifiers. The pattern is ancient, but it keeps appearing in new code because authorization checks are easy to forget.
4. Check for exposed environment variables and debug endpoints (5 min)
Try browsing to /.env, /config.json, /api/debug, /api/test, and /.git/config on your app. These should all return 404. If any of them return content, you have a serious exposure.
5. Test file upload functionality (5 min)
If your app accepts file uploads, try uploading a .html file, a .svg file containing a script tag, and a file with a double extension like photo.jpg.php. Your app should reject file types that are not explicitly on your allowlist and should never execute uploaded files.
6. Review your Supabase Row-Level Security (RLS) policies If you are using Supabase, open your Supabase dashboard, go to Authentication > Policies, and verify that every table has RLS enabled. A table with RLS disabled is accessible to anyone with your anon key. Ask your AI assistant: "Review my Supabase schema and tell me which tables might be missing row-level security policies."
When to Hire a Professional
DIY testing is a first line of defense, not a complete substitute for professional review. You should bring in a professional penetration tester when:
- Your app handles payments, health data, or any regulated personal information
- You are about to launch to a large user base for the first time
- You have had a security incident and need to understand its full scope
- A customer or enterprise contract requires a third-party security assessment
Professional testers bring creativity, specialized tooling, and the ability to chain multiple small findings into a full compromise path -- something automated tools consistently miss.
Summary Checklist
Before you ship, run through this list:
- Run OWASP ZAP against your staging environment and address all High severity findings
- Run Nuclei with the
exposures/andmisconfiguration/template sets - Verify security response headers are present (
HSTS,CSP,X-Frame-Options,X-Content-Type-Options) - Confirm every protected route redirects to login when accessed without a session
- Test at least five numeric IDs in API calls for IDOR vulnerabilities
- Browse to
/.env,/api/debug, and/.git/configand confirm all return 404 - Test file upload endpoints with unexpected file types
- Confirm all Supabase tables have RLS policies enabled
- Never test any application you do not own or have written permission to test
Ask The Guild
Have you run any of these tests on your own app? What did you find -- and what was hardest to fix? Share your experience in the community forum. If you discovered a vulnerability you were not sure how to remediate, post the details (with sensitive information removed) and let the Guild help you work through it.