My First Ethical Open Redirect Scanner: From Zero to Shipped

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!

Leave a Reply