From eb76daaaba6af27391a37ddda648c6e1d84336fc Mon Sep 17 00:00:00 2001 From: Boming Zhang Date: Mon, 3 Aug 2026 18:31:36 +0800 Subject: [PATCH] fix: redact sandbox token and enable CI lint (#104) Reviewed-on: https://focs.gc.sjtu.edu.cn/git/JOJ/JOJ3/pulls/104 Co-authored-by: Boming Zhang Co-committed-by: Boming Zhang --- .gitea/workflows/build.yaml | 4 ++-- cmd/joj3/conf/conf_test.go | 22 ++++++++++++++++++++++ cmd/joj3/conf/model.go | 12 ++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 5e686e1..f95756d 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -19,8 +19,8 @@ jobs: echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_ed25519.pub chmod 600 ~/.ssh/id_ed25519 ~/.ssh/id_ed25519.pub ssh -o StrictHostKeyChecking=accept-new -T git@focs.gc.sjtu.edu.cn -p 2222 - # - name: Lint - # run: make lint + - name: Lint + run: make lint - name: Build run: make build - name: Version diff --git a/cmd/joj3/conf/conf_test.go b/cmd/joj3/conf/conf_test.go index a7528c8..e73e5c0 100644 --- a/cmd/joj3/conf/conf_test.go +++ b/cmd/joj3/conf/conf_test.go @@ -1,8 +1,10 @@ package conf import ( + "bytes" "crypto/sha256" "encoding/hex" + "log/slog" "os" "path/filepath" "reflect" @@ -10,6 +12,26 @@ import ( "testing" ) +func TestConfLogValueRedactsSandboxToken(t *testing.T) { + var output bytes.Buffer + logger := slog.New(slog.NewJSONHandler(&output, nil)) + conf := &Conf{ + Name: "test", + SandboxToken: "top-secret-token", + } + logger.Info("config", "conf", conf) + got := output.String() + if strings.Contains(got, "top-secret-token") { + t.Fatalf("configuration log exposed sandbox token: %s", got) + } + if !strings.Contains(got, "[REDACTED]") || !strings.Contains(got, `"Name":"test"`) { + t.Fatalf("configuration log lost expected diagnostic fields: %s", got) + } + if conf.SandboxToken != "top-secret-token" { + t.Fatalf("logging mutated the runtime configuration: %q", conf.SandboxToken) + } +} + func TestGetSHA256(t *testing.T) { path := filepath.Join(t.TempDir(), "input") content := []byte("joj3") diff --git a/cmd/joj3/conf/model.go b/cmd/joj3/conf/model.go index c7ac480..73894f3 100644 --- a/cmd/joj3/conf/model.go +++ b/cmd/joj3/conf/model.go @@ -1,6 +1,8 @@ package conf import ( + "log/slog" + "github.com/joint-online-judge/JOJ3/internal/stage" ) @@ -32,6 +34,16 @@ type Conf struct { PostStages []ConfStage } +// LogValue preserves the configuration's diagnostic value without writing the +// sandbox credential to text or structured logs. +func (c Conf) LogValue() slog.Value { + type logConf Conf + if c.SandboxToken != "" { + c.SandboxToken = "[REDACTED]" + } + return slog.AnyValue(logConf(c)) +} + type OptionalCmd struct { Args *[]string Env *[]string