Skip to content

Embedded NUL Bytes Are Silently Truncated in Multiple std and os APIs #1559

Description

@kid-lxy

QuickJS accepts JavaScript strings containing embedded NUL bytes in several std and os APIs and passes them to NUL-terminated C/POSIX interfaces without rejecting the embedded NUL.

As a result, the underlying operation is performed using only the prefix before the first \0, while the JavaScript caller sees and may validate the complete string.

The issue has been reproduced in at least the following APIs:

  • std.open
  • os.mkdir
  • os.rename
  • os.symlink
  • os.exec

This may allow a caller to bypass JavaScript-side path or executable-name validation and cause an operation on a different path or executable from the one represented by the original JavaScript string.

Reproducer example: std.open

var stamp = String(Date.now()) + "_" + String((Math.random() * 0x100000000) >>> 0);
var realPath = "/tmp/qjs_null_std_open_" + stamp;
var badPath = realPath + "\x00/malicious";
var vuln = false;

try {
    os.remove(realPath);
} catch (e) {}

try {
    var f = std.open(badPath, "w");
    if (f) {
        f.close();
    }
} catch (e) {}

try {
    var rf = std.open(realPath, "r");
    if (rf) {
        vuln = true;
        rf.close();
    }
} catch (e) {}

try {
    os.remove(realPath);
} catch (e) {}

if (vuln) {
    std.err.puts("VULNERABLE: std.open truncated path at NUL and created " + realPath + "\n");
    std.exit(99);
}

Run:

qjs --std std_open_null_injection.js
echo $?

Observed output:

VULNERABLE: std.open truncated path at NUL and created /tmp/qjs_null_std_open_...

The process exits with status 99 after confirming that the truncated path was created.

QuickJS version

QuickJS version/release: v0.15.1
Git commit: 93d3f7d
Operating system: Ubuntu 24.04 x86_64

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions