Merge fastify/send#1
Conversation
Signed-off-by: Matteo Collina <hello@matteocollina.com>
Signed-off-by: Matteo Collina <hello@matteocollina.com>
Update debug
Signed-off-by: Matteo Collina <hello@matteocollina.com>
* chore: disable package-lock generation * ci: use org reusable workflow * chore(.gitignore): use skeleton template * docs: remove security policy, allowing org one to show * chore(package): replace eslint with standard * chore(package): remove engines * docs(readme): update title, add badges * chore: lint files
Bumps [supertest](https://github.com/visionmedia/supertest) from 6.2.2 to 6.3.3. - [Release notes](https://github.com/visionmedia/supertest/releases) - [Commits](forwardemail/supertest@v6.2.2...v6.3.3) --- updated-dependencies: - dependency-name: supertest dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [mocha](https://github.com/mochajs/mocha) from 9.2.2 to 10.2.0. - [Release notes](https://github.com/mochajs/mocha/releases) - [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md) - [Commits](mochajs/mocha@v9.2.2...v10.2.0) --- updated-dependencies: - dependency-name: mocha dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* replace mocha with tap * fix coverage issue
* add types, nodenext, upgrade mime * improve test coverage
* use listenerCount immediatly * like before
* remove deprecated option and methods * decrease branch coverage to 95
* 100% test coverage * add ENAMETOOLONG test * add test case for ENOTDIR * fix linting * increase longFilename to 512 characters * patch onStatError for further investigation on windows * try to ignore block for coverage * windows switch * fix linting
* integrate rangeg-parser * named export parseRange
* feat: migrate collapseLeadingSlashes * feat: migrate containsDotFile * feat: migrate isUtf8MimeType * feat: migrate normalize list * feat: migrate parseBytesRange * feat: migrated mime * feat: migrate send.1 * feat: migrate send 2 * feat: migrate send.3 and removed tap * feat: migrated commands * chore: import * fix: await * chore: removed empty plans * Delete .taprc Signed-off-by: Matteo Pietro Dazzi <matteopietro.dazzi@gmail.com> * fix: typo * BREAKING CHANGE: remove support for node18 * fix: use c8 --------- Signed-off-by: Matteo Pietro Dazzi <matteopietro.dazzi@gmail.com>
Bumps [tsd](https://github.com/tsdjs/tsd) from 0.31.2 to 0.32.0. - [Release notes](https://github.com/tsdjs/tsd/releases) - [Commits](tsdjs/tsd@v0.31.2...v0.32.0) --- updated-dependencies: - dependency-name: tsd dependency-version: 0.32.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.15.34 to 24.0.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 24.0.8 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [tsd](https://github.com/tsdjs/tsd) from 0.32.0 to 0.33.0. - [Release notes](https://github.com/tsdjs/tsd/releases) - [Commits](tsdjs/tsd@v0.32.0...v0.33.0) --- updated-dependencies: - dependency-name: tsd dependency-version: 0.33.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.10.4 to 25.0.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.0.3 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
| stream.pipe(res) | ||
| } catch (err) { | ||
| res.statusCode = 500 | ||
| res.end(String(err)) |
Check warning
Code scanning / CodeQL
Exception text reinterpreted as HTML Medium test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 4 months ago
In general, to fix this type of issue you must avoid sending raw exception strings (which may embed user-controlled values) directly to the HTTP response in a way that can be interpreted as HTML. Instead, either (a) avoid including the message entirely, (b) send a static, generic error message, or (c) escape/encode the message according to the context (HTML-escape for HTML, JSON-encode for JSON, etc.) before writing it.
Here, the best minimal fix without changing existing functionality is to HTML-escape the error string before passing it to res.end. The project already uses the escape-html library in lib/send.js, which is a standard and appropriate library for this purpose. We can reuse it in test/utils.js by adding a require('escape-html') import and wrapping the error string as escapeHtml(String(err)). This keeps the content of the message visible (just safely escaped) and should not break the tests, as they likely don’t rely on the exact raw characters of the error payload.
Concretely:
- In
test/utils.js, add an import near the top:const escapeHtml = require('escape-html'). - Then, in the
catch (err)block insidecreateServer, changeres.end(String(err))tores.end(escapeHtml(String(err))).
No other files (lib/send.js,lib/parseTokenList.js) need modification because they’re not directly writing exception text to HTTP responses; the vulnerable sink is intest/utils.js.
| @@ -3,6 +3,7 @@ | ||
| const http = require('node:http') | ||
| const assert = require('node:assert') | ||
| const send = require('..') | ||
| const escapeHtml = require('escape-html') | ||
|
|
||
| module.exports.shouldNotHaveHeader = function shouldNotHaveHeader (header, t) { | ||
| return function (res) { | ||
| @@ -25,7 +26,7 @@ | ||
| stream.pipe(res) | ||
| } catch (err) { | ||
| res.statusCode = 500 | ||
| res.end(String(err)) | ||
| res.end(escapeHtml(String(err))) | ||
| } | ||
| }) | ||
| } |
| stream.pipe(res) | ||
| } catch (err) { | ||
| res.statusCode = 500 | ||
| res.end(String(err)) |
Check warning
Code scanning / CodeQL
Information exposure through a stack trace Medium test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 4 months ago
In general, to fix information exposure through stack traces, you should avoid sending the raw error (or its stack) back to the client. Instead, log the full error details on the server (console, logger, etc.) and send a generic, non-sensitive message in the HTTP response. This maintains visibility for developers while preventing attackers from learning internal implementation details.
For this specific code in test/utils.js, we should modify the catch block inside module.exports.createServer so that it no longer does res.end(String(err)). The best minimal-change fix is:
- Log the error using
console.error(err)(built-in, no new dependencies). - Respond with a generic error message string such as
"Internal Server Error"or"An internal error occurred"that does not include any details fromerr.
Concretely:
- In
module.exports.createServer, lines 26–29, keep thecatch (err)andres.statusCode = 500, but replaceres.end(String(err))with a call toconsole.error(err)followed byres.end('Internal Server Error')(or similar). This preserves behavior that a 500 is returned on error, but stops exposing stack trace information to the client while still logging it for debugging.
No additional imports or method definitions are needed; we only use the standard console object.
| @@ -24,8 +24,9 @@ | ||
| res.writeHead(statusCode, headers) | ||
| stream.pipe(res) | ||
| } catch (err) { | ||
| console.error(err) | ||
| res.statusCode = 500 | ||
| res.end(String(err)) | ||
| res.end('Internal Server Error') | ||
| } | ||
| }) | ||
| } |
354f681 to
5eb769d
Compare
Pull Request Test Coverage Report for Build 21231906690Details
💛 - Coveralls |
a9e8e6f to
17df4e4
Compare
…/send - I also run the npm run lint:fix command
17df4e4 to
e1469ad
Compare
No description provided.