Skip to main content
Founding Partner + 7-Day Trial
Tier B Enterprise Fleet · 12-Language Immunity EngineAutoExtinguish: true (4-Gate Vericoding)

AutoExtinguish: true across all 12 supported languages via os.OpenRoot (Go 1.24+) and canonical realpath root-containment guards.

Commercial boundary: ciphermap immunity scan, immunity extinguish --apply, immunity attest (CycloneDX 1.6 CISA IBOM & OpenVEX 0.2.0), and ciphermap mcp require Tier B Enterprise Fleet. Offline proof and IBOM verification (--verify-proof, attest --verify) and the ciphermap demo sandbox run Free.

Back to docs
IMM-PATH-001CRITICALCISA Secure-by-Design Pledge · CWE-22 · NIST SP 800-53 Rev. 5 (AC-3, SI-10)

Unjailed Filesystem Path Traversal or Symlink Escape Across Polyglot I/O

Severity: CRITICAL

Constructing filesystem paths from untrusted relative inputs via path joins or string concatenation without canonical root-confinement remains vulnerable to '../' directory traversal, null-byte or stream-wrapper smuggling (such as PHP phar:// or Ruby '|cmd' open pipes), and symlink escapes. Dynamic file operations must be confined inside canonicalized or kernel-enforced base directories across Go, TypeScript, JavaScript, Python, Java, Kotlin, C#, Rust, C/C++, Ruby, PHP, and Swift.

Remediation checklist

  • Go: open the trusted base directory with root, err := os.OpenRoot(baseDir) (defer root.Close()) and perform file I/O exclusively through *os.Root methods.
  • TypeScript & JavaScript: canonicalize with fs.realpathSync and verify path.relative(realBase, realTarget) does not start with '..' or cross roots; Python: resolve via Path(base_dir).resolve() and enforce target.resolve().is_relative_to(real_base).
  • Java & Kotlin: canonicalize via basePath.toRealPath() and enforce target.toRealPath().startsWith(realBase); C#: canonicalize with Path.GetFullPath and verify ordinal prefix containment with Path.DirectorySeparatorChar; Rust: reject ParentDir/RootDir and verify fs::canonicalize(target).starts_with(&real_base).
  • C/C++: canonicalize with std::filesystem::weakly_canonical and verify component-wise prefix containment; Ruby: avoid Kernel#open/URI.open on dynamic strings and verify File.realpath containment with start_with?(real_base + '/'); PHP: reject stream wrappers, canonicalize with realpath(), and verify str_starts_with($realTarget, $realBase . DIRECTORY_SEPARATOR); Swift: enforce resolvingSymlinksInPath().standardizedFileURL containment.

Illustrative Code Examples

These fragments explain migration direction. They are not complete applications or compiler-verified patches for your project.

Vulnerable — unjailed relative path joins (Go / Ruby / PHP)

terminal · zsh
// Go: unjailed filepath.Join
data, err := os.ReadFile(filepath.Join(baseDir, userRelPath))

# Ruby: unjailed File.join + File.read
body = File.read(File.join(base_dir, params[:file]))

// PHP: unjailed path concatenation
$body = file_get_contents($baseDir . '/' . $_GET['doc']);

Remediated — kernel *os.Root & canonical realpath confinement

terminal · zsh
// Go 1.24+: kernel-enforced *os.Root confinement
root, err := os.OpenRoot(baseDir)
if err != nil { return nil, err }
defer root.Close()
data, err := root.ReadFile(userRelPath)

# Ruby: canonical realpath jail check
real_base = File.realpath(base_dir)
real_target = File.realpath(File.expand_path(user_rel, real_base))
raise ArgumentError, "path escape" unless real_target.start_with?(real_base + File::SEPARATOR)
body = File.binread(real_target)

Preview remediation proposals

Preview proposed changes free with ciphermap fix . --dry-run --offline --no-telemetry. Eligibility depends on the installed build, call shape, module format, and migration context. The bundled RSA fixture has a classical key-size candidate; that does not make it post-quantum secure. Persisted digests and unsupported contexts may be declined. Applying supported candidates requires an entitlement, explicit verifier consent, and the required project tools. Review the actual verification result before adopting a change.

View DevSecOps pricing

Other rule families