Skip to content

Validate templateid/pluginid in pushConfiguration#1392

Open
TristanInSec wants to merge 1 commit intocdapio:developfrom
TristanInSec:validate-template-config-paths
Open

Validate templateid/pluginid in pushConfiguration#1392
TristanInSec wants to merge 1 commit intocdapio:developfrom
TristanInSec:validate-template-config-paths

Conversation

@TristanInSec
Copy link
Copy Markdown

Summary

Aggregator.pushConfiguration() in server/aggregator.js builds the path of the JSON config it is about to read by concatenating templateid and pluginid directly into the string:

filePaths.push(
  __dirname + '/../templates/' + templateid + '/' + pluginid + '.json',
  __dirname + '/../templates/common/' + pluginid + '.json'
);

Both values come from the WebSocket message payload (template-config action), so neither is trusted input. Without validation the path can escape the templates directory.

Changes

  • Add a TEMPLATE_ID_RE = /^[A-Za-z0-9_-]+$/ allowlist for both templateid and pluginid.
  • New buildTemplateConfigPaths() helper resolves the two candidate paths with path.resolve, then verifies each one stays inside its corresponding template directory (templates/<templateid> and templates/common).
  • If the resolver returns no candidates the handler now responds with status 400 and response: 'INVALID_TEMPLATE_OR_PLUGIN_ID' instead of falling through to the filesystem lookup.

The happy path for well-formed template/plugin identifiers resolves to the same absolute paths the previous implementation produced.

Testing

Exercised buildTemplateConfigPaths in isolation against a representative set of inputs:

templateid pluginid Result
etlbatch hdfs two paths inside templates/
a_b-c A9 two paths inside templates/
.. .. []
../../../.. ../../etc/cdap/conf/cdap-site []
etlbatch hdfs/../../etc/passwd []
'' '' []
null hdfs []
etlbatch /absolute/path []
etl.batch hdfs [] (dot not allowed)

Aggregator.pushConfiguration receives templateid and pluginid from the
WebSocket message payload and splices both values into an on-disk path
that is then read with fs.readFileSync. Because neither value is
constrained, an attacker with a valid session can supply values
containing ../ or absolute-path components and cause pushConfiguration
to read any readable .json file on the server.

Restrict the two identifiers to plain identifier characters
([A-Za-z0-9_-]+) and, after resolving the resulting path, verify it
still lives inside the templates directory. Invalid combinations now
reply with a 400/INVALID_TEMPLATE_OR_PLUGIN_ID response instead of
walking the filesystem.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants