Skip to content

fix(extension): entrypoint containment check is bypassable via symlink #500

Description

@margaretjgu

assertWithinInstallDir (src/extension/installer.ts:192) is documented as preventing "symlink/config injection", but it compares resolve()d paths. resolve() does not follow symlinks, so a symlink inside the install directory passes the check while pointing anywhere on disk.

Confirmed end to end. With bin/elastic-demo a symlink to a script outside the install dir:

elastic extension create demo --path <dir>
elastic demo
-> PAYLOAD RAN FROM OUTSIDE THE INSTALL DIR: <dir>/bin/elastic-demo

The registered entrypoint in ~/.elastic/extensions.json reads as an in-directory path, so the registry gives no indication the extension executes something else.

Two separate gaps:

  • installExtension calls the check, but resolve() makes it bypassable. A cloned github:owner/repo shipping a symlink escapes it.
  • createLocalExtension never calls the check at all.

Suggested fix: use realpath on both the entrypoint and the install dir before comparing, and call the check on the create path too.

Scope note: the practical attack is narrow. create --path points at a directory the user already controls, and install runs npm install from a cloned repo, which executes arbitrary postinstall code regardless. The reason to fix it is that the function is documented as a security control and does not currently act as one. If that is not worth fixing, the comment should be corrected instead.

Verification caveat: the end-to-end run above used the create --path route. The install github:... variant was verified by unit-testing the resolve() comparison directly, not with a real malicious repository.

Test plan

  • Test that a symlinked entrypoint pointing outside the install dir is rejected on install
  • Same assertion for extension create --path
  • Regression test that a normal in-directory entrypoint still registers

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingsecuritySecurity related

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions