Skip to content

Commit

Permalink
Enable Secret Scanning for Empty Repo (#1165)
Browse files Browse the repository at this point in the history
  • Loading branch information
johannesHarness authored and Harness committed Mar 29, 2024
1 parent 2eac3c3 commit e4db4dc
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 15 deletions.
58 changes: 58 additions & 0 deletions app/api/controller/githook/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ import (
"github.com/harness/gitness/app/services/settings"
"github.com/harness/gitness/app/store"
"github.com/harness/gitness/app/url"
"github.com/harness/gitness/errors"
"github.com/harness/gitness/git"
"github.com/harness/gitness/git/api"
"github.com/harness/gitness/git/hook"
"github.com/harness/gitness/git/sha"
"github.com/harness/gitness/types"
"github.com/harness/gitness/types/enum"
)
Expand Down Expand Up @@ -92,3 +97,56 @@ func (c *Controller) getRepoCheckAccess(ctx context.Context,

return repo, nil
}

// GetBaseSHAForScanningChanges returns the commit sha to which the new sha of the reference
// should be compared against when scanning incoming changes.
// NOTE: If no such a sha exists, then (sha.None, false, nil) is returned.
// This will happen in case the default branch doesn't exist yet.
func GetBaseSHAForScanningChanges(
ctx context.Context,
rgit RestrictedGIT,
repo *types.Repository,
env hook.Environment,
refUpdates []hook.ReferenceUpdate,
findBaseFor hook.ReferenceUpdate,
) (sha.SHA, bool, error) {
// always return old SHA of ref if possible (even if ref was deleted, that's on the caller)
if !findBaseFor.Old.IsNil() {
return findBaseFor.Old, true, nil
}

// reference is just being created.
// For now we use default branch as a fallback (can be optimized to most recent commit on reference that exists)
dfltBranchFullRef := api.BranchPrefix + repo.DefaultBranch
for _, refUpdate := range refUpdates {
if refUpdate.Ref != dfltBranchFullRef {
continue
}

// default branch is being updated as part of push - make sure we use OLD default branch sha for comparison
if !refUpdate.Old.IsNil() {
return refUpdate.Old, true, nil
}

// default branch is being created - no fallback available
return sha.None, false, nil
}

// read default branch from git
dfltBranchOut, err := rgit.GetBranch(ctx, &git.GetBranchParams{
ReadParams: git.ReadParams{
RepoUID: repo.GitUID,
AlternateObjectDirs: env.AlternateObjectDirs,
},
BranchName: repo.DefaultBranch,
})
if errors.IsNotFound(err) {
// this happens for empty repo's where the default branch wasn't created yet.
return sha.None, false, nil
}
if err != nil {
return sha.None, false, fmt.Errorf("failed to get default branch from git: %w", err)
}

return dfltBranchOut.Branch.SHA, true, nil
}
38 changes: 23 additions & 15 deletions app/api/controller/githook/pre_receive_scan_secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"fmt"

"github.com/harness/gitness/app/services/settings"
"github.com/harness/gitness/errors"
"github.com/harness/gitness/git"
"github.com/harness/gitness/git/api"
"github.com/harness/gitness/git/hook"
Expand Down Expand Up @@ -88,7 +87,7 @@ func scanSecretsInternal(ctx context.Context,
repo *types.Repository,
in types.GithookPreReceiveInput,
) (scanSecretsResult, error) {
var latestDfltCommitSHA string
var baseRevFallBack *string
res := scanSecretsResult{}

for _, refUpdate := range in.RefUpdates {
Expand All @@ -104,23 +103,32 @@ func scanSecretsInternal(ctx context.Context,
baseRev := refUpdate.Old.String() + "^{commit}"
rev := refUpdate.New.String() + "^{commit}"
//nolint:nestif
if refUpdate.Old.String() == types.NilSHA {
if latestDfltCommitSHA == "" {
branchOut, err := rgit.GetBranch(ctx, &git.GetBranchParams{
ReadParams: git.CreateReadParams(repo), // without any custom environment
BranchName: repo.DefaultBranch,
})
if errors.IsNotFound(err) {
return scanSecretsResult{}, nil
}
if refUpdate.Old.IsNil() {
if baseRevFallBack == nil {
fallbackSHA, fallbackAvailable, err := GetBaseSHAForScanningChanges(
ctx,
rgit,
repo,
in.Environment,
in.RefUpdates,
refUpdate,
)
if err != nil {
return scanSecretsResult{}, fmt.Errorf("failed to retrieve latest commit of default branch: %w", err)
return scanSecretsResult{}, fmt.Errorf("failed to get fallback sha: %w", err)
}

if fallbackAvailable {
log.Debug().Msgf("found fallback sha %q", fallbackSHA)
baseRevFallBack = ptr.String(fallbackSHA.String())
} else {
log.Debug().Msg("no fallback sha available, do full scan instead")
baseRevFallBack = ptr.String("")
}
latestDfltCommitSHA = branchOut.Branch.SHA.String()
}
baseRev = latestDfltCommitSHA

log.Debug().Msgf("use latest dflt commit %s as comparison for new branch", latestDfltCommitSHA)
log.Debug().Msgf("new reference, use rev %q as base for secret scanning", *baseRevFallBack)

baseRev = *baseRevFallBack
}

log.Debug().Msg("scan for secrets")
Expand Down

0 comments on commit e4db4dc

Please sign in to comment.