1
0
Fork 0
mirror of https://code.forgejo.org/forgejo/runner.git synced 2025-07-27 17:28:35 +00:00

fix: mask multiline secrets

- do not try to mask a secret when a log line is received
- try to mask secrets before before sending a batch of log
  lines to the Forgejo instance (every second)
- if masking a multiline secret needs more log lines to decide
  if it needs to be masked, do not attempt to send anything to
  the Forgejo instance, just wait until there are more log lines

Closes forgejo/runner#57
This commit is contained in:
Earl Warren 2025-07-05 10:56:28 +02:00
parent b842a66be2
commit 57716748c6
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00

View file

@ -31,8 +31,7 @@ type Reporter struct {
logOffset int logOffset int
logRows []*runnerv1.LogRow logRows []*runnerv1.LogRow
logReplacer *strings.Replacer masker *masker
oldnew []string
reportInterval time.Duration reportInterval time.Duration
state *runnerv1.TaskState state *runnerv1.TaskState
@ -44,24 +43,23 @@ type Reporter struct {
} }
func NewReporter(ctx context.Context, cancel context.CancelFunc, c client.Client, task *runnerv1.Task, reportInterval time.Duration) *Reporter { func NewReporter(ctx context.Context, cancel context.CancelFunc, c client.Client, task *runnerv1.Task, reportInterval time.Duration) *Reporter {
var oldnew []string masker := newMasker()
if v := task.Context.Fields["token"].GetStringValue(); v != "" { if v := task.Context.Fields["token"].GetStringValue(); v != "" {
oldnew = append(oldnew, v, "***") masker.add(v)
} }
if v := client.BackwardCompatibleContext(task, "runtime_token"); v != "" { if v := client.BackwardCompatibleContext(task, "runtime_token"); v != "" {
oldnew = append(oldnew, v, "***") masker.add(v)
} }
for _, v := range task.Secrets { for _, v := range task.Secrets {
oldnew = append(oldnew, v, "***") masker.add(v)
} }
rv := &Reporter{ rv := &Reporter{
ctx: ctx, ctx: ctx,
cancel: cancel, cancel: cancel,
client: c, client: c,
oldnew: oldnew, masker: masker,
reportInterval: reportInterval, reportInterval: reportInterval,
logReplacer: strings.NewReplacer(oldnew...),
state: &runnerv1.TaskState{ state: &runnerv1.TaskState{
Id: task.Id, Id: task.Id,
}, },
@ -290,6 +288,10 @@ func (r *Reporter) ReportLog(noMore bool) error {
return nil return nil
} }
if needMore := r.masker.replace(rows, noMore); needMore {
return NewErrRetry(errRetryNeedMoreRows)
}
resp, err := r.client.UpdateLog(r.ctx, connect.NewRequest(&runnerv1.UpdateLogRequest{ resp, err := r.client.UpdateLog(r.ctx, connect.NewRequest(&runnerv1.UpdateLogRequest{
TaskId: r.state.Id, TaskId: r.state.Id,
Index: int64(r.logOffset), Index: int64(r.logOffset),
@ -402,7 +404,7 @@ func (r *Reporter) handleCommand(originalContent, command, parameters, value str
switch command { switch command {
case "add-mask": case "add-mask":
r.addMask(value) r.masker.add(value)
return nil return nil
case "debug": case "debug":
if r.debugOutputEnabled { if r.debugOutputEnabled {
@ -449,15 +451,8 @@ func (r *Reporter) parseLogRow(entry *log.Entry) *runnerv1.LogRow {
} }
} }
content = r.logReplacer.Replace(content)
return &runnerv1.LogRow{ return &runnerv1.LogRow{
Time: timestamppb.New(entry.Time), Time: timestamppb.New(entry.Time),
Content: strings.ToValidUTF8(content, "?"), Content: strings.ToValidUTF8(content, "?"),
} }
} }
func (r *Reporter) addMask(msg string) {
r.oldnew = append(r.oldnew, msg, "***")
r.logReplacer = strings.NewReplacer(r.oldnew...)
}