mirror of
https://gitea.com/gitea/act_runner.git
synced 2026-08-03 05:13:10 +00:00
feat: mask secrets that reach the log in an encoded form (#1108)
Only the verbatim value of a secret was masked, so a secret leaked through an action that serialized it stayed readable: `toJSON(secrets)` escapes it, an Authorization header carries it base64-encoded, a URL percent-encodes it. Each secret and `::add-mask::` value is now masked in those forms too, matching the value encoders of GitHub's runner. Encodings that leave the value unchanged are skipped, so a plain token still costs a single replacement pair. Includes regression tests. Reviewed-on: https://gitea.com/gitea/runner/pulls/1108 Reviewed-by: Zettat123 <39446+zettat123@noreply.gitea.com>
This commit is contained in:
@@ -5,15 +5,18 @@ package report
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gitea.com/gitea/runner/act/runner"
|
||||
"gitea.com/gitea/runner/internal/pkg/client/mocks"
|
||||
"gitea.com/gitea/runner/internal/pkg/config"
|
||||
|
||||
@@ -1096,3 +1099,24 @@ func TestReporter_ParseResult(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// A secret leaked in an encoded form — the shape it takes once an action puts it in a
|
||||
// JSON body, a URL or a base64 payload — must be masked in the reported log as well.
|
||||
func TestReporter_masksEncodedSecrets(t *testing.T) {
|
||||
secret := `p@ss w"rd/1`
|
||||
r := &Reporter{logReplacer: strings.NewReplacer()}
|
||||
r.oldnew = runner.AppendSecretMasker(r.oldnew, secret)
|
||||
r.logReplacer = strings.NewReplacer(r.oldnew...)
|
||||
|
||||
for _, line := range []string{
|
||||
"token: " + secret,
|
||||
"basic " + base64.StdEncoding.EncodeToString([]byte(secret)),
|
||||
"https://example.com/?token=" + url.QueryEscape(secret),
|
||||
} {
|
||||
row := r.parseLogRow(&log.Entry{Message: line})
|
||||
require.NotNil(t, row)
|
||||
assert.Contains(t, row.Content, "***")
|
||||
assert.NotContains(t, row.Content, secret)
|
||||
assert.NotContains(t, row.Content, base64.StdEncoding.EncodeToString([]byte(secret)))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user