Skip to content

Path traversal / arbitrary local file read via @@x-template (and l10n.yaml) template path #91

@Forbiddem

Description

@Forbiddem

Summary

Parser.resolveTemplatePath() passes a workspace-controlled path straight to fs.readFileSync without any containment check, so a crafted .arb file (or l10n.yaml) can make the extension read any file the editing user can open, outside the project.

  • Version: 0.2.2 (HEAD a6fa5a3)
  • Source: the @@x-template field of an .arb file, or arb-dir / template-arb-file in l10n.yaml
  • Sink: src/messageParser.ts:243fs.readFileSync(templatePath, "utf8")
  • Resolve: src/messageParser.ts:207-218 — no .. rejection, no workspace containment, absolute paths returned as-is

Steps to reproduce

  1. In any Flutter/ARB project, set the template field of an .arb file:
    { "@@locale": "es", "@@x-template": "../../../../../../../../../../etc/passwd" }
    (path.join clamps surplus .. at the filesystem root, so this lands on /etc/passwd regardless of where the repo is cloned; an absolute path works too.)
  2. Open the project in VS Code with the ARB Editor extension installed and open the .arb file.
  3. The extension's parser runs and calls fs.readFileSync("/etc/passwd") — a file entirely outside the workspace.

Impact

  • Arbitrary local file read. Any file readable by the user can be opened by the extension as a side effect of editing a repository.
  • Disclosure channel. For JSON-with-string-values targets, the top-level keys are echoed into the Problems panel as Missing messages from template: <keys> (src/diagnose.ts), surfacing file contents (key names) to the editing user — useful for exfiltration via a repo the attacker later inspects, or simply for tricking a victim.
  • Extension-host DoS (sub-case). The read is synchronous and follows symlinks; pointing the template at /dev/zero, a FIFO, or a multi-GB file blocks the extension host.

The same unchecked path also reaches the sink through the l10n.yaml (arb-dir + template-arb-file) branch.

Suggested fix

Resolve the candidate path and reject anything that escapes the workspace folder (fall back to the document directory when there is no workspace folder). Legitimate in-project templates are unaffected. PR attached.

This was reported through Google's VRP and closed as out of scope for that program; filing here so the project can fix it directly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions