/** * Is `rawUrl` an https URL whose host is EXACTLY `host`? * * A substring test (`url.includes('github.com')`) is not good enough and was a * live token-exfiltration bug: `https://github.com@attacker.example/x.git` * contains the string "github.com", so the old code spliced the GitHub token in * and produced * https://x-access-token:@github.com@attacker.example/x.git * whose REAL host is whatever follows the LAST `@` โ€” attacker.example. git then * sent the token there as basic auth. `url` reaches this code from a model-chosen * tool argument, and the skill is exposed to agents that read untrusted content, * so the host must be parsed, never matched. * * https-only on purpose: a token belongs in an https basic-auth URL and nowhere * else (not http://, not ssh://, not git://). */ export declare function isHttpsHost(rawUrl: string, host: string): boolean; /** * Return `rawUrl` with basic-auth credentials attached, built through the URL * object rather than string replacement so the authority can never be rewritten * by the input. Callers MUST have validated the host with isHttpsHost first. */ export declare function withCredentials(rawUrl: string, user: string, token: string): string; /** * SECURITY (CLAUDE.md ยง5) โ€” strip the auth token from a freshly-cloned repo's * on-disk git state. A `git clone https://x-access-token:@host/...` bakes * that authenticated URL into `/.git/config`; a Fargate agent then reads * UNTRUSTED PR/issue content with a Bash tool and could `cat .git/config` / * `git remote -v` to exfiltrate the tenant token (the shell ENV is scrubbed but * the repo config was not). This rewrites `origin` to the TOKENLESS `cleanUrl` * so the repo the model works in holds no secret. Push is unaffected: * deterministic workflow nodes re-inject the token transiently right before * `git push`, and the model is instructed never to push from Bash. * * `execSyncFn` is injected so this works from the execSync-based clone tools * (github_clone / gitlab_clone). The set-url command uses only the tokenless * URL, so a failure message carries no secret โ€” but we still mask `token` * defensively and never throw (a scrub failure must not break a good clone; it * is logged so a regression is visible). * * @param {(cmd:string, opts?:object)=>any} execSyncFn * @param {string} destPath the cloned repo directory * @param {string} cleanUrl the tokenless remote URL to set on origin * @param {string} [token] the secret, masked out of any error log * @param {string} [label] caller name for the log line */ export declare function scrubClonedRemoteSync(execSyncFn: any, destPath: any, cleanUrl: any, token: any, label?: string): void; export declare const gitSkill: any;