Skip to content

chore: update workflow permissions and code scanning reports#2984

Open
yashmehrotra wants to merge 2 commits intomainfrom
sec2
Open

chore: update workflow permissions and code scanning reports#2984
yashmehrotra wants to merge 2 commits intomainfrom
sec2

Conversation

@yashmehrotra
Copy link
Copy Markdown
Member

@yashmehrotra yashmehrotra commented Apr 17, 2026

Summary by CodeRabbit

  • Refactor

    • Improved safe path-joining and file-write validation used by snapshot exports.
  • Chores

    • Scoped and clarified GitHub Actions permissions at workflow and job levels across CI/CD.
    • Pinned a CI/CD action to a fixed commit for reproducible runs.
    • Updated a runtime dependency for report generation.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 17, 2026

Walkthrough

Adds explicit GitHub Actions workflow- and job-level permission scopes and pins an action; updates a runtime dependency version; adds a new SafeJoin utility and replaces direct filepath.Join usage in snapshot writer to enforce safe path composition.

Changes

Cohort / File(s) Summary
GitHub Actions Workflows
.github/workflows/auto-approve.yml, .github/workflows/release.yml, .github/workflows/test.yml
Introduced workflow-level permissions and job-level overrides (e.g., contents: read at top level; some jobs request contents: write); moved some write perms from top-level to job-level; pinned oven-sh/setup-bun in test.yml.
Path Safety Utility & Usage
utils/dir.go, snapshot/writer.go
Added exported SafeJoin(pathPrefix, name string) (string, error) that resolves and verifies target stays inside base directory; replaced filepath.Join calls with utils.SafeJoin in writer and propagate errors on join failures.
Dependency Update
report/package.json
Bumped @flanksource/facet from ^0.1.10 to ^0.1.39.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: workflow permission updates across multiple files and a dependency bump for code scanning reports.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sec2
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch sec2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@socket-security
Copy link
Copy Markdown

socket-security bot commented Apr 17, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​lodash@​4.17.23 ⏵ 4.18.176 +1100 +1887 +188100
Updatednpm/​@​flanksource/​facet@​0.1.10 ⏵ 0.1.3979 +2100100 +194 +8100

View full report

@socket-security
Copy link
Copy Markdown

socket-security bot commented Apr 17, 2026

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm pdf-lib is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: report/package-lock.jsonnpm/@flanksource/facet@0.1.39npm/pdf-lib@1.17.1

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/pdf-lib@1.17.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/test.yml (1)

88-89: Consider adding explicit permissions to the e2e job.

