Hey dev community! I’m ethicals7s, a self-taught hacker grinding from zero—no mentors, just raw determination after losing my parents young. In a few intense days, I designed, coded, and shipped my first ethical open redirect vulnerability scanner in Node.js. This tool isn’t just basic—it’s optimized with async parallel scans, rate limiting for responsible testing, and JSON export for pro-level logging, making it faster and more robust than my earlier Python attempts. Here’s the full breakdown: my journey, the tech behind it, and how you can dive in.
The Journey
As someone building my way up in tech, I wanted a tool to automate bug bounty hunts for open redirects—those sneaky params that can lead to phishing or worse. I started with research on OWASP guidelines, sketched the logic (payload injection, HTTP status checks), and coded it step by step. Debugging async issues and adding ethics (like delays to avoid DoS) was the real grind, but it taught me tons about full-stack security. This is my unconventional route to senior-level skills—turning challenges into code that matters.
Features
Batch testing: Reads URLs from a text file for efficient scans.
Payload injection: Appends ?redirect=https://evil.com to detect vulnerable redirects.
Async parallelism: Uses Promise.all for simultaneous checks—blazing fast on multiple URLs.
Rate limiting: Built-in 1-second delay per scan to prevent abuse and stay ethical.
JSON export: Saves results as structured data for analysis or reports.
Ethical focus: Designed for permitted testing only, with safe examples and warnings.
Install
Get the dependencies with npm:
npm install axios yargs
Usage
Create urls.txt with one URL per line (safe tests only—e.g., known redirect mimics):texthttps://www.google.com/url?q=https://evil.com
https://example.com
https://www.koni-store.ru/bitrix/redirect.php?event1=&event2=&event3=&goto=https://google.com
Run the scanner:node index.js scan
Example Output
Scanning for open redirects (ethical tests only)…
https://www.google.com/url?q=https://evil.com is VULNERABLE.
https://example.com is SAFE.
https://www.koni-store.ru/bitrix/redirect.php?event1=&event2=&event3=&goto=https://google.com is VULNERABLE.
results.json (auto-generated):
text[
{
“url”: “https://www.google.com/url?q=https://evil.com“,
“status”: “VULNERABLE”
},
{
“url”: “https://example.com“,
“status”: “SAFE”
},
{
“url”: “https://www.koni-store.ru/bitrix/redirect.php?event1=&event2=&event3=&goto=https://google.com“,
“status”: “VULNERABLE”
}
]
Code Snippet (index.js)
Here’s the core—clean, efficient, and ready to fork:
JavaScriptconst fs = require(‘fs’);
const axios = require(‘axios’);
const path = require(‘path’);
const yargs = require(‘yargs’);
const MALICIOUS_DOMAIN = ‘evil.com’;
const INPUT_FILE = path.join(__dirname, ‘urls.txt’);
async function checkForOpenRedirect(url) {
try {
const testUrl = ${url}?redirect=https://${MALICIOUS_DOMAIN};
const response = await axios.get(testUrl, { maxRedirects: 0, validateStatus: null });
if (response.status > 300 && response.status < 400) {
const location = response.headers.location;
if (location && location.includes(MALICIOUS_DOMAIN)) {
return true;
}
}
return false;
} catch (error) {
console.error(Error checking ${url}: ${error.message});
return false;
}
}
async function main(file = INPUT_FILE) {
if (!fs.existsSync(file)) {
console.error(Input file not found: ${file});
console.log(‘Please create a urls.txt file with one URL per line. Use safe tests only.’);
return;
}
const urls = fs.readFileSync(file, ‘utf-8’).split(‘n’).filter(Boolean);
console.log(‘Scanning for open redirects (ethical tests only)…’);
const results = await Promise.all(urls.map(async (url) => {
const vulnerable = await checkForOpenRedirect(url);
await new Promise(resolve => setTimeout(resolve, 1000)); // Rate limit
return { url, status: vulnerable ? ‘VULNERABLE’ : ‘SAFE’ };
}));
results.forEach(({ url, status }) => console.log(${url} is ${status}.));
fs.writeFileSync(‘results.json’, JSON.stringify(results, null, 2)); // JSON export
}
// CLI
yargs.command(‘scan’, ‘Scan for open redirects’, {
file: { description: ‘Input file’, alias: ‘f’, type: ‘string’, default: ‘urls.txt’ }
}, (argv) => main(argv.file))
.help()
.argv;
Notes
Ethical Use Only: Permission-based testing only. Inspired by bug bounties—report responsibly. No production scans without consent.
License: MIT—fork it on GitHub: https://github.com/ethicals7s/ethicals7s-redirect-hunter
What do you think? Fork, test, or suggest improvements—let’s collab! Next: Fraud detector or cert grind. Feedback welcome!
