diff options
author | Norwin <noerw@users.noreply.github.com> | 2021-05-31 08:25:47 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-31 04:25:47 -0400 |
commit | cb940c4312981893fdb54cbd0e07520546776b34 (patch) | |
tree | 69ade3dd15712647ba04186008d3ffab203edf49 /models/task.go | |
parent | 256b1a35615487f27878422f877f25be3f066f54 (diff) | |
download | gitea-cb940c4312981893fdb54cbd0e07520546776b34.tar.gz gitea-cb940c4312981893fdb54cbd0e07520546776b34.zip |
Encrypt migration credentials at rest (#15895)
* encrypt migration credentials in task persistence
Not sure this is the best approach, we could encrypt the entire
`PayloadContent` instead. Also instead of clearing individual fields in
payload content, we could just delete the task once it has
(successfully) finished..?
* remove credentials of past migrations
* only run DB migration for completed tasks
* fix binding
* add omitempty
* never serialize unencrypted credentials
* fix import order
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Diffstat (limited to 'models/task.go')
-rw-r--r-- | models/task.go | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/models/task.go b/models/task.go index 8d4bfbf076..a4ab65b5e5 100644 --- a/models/task.go +++ b/models/task.go @@ -8,8 +8,11 @@ import ( "fmt" migration "code.gitea.io/gitea/modules/migrations/base" + "code.gitea.io/gitea/modules/secret" + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" jsoniter "github.com/json-iterator/go" "xorm.io/builder" @@ -110,6 +113,24 @@ func (task *Task) MigrateConfig() (*migration.MigrateOptions, error) { if err != nil { return nil, err } + + // decrypt credentials + if opts.CloneAddrEncrypted != "" { + if opts.CloneAddr, err = secret.DecryptSecret(setting.SecretKey, opts.CloneAddrEncrypted); err != nil { + return nil, err + } + } + if opts.AuthPasswordEncrypted != "" { + if opts.AuthPassword, err = secret.DecryptSecret(setting.SecretKey, opts.AuthPasswordEncrypted); err != nil { + return nil, err + } + } + if opts.AuthTokenEncrypted != "" { + if opts.AuthToken, err = secret.DecryptSecret(setting.SecretKey, opts.AuthTokenEncrypted); err != nil { + return nil, err + } + } + return &opts, nil } return nil, fmt.Errorf("Task type is %s, not Migrate Repo", task.Type.Name()) @@ -205,12 +226,31 @@ func createTask(e Engine, task *Task) error { func FinishMigrateTask(task *Task) error { task.Status = structs.TaskStatusFinished task.EndTime = timeutil.TimeStampNow() + + // delete credentials when we're done, they're a liability. + conf, err := task.MigrateConfig() + if err != nil { + return err + } + conf.AuthPassword = "" + conf.AuthToken = "" + conf.CloneAddr = util.SanitizeURLCredentials(conf.CloneAddr, true) + conf.AuthPasswordEncrypted = "" + conf.AuthTokenEncrypted = "" + conf.CloneAddrEncrypted = "" + json := jsoniter.ConfigCompatibleWithStandardLibrary + confBytes, err := json.Marshal(conf) + if err != nil { + return err + } + task.PayloadContent = string(confBytes) + sess := x.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { return err } - if _, err := sess.ID(task.ID).Cols("status", "end_time").Update(task); err != nil { + if _, err := sess.ID(task.ID).Cols("status", "end_time", "payload_content").Update(task); err != nil { return err } |