Skip to content

[SECURITY] [v0.0.7] Path traversal vulnerability in workflow_name parameter — arbitrary file write/delete #156

@joshme1

Description

@joshme1

Summary

The workflow_name parameter in cortex github install/uninstall/update commands is not validated for path traversal sequences. While repo_path is checked for .. sequences, workflow_name is directly concatenated into a file path without sanitization.

Affected Code

File: src/cortex-cli/src/github_cmd.rs

let workflows_dir = canonical_path.join(".github").join("workflows");
let workflow_file = workflows_dir.join(format!("{}.yml", args.workflow_name));

// Later: std::fs::write(&workflow_file, &workflow_content)

Steps to Reproduce

  1. In a git repository, run:
    cortex github install --workflow-name "../../../tmp/exploit"
  2. Check that file was created at /tmp/exploit.yml instead of .github/workflows/
  3. Similarly, cortex github uninstall --workflow-name "../../../tmp/exploit" would delete /tmp/exploit.yml

Expected Behavior

Workflow name should be validated to contain only safe characters (alphanumeric, hyphens, underscores). Any path separators or .. sequences should be rejected with an error message.

Actual Behavior

The workflow file is written to or deleted from an arbitrary location determined by the path traversal sequence in workflow_name.

Impact

  • Severity: MEDIUM
  • Attack Vector: Local (requires CLI access)
  • An attacker with CLI access can write/delete files outside the repository directory
  • Could potentially overwrite sensitive system files or create malicious files in arbitrary locations

Fix Suggestion

Add validation for workflow_name before using it in path construction:

// Validate workflow name doesn't contain path traversal or separators
if args.workflow_name.contains("..") || args.workflow_name.contains('/') || args.workflow_name.contains('\\') {
    bail!(
        "Invalid workflow name: '{}'\n\
         Workflow name cannot contain '..' or path separators.",
        args.workflow_name
    );
}

Alternatively, canonicalize the resulting path and verify it's still under workflows_dir:

let workflow_file = workflows_dir.join(format!("{}.yml", args.workflow_name));
let canonical_workflow = workflow_file.canonicalize().unwrap_or_else(|_| workflow_file.clone());
if !canonical_workflow.starts_with(&workflows_dir) {
    bail!("Security error: Workflow name resolves outside .github/workflows directory");
}

Additional Context

The code already has a path traversal check for repo_path (lines 173-181), showing awareness of this class of vulnerability, but the check was not applied to workflow_name. This same pattern exists in run_uninstall() and run_update() functions.


Found by Bug Hunter automated security scanner

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