VYPR
High severity7.5OSV Advisory· Published Sep 30, 2025· Updated Apr 15, 2026

CVE-2025-11149

CVE-2025-11149

Description

This affects all versions of the package node-static; all versions of the package @nubosoftware/node-static. The package fails to catch an exception when user input includes null bytes. This allows attackers to access http://host/%00 and crash the server.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
@nubosoftware/node-staticnpm
<= 0.7.11

Affected products

1

Patches

1
78879dc665f0

Merge commit '9c9389b30caa43c3e2c6f64d5adcad47780b2cde'

https://github.com/cloudhead/node-staticBrett ZamirMar 29, 2021via ghsa
2 files changed · +21 4
  • lib/node-static.js+12 4 modified
    @@ -12,6 +12,14 @@ const fs     = require('fs')
     // Current version
     const version = [0, 7, 9];
     
    +function tryStat(p, callback) {
    +    try {
    +        fs.stat(p, callback);
    +    } catch (e) {
    +        callback(e);
    +    }
    +}
    +
     const Server = function (root, options) {
         if (root && (typeof(root) === 'object')) { options = root; root = null }
     
    @@ -57,7 +65,7 @@ Server.prototype.serveDir = function (pathname, req, res, finish) {
         const htmlIndex = path.join(pathname, this.options.indexFile),
             that = this;
     
    -    fs.stat(htmlIndex, function (e, stat) {
    +    tryStat(htmlIndex, function (e, stat) {
             if (!e) {
                 const status = 200;
                 const headers = {};
    @@ -90,7 +98,7 @@ Server.prototype.serveFile = function (pathname, status, headers, req, res) {
     
         pathname = this.resolve(pathname);
     
    -    fs.stat(pathname, function (e, stat) {
    +    tryStat(pathname, function (e, stat) {
             if (e) {
                 return promise.emit('error', e);
             }
    @@ -145,7 +153,7 @@ Server.prototype.servePath = function (pathname, status, headers, req, res, fini
         // Make sure we're not trying to access a
         // file outside of the root.
         if (pathname.startsWith(that.root)) {
    -        fs.stat(pathname, function (e, stat) {
    +        tryStat(pathname, function (e, stat) {
                 if (e) {
                     finish(404, {});
                 } else if (stat.isFile()) {      // Stream a single file.
    @@ -216,7 +224,7 @@ Server.prototype.respondGzip = function (pathname, status, contentType, _headers
         const that = this;
         if (files.length == 1 && this.gzipOk(req, contentType)) {
             const gzFile = files[0] + ".gz";
    -        fs.stat(gzFile, function (e, gzStat) {
    +        tryStat(gzFile, function (e, gzStat) {
                 if (!e && gzStat.isFile()) {
                     const vary = _headers['Vary'];
                     _headers['Vary'] = (vary && vary != 'Accept-Encoding' ? vary + ', ' : '') + 'Accept-Encoding';
    
  • test/integration/node-static-test.js+9 0 modified
    @@ -460,4 +460,13 @@ suite.addBatch({
                     assert.equal(body, 'hello world');
                 }
             }
    +    }).addBatch({
    +        'handling malicious urls': {
    +            topic : function(){
    +                request.get(TEST_SERVER + '/%00', this.callback);
    +            },
    +            'should respond with 404' : function(error, response, body){
    +                assert.equal(response.statusCode, 404);
    +            }
    +        }
         }).export(module);
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.