Skip to content

security: validate version string in HttpSourceDownloader to prevent unexpected URL construction #413

@stack72

Description

@stack72

Summary

The version parameter passed to HttpSourceDownloader.downloadAndExtract() is interpolated directly into a GitHub URL with no validation:

// src/infrastructure/source/http_source_downloader.ts:42-43
const tag = version.startsWith("v") ? version : `v${version}`;
return `${HttpSourceDownloader.GITHUB_BASE}/tags/${tag}.tar.gz`;

There is no check that version contains only safe URL characters. Characters such as #, ?, /, .., or URL-encoded sequences (e.g. %2F) could cause the constructed URL to resolve unexpectedly within the GitHub URL space.

Risk

The base URL is hardcoded to https://github.com/systeminit/swamp/archive/refs, so no SSRF to arbitrary hosts is possible. However, a crafted version string could:

  • Escape the /tags/ path segment (e.g. version = "1.0/../../heads/main")
  • Hit unintended GitHub archive endpoints

Recommended Fix

Add a validation guard at the top of downloadAndExtract() (or inside getArchiveUrl()) that rejects any version string not matching a safe pattern:

if (!/^[a-zA-Z0-9._-]+$/.test(version)) {
  throw new UserError(
    `Invalid version string "${version}": must contain only alphanumeric characters, dots, hyphens, and underscores.`,
  );
}

Add a test that calling downloadAndExtract with "../malicious" throws a UserError before any network request is made.

References

  • src/infrastructure/source/http_source_downloader.tsgetArchiveUrl()

Metadata

Metadata

Assignees

No one assigned

    Labels

    betaIssues required to close out before public betabugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions