Skip to content

[PPSC-602] fix(security): armisignore size limit and go-git CVE remediation#136

Merged
yiftach-armis merged 4 commits intomainfrom
fix/PPSC-602-security-code-scanning-round2
Mar 31, 2026
Merged

[PPSC-602] fix(security): armisignore size limit and go-git CVE remediation#136
yiftach-armis merged 4 commits intomainfrom
fix/PPSC-602-security-code-scanning-round2

Conversation

@yiftach-armis
Copy link
Copy Markdown
Collaborator

@yiftach-armis yiftach-armis commented Mar 31, 2026

Related Issue

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Problem

After merging PR #135 (security code scanning remediations), GitHub Code Scanning reported 21 new/pre-existing open alerts. Triage revealed:

  • 6 were duplicates of previously dismissed alerts (line shifts or overlapping CWEs)
  • 13 were false positives (standard CLI patterns, hardcoded paths, read-only ops)
  • 2 were true positives requiring fixes

Solution

Alert triage (19 of 21 dismissed via GitHub API):

  • 6 duplicates re-dismissed with cross-references to original dismissals
  • 13 false positives dismissed with detailed justification comments

Code fixes for 2 true positives:

  • CWE-770 (internal/scan/repo/ignore.go): Added 1MB size check before os.ReadFile on .armisignore files to prevent memory exhaustion from maliciously large ignore files
  • CVE-2026-34165 (go.mod): Upgraded go-git/go-git/v5 from v5.17.0 to v5.17.2

Testing

Automated Tests

  • Unit tests added/updated
  • All tests passing locally

Manual Testing

  • go test ./internal/scan/repo/... -run Ignore — all 4 tests pass including new oversized file test
  • Verified open alert count dropped from 21 to 2 (these 2 will auto-close when this PR merges)

Checklist

  • Code follows project style guidelines
  • Pre-commit hooks pass
  • Self-review performed
  • No new warnings generated

…70, CVE-2026-34165)

- Add 1MB size check before reading .armisignore files to prevent
  memory exhaustion from maliciously large ignore files
- Upgrade go-git/go-git/v5 from v5.17.0 to v5.17.2 to address
  CVE-2026-34165
- Add test for oversized .armisignore rejection
Copilot AI review requested due to automatic review settings March 31, 2026 15:24
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses two security findings in the CLI repo scanner: it introduces a maximum size limit for .armisignore files to prevent unbounded memory reads, and updates go-git to remediate a reported CVE.

Changes:

  • Enforce a 1 MiB maximum size for .armisignore files during ignore pattern loading.
  • Add unit coverage for oversized .armisignore handling.
  • Bump github.com/go-git/go-git/v5 from v5.17.0 to v5.17.2 (and update go.sum).

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.

