Skip to content

Shell injection risk: resolveTemplate substitutes args directly into command strings #23

@Lukavyi

Description

@Lukavyi

Problem

resolveTemplate() in src/workflows/file.ts does a naive string replace of ${arg} directly into shell command strings (line 177):

const command = resolveTemplate(step.command, resolvedArgs, results);

Where resolveArgsTemplate is just:

input.replace(/\$\{([A-Za-z0-9_-]+)\}/g, (match, key) => {
    if (key in args) return String(args[key]);
    return match;
});

This means if an arg value contains shell metacharacters (", $, backticks, etc.), the resulting command string breaks or behaves unexpectedly.

Reproduction

args:
  text:
    description: "Text to process"

steps:
  - id: process
    command: |
      jq -n --arg text "${text}" '{"result": $text}'

Call with text containing quotes or special chars:

lobster run workflow.lobster --args-json '{"text":"hello \"world\" - test"}'

Result: jq gets a broken command because the " chars end up unescaped in the shell string.

Current workaround

Use step-level env instead of inline ${arg} in commands:

steps:
  - id: process
    env:
      MY_TEXT: "${text}"
    command: |
      jq -n --arg text "$MY_TEXT" '{"result": $text}'

This works because env values are passed via Node.js process.env to spawn(), so shell interpolation of $MY_TEXT is safe.

Suggested fix

Either:

  1. Auto-escape args when substituting into command strings (shell-escape special chars)
  2. Pass args as env vars automatically (e.g. LOBSTER_ARG_<name>) so commands can reference $LOBSTER_ARG_text safely
  3. Document the limitation and recommend env approach as best practice

Option 2 seems cleanest - it would make all args available as env vars by default without changing existing behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions