Kuberwastaken/claurst · error
Path contains URL-encoded traversal sequences
Error message
Path contains URL-encoded traversal sequences: {:?} What it means
Path-security guard in validate_memory_path: the path (case-insensitively) contains %2e or %2f — percent-encoded '.' or '/' sequences used to smuggle traversal past naive decoding. The formatted value is the offending input; the check runs before any decoding so encoded traversal cannot escape the memory directory.
Solutions
- Rename the file so its key contains no percent-encoded dot/slash sequences
- Reject the entry — encoded traversal in a sync key is hostile or corrupted input
- Sanitize team-memory keys on ingest before they reach sync
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at src-rust/crates/core/src/team_memory_sync.rs:88 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/75f7360d45190837.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/core/src/team_memory_sync.rs:88
// ---------------------------------------------------------------------------
// Path security validation
// ---------------------------------------------------------------------------
/// Reject paths that could escape the team-memory directory.
///
/// Checks performed (mirroring the TypeScript `securePath` validation):
/// - No null bytes
/// - No URL-encoded traversal sequences (`%2e`, `%2f`, case-insensitive)
/// - No backslashes
/// - Not an absolute path (Unix `/` or Windows `C:` style)
/// - No `..` components
pub fn validate_memory_path(path: &str) -> Result<()> {
if path.contains('\0') {
anyhow::bail!("Path contains null bytes: {:?}", path);
}
let lower = path.to_ascii_lowercase();
if lower.contains("%2e") || lower.contains("%2f") {
anyhow::bail!("Path contains URL-encoded traversal sequences: {:?}", path);
}
if path.contains('\\') {
anyhow::bail!("Path contains backslashes: {:?}", path);
}
if path.starts_with('/') {
anyhow::bail!("Absolute Unix paths not allowed: {:?}", path);
}
// Windows-style absolute path: e.g. "C:" or "c:"
if path.len() >= 2 {
let mut chars = path.chars();
let first = chars.next().unwrap();
if first.is_ascii_alphabetic() && chars.next() == Some(':') {
anyhow::bail!("Absolute Windows paths not allowed: {:?}", path);
}
}
if path.split('/').any(|component| component == "..") {
anyhow::bail!("Path traversal not allowed: {:?}", path);
}View on GitHub (pinned to b0637c97ec)