The e2e job has no permissions block, so it inherits the top-level contents: read (line 3-4). That is sufficient for current steps (checkout + tests), but for consistency with the hardening applied to test/release.yml jobs, consider declaring it explicitly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/test.yml around lines 88 - 89, Add an explicit permissions
block to the e2e job so it doesn't rely on top-level defaults: in the e2e job
definition (job name "e2e") add a permissions section granting at minimum
contents: read (to match the hardening used in the other jobs such as "test" and
"release.yml"); ensure the new permissions block is properly indented under the
e2e job so actions/checkout and test steps retain read-only access.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@utils/dir.go`:
- Around line 9-14: SafeJoin currently allows names like "." or ".." through
because filepath.Base returns them; update SafeJoin to sanitize/reject those
cases by computing b := filepath.Base(name) (after filepath.Clean) and if b ==
"." || b == ".." || strings.ContainsRune(b, os.PathSeparator) then replace b
with a safe fallback (e.g. a constant like "_" or an escaped form) or return the
pathPrefix-only result; ensure you use filepath.Clean and os.PathSeparator
checks and keep the function signature (SafeJoin) unchanged so callers continue
to receive a safe, non-traversing joined path.

---

Nitpick comments:
In @.github/workflows/test.yml:
- Around line 88-89: Add an explicit permissions block to the e2e job so it
doesn't rely on top-level defaults: in the e2e job definition (job name "e2e")
add a permissions section granting at minimum contents: read (to match the
hardening used in the other jobs such as "test" and "release.yml"); ensure the
new permissions block is properly indented under the e2e job so actions/checkout
and test steps retain read-only access.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 627735e2-0f37-46be-b388-d617d3f6a4e1

📥 Commits

Reviewing files that changed from the base of the PR and between a809b15 and f2103d2.

⛔ Files ignored due to path filters (1)
  • report/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • .github/workflows/auto-approve.yml
  • .github/workflows/release.yml
  • .github/workflows/test.yml
  • report/package.json
  • snapshot/writer.go
  • utils/dir.go

Comment thread utils/dir.go Outdated
Comment thread snapshot/writer.go Fixed
…ata used in path expression

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
utils/dir.go (1)

26-26: Simplify the traversal check with strings.HasPrefix.

The current expression relies on Go's operator precedence (&& binds tighter than ||) and manual slicing, which is easy to misread. Since filepath.Rel returns a cleaned path, strings.HasPrefix(rel, "..") combined with a boundary check is both clearer and equivalent.

-	if rel == ".." || len(rel) >= 3 && rel[:3] == ".."+string(filepath.Separator) {
+	if rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) {
 		return "", fmt.Errorf("invalid path: outside base directory")
 	}

Requires adding "strings" to the import block.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@utils/dir.go` at line 26, The traversal-check using `if rel == ".." ||
len(rel) >= 3 && rel[:3] == ".."+string(filepath.Separator)` is hard to read and
fragile; replace it with a clearer prefix check using strings.HasPrefix(rel,
"..") while preserving the boundary behavior (since filepath.Rel returns cleaned
paths) and update the surrounding logic in the same function that calls
`filepath.Rel`/uses `rel`; also add the "strings" import to the import block.
Ensure you reference and modify the exact check expression so behavior remains
equivalent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@utils/dir.go`:
- Around line 11-31: SafeJoin currently compares lexical paths only and can be
bypassed via symlinks; modify SafeJoin to resolve symlinks on both the base and
the target before performing the filepath.Rel check by using
filepath.EvalSymlinks (or if the full target does not yet exist, walk up to the
deepest existing ancestor of targetAbs and EvalSymlinks that ancestor) so the
rel computation is done on real paths; ensure errors from EvalSymlinks are
handled and included in returned errors and keep the same return values from
SafeJoin.

---

Nitpick comments:
In `@utils/dir.go`:
- Line 26: The traversal-check using `if rel == ".." || len(rel) >= 3 && rel[:3]
== ".."+string(filepath.Separator)` is hard to read and fragile; replace it with
a clearer prefix check using strings.HasPrefix(rel, "..") while preserving the
boundary behavior (since filepath.Rel returns cleaned paths) and update the
surrounding logic in the same function that calls `filepath.Rel`/uses `rel`;
also add the "strings" import to the import block. Ensure you reference and
modify the exact check expression so behavior remains equivalent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 05b504a0-599b-4699-8977-e58800be83ac

📥 Commits

Reviewing files that changed from the base of the PR and between f2103d2 and 8b33888.

⛔ Files ignored due to path filters (1)
  • report/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • .github/workflows/auto-approve.yml
  • .github/workflows/release.yml
  • .github/workflows/test.yml
  • report/package.json
  • snapshot/writer.go
  • utils/dir.go
✅ Files skipped from review due to trivial changes (3)
  • report/package.json
  • .github/workflows/auto-approve.yml
  • .github/workflows/release.yml
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/test.yml
  • snapshot/writer.go

Comment thread utils/dir.go
Comment on lines +11 to +31
func SafeJoin(pathPrefix, name string) (string, error) {
baseAbs, err := filepath.Abs(filepath.Clean(pathPrefix))
if err != nil {
return "", fmt.Errorf("failed to resolve base path: %w", err)
}

targetAbs, err := filepath.Abs(filepath.Join(baseAbs, name))
if err != nil {
return "", fmt.Errorf("failed to resolve target path: %w", err)
}

rel, err := filepath.Rel(baseAbs, targetAbs)
if err != nil {
return "", fmt.Errorf("failed to verify target path: %w", err)
}
if rel == ".." || len(rel) >= 3 && rel[:3] == ".."+string(filepath.Separator) {
return "", fmt.Errorf("invalid path: outside base directory")
}

return targetAbs, nil
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

SafeJoin does not resolve symlinks, so traversal via symlinks is still possible.

Unlike safeReadFile in playbook/actions/ai.go (which uses filepath.EvalSymlinks before filepath.Rel), SafeJoin compares lexical paths only. If pathPrefix (or any component under it) contains a symlink that points outside the base directory, a name that traverses through it will pass the filepath.Rel check and return an absolute path that actually resolves outside pathPrefix.

For the current snapshot-writer callers this is not exploitable (names are constructed internally), but the doc comment advertises this as a guard against user-controlled input, and the relevant snippets flag views/render_facet.go and playbook/actions/ai.go as candidate call-sites where attacker-influenced inputs flow in. Consider resolving symlinks before the Rel check, or documenting explicitly that the helper assumes a symlink-free base.

🛡️ Suggested hardening
 func SafeJoin(pathPrefix, name string) (string, error) {
-	baseAbs, err := filepath.Abs(filepath.Clean(pathPrefix))
+	baseAbs, err := filepath.Abs(pathPrefix)
 	if err != nil {
 		return "", fmt.Errorf("failed to resolve base path: %w", err)
 	}
+	if resolved, err := filepath.EvalSymlinks(baseAbs); err == nil {
+		baseAbs = resolved
+	}
 
-	targetAbs, err := filepath.Abs(filepath.Join(baseAbs, name))
+	targetAbs, err := filepath.Abs(filepath.Join(baseAbs, name))
 	if err != nil {
 		return "", fmt.Errorf("failed to resolve target path: %w", err)
 	}
+	if resolved, err := filepath.EvalSymlinks(targetAbs); err == nil {
+		targetAbs = resolved
+	}
 
 	rel, err := filepath.Rel(baseAbs, targetAbs)
 	if err != nil {
 		return "", fmt.Errorf("failed to verify target path: %w", err)
 	}
-	if rel == ".." || len(rel) >= 3 && rel[:3] == ".."+string(filepath.Separator) {
+	if rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) {
 		return "", fmt.Errorf("invalid path: outside base directory")
 	}

Note: EvalSymlinks fails if the target does not yet exist (common when the helper is used to compute an output path). In that case you typically want to resolve the deepest existing ancestor instead of the full targetAbs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@utils/dir.go` around lines 11 - 31, SafeJoin currently compares lexical paths
only and can be bypassed via symlinks; modify SafeJoin to resolve symlinks on
both the base and the target before performing the filepath.Rel check by using
filepath.EvalSymlinks (or if the full target does not yet exist, walk up to the
deepest existing ancestor of targetAbs and EvalSymlinks that ancestor) so the
rel computation is done on real paths; ensure errors from EvalSymlinks are
handled and included in returned errors and keep the same return values from
SafeJoin.

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