"""Language-neutral patterns: credential locations, persistence locations, TLS/registry settings, obfuscation markers and the workspace-scope classifier for paths. """ from __future__ import annotations import re _SEP = r"""['"\s,/\\+)(]{0,8}""" # tolerate Path("~") / ".ssh" / "id_rsa" style construction SECRET_PATTERNS = [ ("~/.ssh", re.compile(r"\.ssh\b(?!_)" + r"|\bid_(rsa|dsa|ecdsa|ed25519)\b|\bauthorized_keys\b|\bknown_hosts\b")), ("~/.aws credentials", re.compile(r"\.aws" + _SEP + r"(credentials|config)\b|\bAWS_SECRET_ACCESS_KEY\b|\bAWS_SESSION_TOKEN\b")), ("~/.npmrc", re.compile(r"\.npmrc\b|_authToken\b")), ("~/.pypirc", re.compile(r"\.pypirc\b")), ("~/.netrc", re.compile(r"(?= 2: out.append((f"_0x identifiers ({n} on line)", "hex-named identifiers")) if OBF_PACKED.search(line): out.append(("packed/encoded JS", "packer signature")) m = OBF_CHARCODES.search(line) if m: out.append(("charcode array/sequence", "numeric character codes")) m = OBF_B64.search(line) if m and not re.fullmatch(r"[A-Za-z]+", m.group(0)[:200]) and not re.search(r"sha\d+-|integrity|\"resolved\"", line): out.append((f"base64-like blob ({len(m.group(0))} chars)", "long encoded literal")) m = OBF_HEX.search(line) if m and not re.search(r"sha\d+|integrity|hash|digest", line, re.I): out.append((f"hex blob ({len(m.group(0))} chars)", "long encoded literal")) if BIDI.search(line): out.append(("bidi/zero-width unicode", "invisible or direction-changing characters")) if len(line) > 2000 and lang in ("javascript", "typescript", "python", "tsx", "sfc"): out.append((f"very long line ({len(line)} chars)", "minified or packed")) return out def path_scope(expr: str) -> str: """Classify a path expression: home, system, temp, workspace or unknown. Purely textual.""" e = expr.strip().strip("'\"`") if not e or e == "dynamic": return "unknown" m = re.match(r"^\(?(?:pathlib\.)?(?:Path|PurePath|os\.path\.join|path\.join|path\.resolve)\(\s*['\"]([^'\"]+)['\"]", e) if m and not re.search(r"home|expanduser|tmp|temp|environ|getenv|process\.env", e, re.I): e = m.group(1) if re.search(r"(^~|\$HOME\b|\$\{HOME\}|%USERPROFILE%|%APPDATA%|\bhomedir\(\)|Path\.home\(\)|expanduser|" r"\bos\.homedir|HOMEPATH|\bAPPDATA\b|LOCALAPPDATA|getenv\(['\"]HOME|environ\[['\"]HOME|process\.env\.HOME)", e): return "home" if re.search(r"(^/tmp\b|^/var/tmp\b|\btempfile\b|\bmkdtemp|\bmkstemp|\btmpdir\(\)|\bgettempdir|\$TMPDIR|\bTemporaryDirectory|\btmp_path\b|\btmpdir\b|RUNNER_TEMP)", e): return "temp" if re.match(r"^(/(etc|usr|bin|sbin|lib|lib64|opt|var|boot|root|System|Library|Applications|private)\b|[A-Za-z]:\\\\?(Windows|Program))", e): return "system" if re.match(r"^/dev/", e): return "device" if re.search(r"(^|/)\.\.(/|$)", e) and not re.search(r"__file__|__dirname|import\.meta", e): return "parent of workspace?" if re.match(r"^/", e): return "absolute (other)" if re.match(r"^[\w.@-][\w./@-]*$", e) or re.search(r"__file__|__dirname|import\.meta\.url|cwd\(\)|getcwd", e): return "workspace" return "unknown"