2022-09-04 13:47:56 +03:00
// Copyright 2022 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2022-09-04 13:47:56 +03:00
package migrations
import (
"fmt"
"strings"
2022-10-17 02:29:26 +03:00
system_model "code.gitea.io/gitea/models/system"
2022-09-04 13:47:56 +03:00
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
base "code.gitea.io/gitea/modules/migration"
)
// WarnAndNotice will log the provided message and send a repository notice
2023-07-04 21:36:08 +03:00
func WarnAndNotice ( fmtStr string , args ... any ) {
2022-09-04 13:47:56 +03:00
log . Warn ( fmtStr , args ... )
2022-10-17 02:29:26 +03:00
if err := system_model . CreateRepositoryNotice ( fmt . Sprintf ( fmtStr , args ... ) ) ; err != nil {
2022-09-04 13:47:56 +03:00
log . Error ( "create repository notice failed: " , err )
}
}
func hasBaseURL ( toCheck , baseURL string ) bool {
if len ( baseURL ) > 0 && baseURL [ len ( baseURL ) - 1 ] != '/' {
baseURL += "/"
}
return strings . HasPrefix ( toCheck , baseURL )
}
// CheckAndEnsureSafePR will check that a given PR is safe to download
func CheckAndEnsureSafePR ( pr * base . PullRequest , commonCloneBaseURL string , g base . Downloader ) bool {
valid := true
// SECURITY: the patchURL must be checked to have the same baseURL as the current to prevent open redirect
if pr . PatchURL != "" && ! hasBaseURL ( pr . PatchURL , commonCloneBaseURL ) {
// TODO: Should we check that this url has the expected format for a patch url?
WarnAndNotice ( "PR #%d in %s has invalid PatchURL: %s baseURL: %s" , pr . Number , g , pr . PatchURL , commonCloneBaseURL )
pr . PatchURL = ""
valid = false
}
// SECURITY: the headCloneURL must be checked to have the same baseURL as the current to prevent open redirect
if pr . Head . CloneURL != "" && ! hasBaseURL ( pr . Head . CloneURL , commonCloneBaseURL ) {
// TODO: Should we check that this url has the expected format for a patch url?
WarnAndNotice ( "PR #%d in %s has invalid HeadCloneURL: %s baseURL: %s" , pr . Number , g , pr . Head . CloneURL , commonCloneBaseURL )
pr . Head . CloneURL = ""
valid = false
}
// SECURITY: SHAs Must be a SHA
2023-12-14 00:02:00 +03:00
// FIXME: hash only a SHA1
2023-12-17 14:56:08 +03:00
CommitType := git . Sha1ObjectFormat
2023-12-14 00:02:00 +03:00
if pr . MergeCommitSHA != "" && ! CommitType . IsValid ( pr . MergeCommitSHA ) {
2022-09-04 13:47:56 +03:00
WarnAndNotice ( "PR #%d in %s has invalid MergeCommitSHA: %s" , pr . Number , g , pr . MergeCommitSHA )
pr . MergeCommitSHA = ""
}
2023-12-14 00:02:00 +03:00
if pr . Head . SHA != "" && ! CommitType . IsValid ( pr . Head . SHA ) {
2022-09-04 13:47:56 +03:00
WarnAndNotice ( "PR #%d in %s has invalid HeadSHA: %s" , pr . Number , g , pr . Head . SHA )
pr . Head . SHA = ""
valid = false
}
2023-12-14 00:02:00 +03:00
if pr . Base . SHA != "" && ! CommitType . IsValid ( pr . Base . SHA ) {
2022-09-04 13:47:56 +03:00
WarnAndNotice ( "PR #%d in %s has invalid BaseSHA: %s" , pr . Number , g , pr . Base . SHA )
pr . Base . SHA = ""
valid = false
}
// SECURITY: Refs must be valid refs or SHAs
if pr . Head . Ref != "" && ! git . IsValidRefPattern ( pr . Head . Ref ) {
WarnAndNotice ( "PR #%d in %s has invalid HeadRef: %s" , pr . Number , g , pr . Head . Ref )
pr . Head . Ref = ""
valid = false
}
if pr . Base . Ref != "" && ! git . IsValidRefPattern ( pr . Base . Ref ) {
WarnAndNotice ( "PR #%d in %s has invalid BaseRef: %s" , pr . Number , g , pr . Base . Ref )
pr . Base . Ref = ""
valid = false
}
pr . EnsuredSafe = true
return valid
}