balderdashy / balderdashy/sails

Invalid body in fake POST API calls potential security vulnerability

Open
#7,196 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

does this answer your question?
Dominant language
JavaScript
Stars
22.8k
Forks
1.9k
PR merge metrics
No merged PRs in 30d

Description

**Node version**: 14
**Sails version** _(sails)_: 1.4.4 and 1.5.0
**ORM hook version** _(sails-hook-orm)_: 4.0.0
**Sockets hook version** _(sails-hook-sockets)_: 2.0.1
**Organics hook version** _(sails-hook-organics)_: n/a
**Grunt hook version** _(sails-hook-grunt)_: n/a - not using
**Uploads hook version** _(sails-hook-uploads)_: n/a - not using
**DB adapter & version** _(e.g. sails-mysql@5.55.5)_: na - not using
**Skipper adapter & version** _(e.g. skipper-s3@5.55.5)_: 0.9.1


Make API Call with fake body data:
`POST /api/fake/call`
Body (use application\json):
`{ Fake broken data}`

This should return a 404 because the API is not listed in routes.js. But instead some of the underlying code (body-parser, skipper) is being called before an error occurs and it returns the full API stack back to the calling API.

This was discovered because of actual attempts that were trying out the following code on a site I have log access to. I confirmed that partial execution containing malicious executable code was *attempted* but the following error was spit back, most likely preventing the execution. The containers were recycled anyway for safety.

`
381
2021-12-15T17:59:36.389-08:00
2021-12-16T01:59:36.389Z info: <<<< POST /data6688/open/getCompanyInfo (time: 10) :: [code: 400]
382
2021-12-15T17:59:36.382-08:00
2021-12-16T01:59:36.382Z error: Unable to parse HTTP body- error occurred :: 'UnsupportedMediaTypeError: unsupported charset "UTF8"\n' +
383
2021-12-15T17:59:36.382-08:00
' at jsonParser (**redacted**/node_modules/skipper/node_modules/body-parser/lib/types/json.js:126:12)\n' +
384
2021-12-15T17:59:36.382-08:00
' at _parseHTTPBody (**redacted**/node_modules/skipper/lib/skipper.js:119:5)\n' +
385
2021-12-15T17:59:36.382-08:00
' at Layer.handle [as handle_request] (**redacted**/node_modules/express/lib/router/layer.js:95:5)\n' +
386
2021-12-15T17:59:36.382-08:00
' at trim_prefix (**redacted**/node_modules/express/lib/router/index.js:317:13)\n' +
387
2021-12-15T17:59:36.382-08:00
' at **redacted**/node_modules/express/lib/router/index.js:284:7\n' +
388
2021-12-15T17:59:36.382-08:00
' at Function.process_params (**redacted**/node_modules/express/lib/router/index.js:335:12)\n' +
389
2021-12-15T17:59:36.382-08:00
' at next (**redacted**/node_modules/express/lib/router/index.js:275:10)\n' +
390
2021-12-15T17:59:36.382-08:00
' at cookieParser (**redacted**/node_modules/cookie-parser/index.js:57:14)\n' +
391
2021-12-15T17:59:36.382-08:00
' at Layer.handle [as handle_request] (**redacted**/node_modules/express/lib/router/layer.js:95:5)\n' +
392
2021-12-15T17:59:36.382-08:00
' at trim_prefix (**redacted**/node_modules/express/lib/router/index.js:317:13)\n' +
393
2021-12-15T17:59:36.382-08:00
' at **redacted**/node_modules/express/lib/router/index.js:284:7\n' +
394
2021-12-15T17:59:36.382-08:00
' at Function.process_params (**redacted**/node_modules/express/lib/router/index.js:335:12)\n' +
395
2021-12-15T17:59:36.382-08:00
' at next (**redacted**/node_modules/express/lib/router/index.js:275:10)\n' +
396
2021-12-15T17:59:36.382-08:00
' at responseTimeLogger (**redacted**/config/http.js:61:18)\n' +
397
2021-12-15T17:59:36.382-08:00
' at Layer.handle [as handle_request] (**redacted**/node_modules/express/lib/router/layer.js:95:5)\n' +
398
2021-12-15T17:59:36.382-08:00
' at trim_prefix (**redacted**/node_modules/express/lib/router/index.js:317:13)\n' +
399
2021-12-15T17:59:36.382-08:00
' at **redacted**/node_modules/express/lib/router/index.js:284:7\n' +
400
2021-12-15T17:59:36.382-08:00
' at Function.process_params (**redacted**/node_modules/express/lib/router/index.js:335:12)\n' +
401
2021-12-15T17:59:36.382-08:00
' at next (**redacted**/node_modules/express/lib/router/index.js:275:10)\n' +
402
2021-12-15T17:59:36.382-08:00
' at requestLogger (**redacted**/config/http.js:68:20)\n' +
403
2021-12-15T17:59:36.382-08:00
' at Layer.handle [as handle_request] (**redacted**/node_modules/express/lib/router/layer.js:95:5)\n' +
404
2021-12-15T17:59:36.382-08:00
' at trim_prefix (**redacted**/node_modules/express/lib/router/index.js:317:13)'
405
2021-12-15T17:59:36.379-08:00
2021-12-16T01:59:36.379Z info: >>>> POST /data6688/open/getCompanyInfo
`

The above should have returned a 404 and never processed ANY code outside of validation of the route. The various librraries involved are a concern if the malicious code contained cookies or file uploads. It may not have executed anything but it should not have informed the hacker that this was a valid url with some kind of server.

This should have generated a 404 and without error stack information.

I'm also able to reproduce this easily on my end as well and it returns the error stack back to the API caller which is no bueno either.

At worst this is a serious security issue. At best, the API should return a 404 without any callstack information.

I've also installed a vanilla version of Sails 1.5.0 WebApp and can reproduce the same issue.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the invalid POST against the vanilla Sails 1.5.0 app, then trace route handling through routes.js and the body-parser/skipper middleware shown in the report. Review the Express stack and the middleware references in config/http.js. Done means an unlisted route returns 404 without processing the body or exposing an error stack.

Written by the indexing model from the issue text.

Assessment

Tech stack
express, javascript, node.js
Domain
api, backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.