-
Notifications
You must be signed in to change notification settings - Fork 1
[PPSC-602] fix(security): armisignore size limit and go-git CVE remediation #136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
30541a0
fb9d646
6eba49a
adcf45f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,18 @@ | ||
| package repo | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "io" | ||
| "os" | ||
| "path/filepath" | ||
| "strings" | ||
|
|
||
| "github.com/go-git/go-git/v5/plumbing/format/gitignore" | ||
| ) | ||
|
|
||
| // maxIgnoreFileSize is the maximum allowed size for a .armisignore file (1 MB). | ||
| const maxIgnoreFileSize = 1 << 20 | ||
|
|
||
| // IgnoreMatcher matches files against ignore patterns. | ||
| type IgnoreMatcher struct { | ||
| patterns []gitignore.Pattern | ||
|
|
@@ -28,6 +33,9 @@ func LoadIgnorePatterns(repoRoot string) (*IgnoreMatcher, error) { | |
| } | ||
|
|
||
| if !info.IsDir() && info.Name() == ".armisignore" { | ||
| if info.Mode()&os.ModeSymlink != 0 { | ||
| return fmt.Errorf(".armisignore is a symlink (rejected): %s", path) | ||
| } | ||
| patterns, err := loadIgnoreFile(path, repoRoot) | ||
|
Comment on lines
35
to
39
|
||
| if err != nil { | ||
| return err | ||
|
|
@@ -50,10 +58,21 @@ func LoadIgnorePatterns(repoRoot string) (*IgnoreMatcher, error) { | |
| } | ||
|
|
||
| func loadIgnoreFile(ignoreFilePath, repoRoot string) ([]gitignore.Pattern, error) { | ||
| data, err := os.ReadFile(ignoreFilePath) // #nosec G304 - ignore file path is constructed internally | ||
| f, err := os.Open(ignoreFilePath) // #nosec G304 - ignore file path is constructed internally | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| defer f.Close() //nolint:errcheck // read-only file | ||
|
|
||
| // Read up to maxIgnoreFileSize+1 to detect files exceeding the limit. | ||
| limited := io.LimitReader(f, maxIgnoreFileSize+1) | ||
| data, err := io.ReadAll(limited) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| if len(data) > maxIgnoreFileSize { | ||
| return nil, fmt.Errorf(".armisignore file too large (max %d bytes): %s", maxIgnoreFileSize, ignoreFilePath) | ||
| } | ||
|
|
||
| ignoreDir := filepath.Dir(ignoreFilePath) | ||
| relDir, err := filepath.Rel(repoRoot, ignoreDir) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The newly added behavior that rejects symlinked
.armisignorefiles isn’t covered by a unit test. Since this is security-related behavior, add a test that creates a symlink.armisignoreand assertsLoadIgnorePatternsreturns an error (skip the test on platforms/environments where symlink creation isn’t permitted).