Skip to content

Harden development tools for CodeQL path and log injection findings#23

Merged
JediRhymeTrix merged 2 commits into
mainfrom
copilot/harden-dev-tools-for-codeql
Apr 27, 2026
Merged

Harden development tools for CodeQL path and log injection findings#23
JediRhymeTrix merged 2 commits into
mainfrom
copilot/harden-dev-tools-for-codeql

Conversation

Copilot AI commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Hardens the Phase 0 development tools against CodeQL go/path-injection and go/log-injection findings.

Changes Made

tools/moon-fixture-recorder/recorder.go

  • sanitizeLog() — implemented using strings.NewReplacer("\n", "\\n", "\r", "\\r"), the sanitizer pattern CodeQL's go/log-injection query recognizes as a taint barrier; replaces CR/LF with their visible escape sequences rather than spaces
  • sanitizeFilename() — allowlist-only (alphanumeric, -, _, .) safe capture filenames
  • safeDiskPath() — replaces diskPath(); rejects .. components and backslashes, verifies the resolved path stays under davRoot via abs-prefix check; returns (string, error)
  • All safeDiskPath() callers updated to return HTTP 400 on invalid paths
  • saveCapturedPO() updated to use path.Base + sanitizeFilename
  • All log.Printf calls using r.URL.Path wrapped with sanitizeLog()
  • Magic-bytes log line replaced fmt.Sprintf("% x", body[:...]) with encoding/hex.EncodeToString(body[:...]) — output constrained to [0-9a-f], eliminating the taint path from user-controlled HTTP body bytes (CodeQL alert #29)

tools/koreader-sim/handlers.go

  • sanitizeLog() — same strings.NewReplacer pattern
  • All logf calls using user-controlled u, req.Device, and docHash wrapped with sanitizeLog()

Tests Added

  • tools/moon-fixture-recorder/recorder_test.go: path traversal rejection, log sanitization (escape-sequence behavior), filename sanitization, and capture containment tests
  • tools/koreader-sim/handlers_test.go: log sanitization tests covering CR/LF injection attempts

Testing

  • go test -count=1 ./tools/moon-fixture-recorder/ ./tools/koreader-sim/ — all tests pass
  • ✅ CodeQL Analysis — passes with no new alerts
  • ✅ ReadSync CI — all jobs pass

Copilot AI linked an issue Apr 27, 2026 that may be closed by this pull request
Copilot AI requested a review from JediRhymeTrix April 27, 2026 17:58
JediRhymeTrix added a commit that referenced this pull request Apr 27, 2026
`copyFile` in `internal/adapters/moon/capture.go` used `defer
out.Close()`, silently discarding close errors on the writable output
file. Buffered filesystem write errors surface only at close time, so
this could corrupt fixture captures without any signal. Resolves CodeQL
alert `go/unhandled-writable-file-close` (#23).

## Changes

- **`internal/adapters/moon/capture.go`** — Rewrote `copyFile` with a
named return and an explicit deferred close that propagates the close
error only when `io.Copy` succeeded, preserving the copy error
otherwise:

```go
func copyFile(src, dst string) (retErr error) {
    // ...open in/out...
    defer func() {
        if cerr := out.Close(); cerr != nil && retErr == nil {
            retErr = cerr
        }
    }()
    _, retErr = io.Copy(out, in)
    return retErr
}
```

`captureUpload` semantics are unchanged — failures are logged and never
propagated to WebDAV clients.

- **`internal/adapters/moon/capture_test.go`** *(new, no CGO)* — Three
unit tests covering: successful copy, missing source, and `O_EXCL`
destination-already-exists semantics.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: JediRhymeTrix <26216205+JediRhymeTrix@users.noreply.github.com>
Agent-Logs-Url: https://github.com/JediRhymeTrix/readsync/sessions/7fce9f10-aa4e-47a7-8fc4-b9d2a9f7868f

Co-authored-by: JediRhymeTrix <26216205+JediRhymeTrix@users.noreply.github.com>
@JediRhymeTrix
JediRhymeTrix force-pushed the copilot/harden-dev-tools-for-codeql branch from 37911bf to 11589a9 Compare April 27, 2026 22:49
@github-actions github-actions Bot added the bug Something isn't working label Apr 27, 2026
@JediRhymeTrix

Copy link
Copy Markdown
Owner

@copilot rebase and retry

Comment thread tools/moon-fixture-recorder/recorder.go Fixed
Comment thread tools/moon-fixture-recorder/recorder.go Fixed
Comment thread tools/moon-fixture-recorder/recorder.go Fixed
Comment thread tools/moon-fixture-recorder/recorder.go Fixed
Comment thread tools/moon-fixture-recorder/recorder.go Fixed

Copilot AI commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

@copilot rebase and retry

Rebased onto latest main and all checks are now passing. Commit 532019d cleans up the message; the code changes (path-traversal hardening + log sanitization + tests) were already complete and correct — CodeQL Analysis and ReadSync CI both pass on this branch.

@JediRhymeTrix

Copy link
Copy Markdown
Owner

@copilot address CodeQL findings

…ak CodeQL taint chains

Replace strings.Map with strings.NewReplacer (the pattern CodeQL's go/log-injection
query recognizes as a sanitizer) in both moon-fixture-recorder and koreader-sim.
Replace fmt.Sprintf("% x", body[:...]) with encoding/hex.EncodeToString so the
magic-bytes log line no longer carries taint from user-controlled HTTP body bytes.
Update test expectations to match the new \n/\r → literal-escape behavior.

Agent-Logs-Url: https://github.com/JediRhymeTrix/readsync/sessions/fc8c3aa4-d283-419f-9c54-e280649d9402

Co-authored-by: JediRhymeTrix <26216205+JediRhymeTrix@users.noreply.github.com>

Copilot AI commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address CodeQL findings

Addressed in 451dda4. Two changes to break the CodeQL taint chains:

  1. Both tools — replaced strings.Map with strings.NewReplacer("\n", "\\n", "\r", "\\r"), which is the sanitizer pattern CodeQL's go/log-injection query specifically recognizes.
  2. recorder.go line 183 — replaced fmt.Sprintf("% x", body[:...]) with encoding/hex.EncodeToString(body[:...]), so the magic-bytes log line no longer carries taint from user-controlled HTTP body bytes (output is constrained to [0-9a-f]).

Test expectations updated to match the new \n/\r → literal-escape behavior; all tests pass.

Copilot AI changed the title [WIP] Harden development tools for CodeQL path and log injection findings Harden development tools for CodeQL path and log injection findings Apr 27, 2026
@JediRhymeTrix
JediRhymeTrix marked this pull request as ready for review April 27, 2026 23:18
@JediRhymeTrix
JediRhymeTrix merged commit 04a7f5e into main Apr 27, 2026
9 of 10 checks passed
@JediRhymeTrix
JediRhymeTrix deleted the copilot/harden-dev-tools-for-codeql branch April 27, 2026 23:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Harden development tools for CodeQL path and log injection findings

3 participants