Harden secret-file creation, token comparison and git refname args
Works off the security audit in docs/prs/2026-07-08-PR#000: TODO 1, 8, 9 and 10, the four items that need no design decision. New `SecretFiles` creates files holding secrets with mode 0600 and their directories with 0700 *at creation*, as a file attribute, instead of writing at the umask default and chmod-ing afterwards — that left a window in which the Gitea token was world-readable, which matters on a multi-tenant host. It is used by `init` for .git/gittally/.gittally.yml and by `ControlTokenService` for the control token; the shell setup script now writes its YAML in a `umask 077` subshell for the same reason. `ControlTokenService.matches` hashes both sides with SHA-256 before `MessageDigest.isEqual`, so the comparison always runs over two 32-byte buffers and cannot return early on a length mismatch. `GitService.checkout` and `fetchBranch` pass `--` before the refname, so a branch named like an option cannot be read as one. `resetHardToOrigin` keeps its plain form: `git reset --hard -- <commit>` is rejected outright and its argument is already `origin/`-prefixed. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -37,7 +37,8 @@ class GitService(
|
||||
workingDir: Path = Paths.get("."),
|
||||
) {
|
||||
authenticated(workingDir) { environment ->
|
||||
runner.runOrThrow(listOf("git", "fetch", "origin", branch), workingDir, environment)
|
||||
// `--` guards against refnames starting with `-` being read as git options
|
||||
runner.runOrThrow(listOf("git", "fetch", "origin", "--", branch), workingDir, environment)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +143,7 @@ class GitService(
|
||||
workingDir: Path = Paths.get("."),
|
||||
) {
|
||||
if (refExists("refs/heads/$branch", workingDir)) {
|
||||
runner.runOrThrow(listOf("git", "switch", branch), workingDir)
|
||||
runner.runOrThrow(listOf("git", "switch", "--", branch), workingDir)
|
||||
} else {
|
||||
runner.runOrThrow(listOf("git", "switch", "--track", "-c", branch, "refs/remotes/origin/$branch"), workingDir)
|
||||
}
|
||||
@@ -152,6 +153,8 @@ class GitService(
|
||||
branch: String,
|
||||
workingDir: Path = Paths.get("."),
|
||||
) {
|
||||
// no `--` here: with paths `git reset --hard` refuses to run; the `origin/` prefix
|
||||
// already keeps the argument from looking like an option
|
||||
runner.runOrThrow(listOf("git", "reset", "--hard", "origin/$branch"), workingDir)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user