File Description
internal/scan/repo/ignore.go Adds a .armisignore size limit check before reading ignore files.
internal/scan/repo/ignore_test.go Adds a test ensuring oversized .armisignore files produce an error.
go.mod Updates go-git dependency version for CVE remediation.
go.sum Updates checksums for the new go-git version.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 34 to 38
if !info.IsDir() && info.Name() == ".armisignore" {
if info.Size() > maxIgnoreFileSize {
return fmt.Errorf(".armisignore file too large (%d bytes, max %d): %s", info.Size(), maxIgnoreFileSize, path)
}
patterns, err := loadIgnoreFile(path, repoRoot)
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The size guard is based on the os.FileInfo returned by filepath.Walk (which uses Lstat) and is checked before os.ReadFile. This can be bypassed by a symlink named .armisignore pointing to a large file (symlink size is small but ReadFile follows it), and it’s also a TOCTOU window if the file grows after the check. Consider enforcing the limit in loadIgnoreFile by opening the file and reading via a bounded reader (e.g., io.LimitReader) and/or rejecting symlinks explicitly, so the limit applies to the actual bytes read.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 31, 2026

Armis AppSecArmis AppSec Security Scan Results

✅ No issues

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 31, 2026

Test Coverage Report

total: (statements) 81.1%

Coverage by function
github.com/ArmisSecurity/armis-cli/cmd/armis-cli/main.go:19:			main					0.0%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:61:			copyWithContext				70.4%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:134:			WithHTTPClient				100.0%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:143:			WithUploadHTTPClient			100.0%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:151:			WithAllowLocalURLs			100.0%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:163:			NewClient				100.0%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:211:			IsDebug					100.0%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:225:			setAuthHeader				77.8%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:259:			StartIngest				72.3%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:418:			GetIngestStatus				82.6%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:459:			WaitForIngest				84.6%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:510:			FetchNormalizedResults			74.2%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:565:			FetchAllNormalizedResults		91.7%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:590:			GetScanResult				68.4%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:625:			WaitForScan				90.0%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:646:			formatBytes				100.0%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:668:			FetchArtifactScanResults		75.0%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:723:			ValidatePresignedURL			100.0%
github.com/ArmisSecurity/armis-cli/internal/api/client.go:759:			DownloadFromPresignedURL		84.2%
github.com/ArmisSecurity/armis-cli/internal/auth/auth.go:58:			NewAuthProvider				95.2%
github.com/ArmisSecurity/armis-cli/internal/auth/auth.go:104:			GetAuthorizationHeader			100.0%
github.com/ArmisSecurity/armis-cli/internal/auth/auth.go:124:			GetTenantID				85.7%
github.com/ArmisSecurity/armis-cli/internal/auth/auth.go:141:			GetRegion				85.7%
github.com/ArmisSecurity/armis-cli/internal/auth/auth.go:156:			IsLegacy				100.0%
github.com/ArmisSecurity/armis-cli/internal/auth/auth.go:169:			GetRawToken				85.7%
github.com/ArmisSecurity/armis-cli/internal/auth/auth.go:196:			exchangeCredentials			87.9%
github.com/ArmisSecurity/armis-cli/internal/auth/auth.go:267:			refreshIfNeeded				100.0%
github.com/ArmisSecurity/armis-cli/internal/auth/auth.go:297:			parseJWTClaims				93.3%
github.com/ArmisSecurity/armis-cli/internal/auth/client.go:29:			Error					100.0%
github.com/ArmisSecurity/armis-cli/internal/auth/client.go:41:			NewAuthClient				100.0%
github.com/ArmisSecurity/armis-cli/internal/auth/client.go:97:			Authenticate				77.4%
github.com/ArmisSecurity/armis-cli/internal/auth/region_cache.go:34:		NewRegionCache				100.0%
github.com/ArmisSecurity/armis-cli/internal/auth/region_cache.go:40:		Load					82.4%
github.com/ArmisSecurity/armis-cli/internal/auth/region_cache.go:74:		Save					76.9%
github.com/ArmisSecurity/armis-cli/internal/auth/region_cache.go:104:		Clear					75.0%
github.com/ArmisSecurity/armis-cli/internal/auth/region_cache.go:114:		getFilePath				83.3%
github.com/ArmisSecurity/armis-cli/internal/auth/region_cache.go:131:		loadCachedRegion			100.0%
github.com/ArmisSecurity/armis-cli/internal/auth/region_cache.go:135:		saveCachedRegion			100.0%
github.com/ArmisSecurity/armis-cli/internal/auth/region_cache.go:139:		clearCachedRegion			100.0%
github.com/ArmisSecurity/armis-cli/internal/cli/color.go:60:			InitColors				85.2%
github.com/ArmisSecurity/armis-cli/internal/cli/color.go:107:			ColorsEnabled				100.0%
github.com/ArmisSecurity/armis-cli/internal/cli/color.go:113:			ColorsForced				100.0%
github.com/ArmisSecurity/armis-cli/internal/cli/color.go:119:			SetOutputToFile				100.0%
github.com/ArmisSecurity/armis-cli/internal/cli/color.go:125:			GetOutputToFile				0.0%
github.com/ArmisSecurity/armis-cli/internal/cli/color.go:129:			enableColors				100.0%
github.com/ArmisSecurity/armis-cli/internal/cli/color.go:136:			disableColors				100.0%
github.com/ArmisSecurity/armis-cli/internal/cli/color.go:151:			parseErrorMessage			92.9%
github.com/ArmisSecurity/armis-cli/internal/cli/color.go:182:			PrintError				100.0%
github.com/ArmisSecurity/armis-cli/internal/cli/color.go:195:			PrintErrorf				0.0%
github.com/ArmisSecurity/armis-cli/internal/cli/color.go:201:			PrintWarning				100.0%
github.com/ArmisSecurity/armis-cli/internal/cli/color.go:206:			PrintWarningf				100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/auth.go:33:			init					100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/auth.go:39:			runAuth					92.9%
github.com/ArmisSecurity/armis-cli/internal/cmd/context.go:24:			NewSignalContext			100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/context.go:33:			handleScanError				100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/help.go:30:			SetupHelp				91.7%
github.com/ArmisSecurity/armis-cli/internal/cmd/help.go:58:			styledUsageTemplate			100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/help.go:101:			defaultUsageTemplate			100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/help.go:108:			initColorsForHelp			35.3%
github.com/ArmisSecurity/armis-cli/internal/cmd/help.go:149:			styleHelpOutput				83.3%
github.com/ArmisSecurity/armis-cli/internal/cmd/output_helper.go:27:		Cleanup					100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/output_helper.go:53:		ResolveOutput				96.4%
github.com/ArmisSecurity/armis-cli/internal/cmd/root.go:149:			SetVersion				100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/root.go:157:			Execute					100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/root.go:161:			init					100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/root.go:192:			PrintUpdateNotification			81.2%
github.com/ArmisSecurity/armis-cli/internal/cmd/root.go:234:			printUpdateNotificationOnce		75.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/root.go:247:			getEnvOrDefault				100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/root.go:254:			getEnvOrDefaultInt			100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/root.go:264:			getAPIBaseURL				100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/root.go:277:			getAuthProvider				100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/root.go:289:			getPageLimit				100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/root.go:296:			validatePageLimit			100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/root.go:306:			validateFailOn				100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/root.go:324:			getFailOn				100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/scan.go:92:			init					100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/scan_image.go:152:		init					100.0%
github.com/ArmisSecurity/armis-cli/internal/cmd/scan_repo.go:188:		init					100.0%
github.com/ArmisSecurity/armis-cli/internal/httpclient/client.go:31:		NewClient				100.0%
github.com/ArmisSecurity/armis-cli/internal/httpclient/client.go:57:		Do					86.1%
github.com/ArmisSecurity/armis-cli/internal/output/errno_unix.go:12:		isSyncNotSupported			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:54:			wrapText				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:77:			wrapLine				91.7%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:115:		formatRecommendations			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:185:		wrapTextWithFirstLinePrefix		90.9%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:224:		write					66.7%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:255:		Write					89.5%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:285:		Format					100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:290:		FormatWithOptions			84.4%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:360:		SyncColors				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:364:		sortFindingsBySeverity			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:375:		loadSnippetFromFile			69.4%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:487:		formatCodeSnippetWithFrame		91.1%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:580:		truncatePlainLine			0.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:592:		highlightColumns			93.5%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:637:		scanDuration				89.5%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:670:		pluralize				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:679:		renderBriefStatus			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:719:		renderSummaryDashboard			56.4%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:800:		renderFindings				88.9%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:829:		renderFinding				69.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:919:		renderGroupedFindings			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:943:		groupFindings				96.8%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1000:		severityRank				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1007:		isGitRepo				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1014:		getGitBlame				38.1%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1051:		parseGitBlame				95.2%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1087:		maskEmail				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1110:		getTopLevelDomain			75.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1122:		getHumanDisplayTitle			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1136:		wrapTitle				93.9%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1195:		maskFixForDisplay			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1230:		formatFixSection			0.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1295:		formatProposedSnippet			0.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1378:		limitHunkContext			64.7%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1454:		parseDiffHunk				91.7%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1476:		parseDiffLines				94.6%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1567:		findInlineChanges			73.5%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1638:		computeLCS				92.3%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1690:		buildTokenPositions			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1706:		tokenizeLine				92.9%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1734:		isWordChar				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1741:		formatDiffWithColorsStyled		77.1%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1815:		extractDiffFilename			80.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1837:		formatDiffHunkLine			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1857:		formatDiffContextLine			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1868:		formatDiffRemoveLine			86.4%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1909:		formatDiffAddLine			86.4%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1951:		applyInlineHighlights			81.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:1993:		truncateDiffLine			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:2000:		truncateDiffLineWithFlag		66.7%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:2014:		adjustHighlightSpans			83.3%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:2036:		groupDiffHunks				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:2067:		collectRenderOps			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:2110:		renderChangeBlock			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:2169:		formatDiffHunkSeparator			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:2184:		formatValidationSection			0.0%
github.com/ArmisSecurity/armis-cli/internal/output/human.go:2241:		getExposureDescription			0.0%
github.com/ArmisSecurity/armis-cli/internal/output/icons.go:24:			GetConfidenceIcon			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/json.go:15:			Format					100.0%
github.com/ArmisSecurity/armis-cli/internal/output/json.go:24:			FormatWithOptions			66.7%
github.com/ArmisSecurity/armis-cli/internal/output/json.go:32:			formatWithDebug				0.0%
github.com/ArmisSecurity/armis-cli/internal/output/json.go:58:			maskScanResultForOutput			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/json.go:78:			maskFindingSecrets			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/junit.go:48:			Format					100.0%
github.com/ArmisSecurity/armis-cli/internal/output/junit.go:55:			FormatWithOptions			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/junit.go:63:			formatWithSeverities			83.3%
github.com/ArmisSecurity/armis-cli/internal/output/junit.go:88:			isFailureSeverity			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/junit.go:98:			convertToJUnitCasesWithSeverities	91.7%
github.com/ArmisSecurity/armis-cli/internal/output/junit.go:130:		countFailuresWithSeverities		100.0%
github.com/ArmisSecurity/armis-cli/internal/output/output.go:24:		Error					0.0%
github.com/ArmisSecurity/armis-cli/internal/output/output.go:44:		GetFormatter				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/output.go:60:		ShouldFail				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/output.go:78:		CheckExit				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/sarif.go:159:		stripMarkdown				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/sarif.go:170:		Format					100.0%
github.com/ArmisSecurity/armis-cli/internal/output/sarif.go:197:		buildRules				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/sarif.go:261:		convertToSarifResults			88.5%
github.com/ArmisSecurity/armis-cli/internal/output/sarif.go:351:		buildMessageText			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/sarif.go:358:		severityToSarifLevel			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/sarif.go:377:		severityToSecurityScore			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/sarif.go:395:		generateHelpURI				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/sarif.go:422:		convertFixToSarif			90.5%
github.com/ArmisSecurity/armis-cli/internal/output/sarif.go:539:		FormatWithOptions			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/styles.go:138:		DefaultStyles				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/styles.go:276:		NoColorStyles				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/styles.go:353:		GetStyles				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/styles.go:361:		SyncStylesWithColorMode			100.0%
github.com/ArmisSecurity/armis-cli/internal/output/styles.go:386:		GetSeverityText				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/styles.go:414:		TerminalWidth				33.3%
github.com/ArmisSecurity/armis-cli/internal/output/syntax.go:21:		GetLexer				100.0%
github.com/ArmisSecurity/armis-cli/internal/output/syntax.go:32:		GetChromaStyle				80.0%
github.com/ArmisSecurity/armis-cli/internal/output/syntax.go:45:		HighlightCode				81.2%
github.com/ArmisSecurity/armis-cli/internal/output/syntax.go:79:		HighlightLine				75.0%
github.com/ArmisSecurity/armis-cli/internal/output/syntax.go:88:		getTerminalFormatter			60.0%
github.com/ArmisSecurity/armis-cli/internal/output/syntax.go:103:		HighlightLineWithBackground		87.5%
github.com/ArmisSecurity/armis-cli/internal/output/syntax.go:126:		getBackgroundANSI			58.3%
github.com/ArmisSecurity/armis-cli/internal/output/syntax.go:158:		rgbToANSI256				0.0%
github.com/ArmisSecurity/armis-cli/internal/output/syntax.go:171:		parseHexColor				76.9%
github.com/ArmisSecurity/armis-cli/internal/output/writer.go:51:		validateOutputPath			92.3%
github.com/ArmisSecurity/armis-cli/internal/output/writer.go:88:		NewFileOutput				88.2%
github.com/ArmisSecurity/armis-cli/internal/output/writer.go:142:		Writer					100.0%
github.com/ArmisSecurity/armis-cli/internal/output/writer.go:147:		Close					100.0%
github.com/ArmisSecurity/armis-cli/internal/output/writer.go:164:		FormatFromExtension			100.0%
github.com/ArmisSecurity/armis-cli/internal/progress/progress.go:32:		IsCI					100.0%
github.com/ArmisSecurity/armis-cli/internal/progress/progress.go:60:		isTerminalWriter			100.0%
github.com/ArmisSecurity/armis-cli/internal/progress/progress.go:68:		NewReader				100.0%
github.com/ArmisSecurity/armis-cli/internal/progress/progress.go:83:		NewWriter				50.0%
github.com/ArmisSecurity/armis-cli/internal/progress/progress.go:117:		NewSpinner				100.0%
github.com/ArmisSecurity/armis-cli/internal/progress/progress.go:125:		NewSpinnerWithTimeout			100.0%
github.com/ArmisSecurity/armis-cli/internal/progress/progress.go:141:		NewSpinnerWithContext			100.0%
github.com/ArmisSecurity/armis-cli/internal/progress/progress.go:149:		SetWriter				100.0%
github.com/ArmisSecurity/armis-cli/internal/progress/progress.go:158:		Start					89.8%
github.com/ArmisSecurity/armis-cli/internal/progress/progress.go:268:		Stop					100.0%
github.com/ArmisSecurity/armis-cli/internal/progress/progress.go:303:		Update					100.0%
github.com/ArmisSecurity/armis-cli/internal/progress/progress.go:310:		GetElapsed				100.0%
github.com/ArmisSecurity/armis-cli/internal/progress/progress.go:317:		formatDuration				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/finding_type.go:9:		DeriveFindingType			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:46:		NewScanner				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:60:		WithPollInterval			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:66:		WithSBOMVEXOptions			0.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:73:		WithPullPolicy				0.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:79:		ScanImage				0.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:110:		ScanTarball				77.1%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:201:		exportImage				0.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:251:		isDockerAvailable			42.9%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:265:		getDockerCommand			75.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:274:		validateDockerCommand			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:282:		imageExistsLocally			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:290:		determinePullBehavior			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:306:		buildScanResult				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:333:		convertNormalizedFindings		85.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:456:		shouldFilterByExploitability		100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:475:		cleanDescription			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:494:		isEmptyFinding				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/image.go:509:		generateFindingTitle			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/image/validate.go:11:		validateImageName			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/mask.go:21:			MaskFixSecrets				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/files.go:26:		ParseFileList				87.5%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/files.go:41:		addFile					87.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/files.go:93:		Files					100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/files.go:98:		RepoRoot				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/files.go:103:		ValidateExistence			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/gitchanges.go:52:		GitChangedFiles				82.6%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/gitchanges.go:102:	gitRepoRoot				80.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/gitchanges.go:126:	changedUncommitted			41.7%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/gitchanges.go:155:	changedStaged				75.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/gitchanges.go:168:	validateRef				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/gitchanges.go:181:	changedSinceRef				75.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/gitchanges.go:204:	filterToScanPath			94.1%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/gitchanges.go:239:	runGit					91.7%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/gitchanges.go:265:	parseLines				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/gitchanges.go:285:	combineAndDedupe			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/ignore.go:23:		LoadIgnorePatterns			88.9%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/ignore.go:60:		loadIgnoreFile				88.5%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/ignore.go:105:		Match					100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/ignore.go:117:		shouldSkipDir				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:45:		NewScanner				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:59:		WithPollInterval			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:65:		WithIncludeFiles			0.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:71:		WithSBOMVEXOptions			0.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:77:		Scan					70.9%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:242:		tarGzDirectory				71.8%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:325:		isPathContained				75.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:334:		tarGzFiles				78.6%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:425:		safeAddSize				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:432:		calculateFilesSize			78.6%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:457:		calculateDirSize			79.2%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:501:		shouldSkip				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:532:		isTestFile				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:576:		buildScanResult				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:603:		convertNormalizedFindings		73.3%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:726:		shouldFilterByExploitability		100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:745:		cleanDescription			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:766:		generateFindingTitle			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/repo/repo.go:770:		isEmptyFinding				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/sbom_vex.go:38:		NewSBOMVEXDownloader			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/sbom_vex.go:50:		Download				85.2%
github.com/ArmisSecurity/armis-cli/internal/scan/sbom_vex.go:102:		downloadAndSave				77.8%
github.com/ArmisSecurity/armis-cli/internal/scan/status.go:16:			FormatScanStatus			100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/status.go:35:			FormatElapsed				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/status.go:48:			MapSeverity				100.0%
github.com/ArmisSecurity/armis-cli/internal/scan/testhelpers/findings.go:9:	CreateNormalizedFinding			0.0%
github.com/ArmisSecurity/armis-cli/internal/scan/testhelpers/findings.go:14:	CreateNormalizedFindingWithLabels	0.0%
github.com/ArmisSecurity/armis-cli/internal/scan/testhelpers/findings.go:19:	CreateNormalizedFindingFull		0.0%
github.com/ArmisSecurity/armis-cli/internal/scan/title.go:14:			GenerateFindingTitle			0.0%
github.com/ArmisSecurity/armis-cli/internal/update/update.go:63:		NewChecker				100.0%
github.com/ArmisSecurity/armis-cli/internal/update/update.go:79:		CheckCached				100.0%
github.com/ArmisSecurity/armis-cli/internal/update/update.go:97:		CheckInBackground			100.0%
github.com/ArmisSecurity/armis-cli/internal/update/update.go:117:		check					85.7%
github.com/ArmisSecurity/armis-cli/internal/update/update.go:160:		fetchLatestVersion			89.5%
github.com/ArmisSecurity/armis-cli/internal/update/update.go:193:		getCacheFilePath			66.7%
github.com/ArmisSecurity/armis-cli/internal/update/update.go:208:		readCache				84.6%
github.com/ArmisSecurity/armis-cli/internal/update/update.go:231:		writeCache				76.9%
github.com/ArmisSecurity/armis-cli/internal/update/update.go:254:		IsNewer					100.0%
github.com/ArmisSecurity/armis-cli/internal/update/update.go:277:		parseVersion				100.0%
github.com/ArmisSecurity/armis-cli/internal/update/update.go:300:		FormatNotification			100.0%
github.com/ArmisSecurity/armis-cli/internal/update/update.go:319:		getUpdateCommand			40.0%
github.com/ArmisSecurity/armis-cli/internal/util/cache.go:21:			GetCacheDir				75.0%
github.com/ArmisSecurity/armis-cli/internal/util/cache.go:41:			GetCacheFilePath			80.0%
github.com/ArmisSecurity/armis-cli/internal/util/format.go:7:			FormatCategory				100.0%
github.com/ArmisSecurity/armis-cli/internal/util/mask.go:109:			MaskSecretInLine			86.4%
github.com/ArmisSecurity/armis-cli/internal/util/mask.go:163:			maskValue				83.3%
github.com/ArmisSecurity/armis-cli/internal/util/mask.go:189:			MaskSecretInLines			100.0%
github.com/ArmisSecurity/armis-cli/internal/util/mask.go:203:			MaskSecretInMultiLineString		100.0%
github.com/ArmisSecurity/armis-cli/internal/util/mask.go:217:			MaskSecretsInStringMap			100.0%
github.com/ArmisSecurity/armis-cli/internal/util/path.go:13:			SanitizePath				90.9%
github.com/ArmisSecurity/armis-cli/internal/util/path.go:51:			SafeJoinPath				87.5%
github.com/ArmisSecurity/armis-cli/test/sample-repo/src/main.go:6:		main					0.0%
total:										(statements)				81.1%

Address Copilot review: the Walk-based info.Size() check was
bypassable via symlinks (Lstat returns symlink size, not target)
and had a TOCTOU window. Replace with:
- Reject symlinked .armisignore files in Walk callback
- Use io.LimitReader in loadIgnoreFile to enforce the 1MB cap
  on actual bytes read, eliminating both the symlink and TOCTOU
  bypass vectors
The Coverage Comment job failed with a transient GitHub API 503.
The github-script action defaults to 0 retries, so any transient
server error causes an immediate failure. Adding retries: 3 makes
the step resilient to temporary GitHub API outages.
Copilot AI review requested due to automatic review settings March 31, 2026 15:43
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 35 to +38
if !info.IsDir() && info.Name() == ".armisignore" {
if info.Mode()&os.ModeSymlink != 0 {
return fmt.Errorf(".armisignore is a symlink (rejected): %s", path)
}
Copy link

Copilot AI Mar 31, 2026

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 .armisignore files isn’t covered by a unit test. Since this is security-related behavior, add a test that creates a symlink .armisignore and asserts LoadIgnorePatterns returns an error (skip the test on platforms/environments where symlink creation isn’t permitted).

Copilot uses AI. Check for mistakes.
Cover the symlink rejection path in LoadIgnorePatterns with a test
that creates a symlinked .armisignore and asserts the expected error.
Skips gracefully on platforms where symlinks aren't supported.
@yiftach-armis yiftach-armis merged commit 3056c98 into main Mar 31, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants