5465 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / index-fixed.js JS
const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const vm = require('vm');

if (!fs.existsSync('./lib/WebAudioRecorder.js')) {
    console.error('WebAudioRecorder.js not found. Please run "npm run setup" to download the library.');
    process.exit(1);
}

global.window = {};
global.window.Worker = function() { return { postMessage: () => {}, terminate: () => {} }; };
global.Worker = global.window.Worker;

vm.runInThisContext(fs.readFileSync('./lib/WebAudioRecorder.js', 'utf-8'));

const webAudioRecorder = global.window.WebAudioRecorder;
if (!webAudioRecorder) {
    console.error('Failed to load WebAudioRecorder.js. Please ensure the library is correctly downloaded.');
    process.exit(1);
}
console.log("Original WebAudioRecorder loaded successfully.");

const fakeNode = {
    context: {
        simpleRate: 44100,
        createGain: () => ({ connect: () => {} }),
        createScriptProcessor: () => ({ connect: () => {}, bufferSize: 4096 }), 
        destination: {}
    },
    connect: () => {}
};

const DANGEROUS_KEY = ['__proto__', 'constructor', 'prototype'];

function sanitize(obj) {
    if (typeof obj !== 'object' || obj === null) return obj;

    const clean = {};

    for (const key of Object.keys(obj)) {
        if (DANGEROUS_KEY.includes(key)) {
            console.warn(`Blocked Dangerous Keys: ${key}`)
            continue;
        }
        clean[key] = sanitize(obj[key]);
    }
    return clean;
}

const ALLOWED_ENCODINGS = ['wav', 'ogg', 'mp3'];

function buildSafeConfig(userConfig) {
    const safe = {};

    if (userConfig.numChannels) {
        safe.numchannels = parseInt(userConfig.numChannels);
    }
    if (userConfig.encoding && ALLOWED_ENCODINGS.includes(userConfig.encoding)) {
        safe.encoding = userConfig.encoding;
    }
    if (userConfig.workerDir && typeof userConfig.workerDir === 'string') {
        safe.workerDir = userConfig.workerDir;
    } 

    return safe;
}

const app = express();
app.use(bodyParser.json());

app.post('/api/audio/config', (req, res) => {
    // Handle audio configuration logic here
    console.log('Received audio config:', JSON.stringify(req.body, null, 2));

    const userConfig = req.body.config || {};

    const santizedConfig = sanitize(userConfig);
    console.log('After sanitize():', JSON.stringify(santizedConfig));

    const safeConfig = buildSafeConfig(santizedConfig);
    console.log('Safe config passed to constructor', JSON.stringify(safeConfig))

    try {
        new webAudioRecorder(fakeNode, safeConfig);
    } catch (error) {
        console.error('Error creating WebAudioRecorder instance:', error);
        return res.status(500).json({ status: 'error', message: 'Failed to initialize audio recorder.' });
    }

    const testObj = {};
    const polluted = testObj.polluted !== undefined;
    console.log('Pollution Check:', polluted, '| value:', testObj.polluted);

    // RCE Gadjet - executes if toString got polluted on Object.prototype
    if(({}).toString === 'pwned') {
        const { execSync } = require('child_process');
        const result = execSync('whoami').toString().trim();

        console.log('RCE Exploit Successful - Current User:', result);
        return res.json({ rce: result });
    }

    res.json({ status: 'success',
        polluted,
        pollutedValue: testObj.polluted,
        globalProtoPolluted: ({}.polluted !== undefined)
    });

});

app.listen(3000, () => {
    console.log('Server is running on http://localhost:3000');
});