fix(binding): skip unix mode audit on windows#1525
Conversation
📝 WalkthroughWalkthroughSplits ChangesWindows POSIX permission audit bypass
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
Fixes Windows exec-provider binding failures by avoiding Unix permission-bit audits on Windows, where Go’s synthesized POSIX mode bits don’t reflect NTFS ACL permissions.
Changes:
- Skip group/world permission-bit checks in
AssertSecurePathon Windows while retaining other secure-path checks (absolute path, not-a-directory, trusted dir, symlink handling, owner UID logic). - Add a regression test covering the “synthetic 0666” Windows-mode scenario.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| internal/binding/audit.go | Skips Unix permission-bit audit on Windows to prevent false “world-writable” failures. |
| internal/binding/audit_test.go | Adds a regression test to ensure Windows (or simulated Windows) ignores synthetic POSIX mode bits. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
evandance
left a comment
There was a problem hiding this comment.
Thanks for the fix — the diagnosis is right: on Windows Go synthesizes mode bits from the read-only attribute, so the world-writable check misfires; the early return is scoped to just the permission-bit audit, and the non-Windows path and the new regression test both look correct.
One change before merge: this package already expresses its other Unix-only check (file ownership) as a build-tagged no-op on Windows (audit_unix.go / audit_windows.go). Please land this POSIX-mode-audit skip the same way — as OS-compiled functions — rather than a runtime GOOS check plus a test-only package-level variable in the shared file. In a security-audit module, keeping the OS branch compile-time and avoiding a mutable global is more consistent with the existing structure.
Please also add a line to the PR description noting the trade-off: on Windows the inapplicable POSIX mode audit is skipped, but the absolute-path, non-directory, symlink, and trusted-dir checks still run; real NTFS ACL auditing can be a follow-up enhancement.
With those two addressed, I have no other blocking comments at the code level; merge will still need a sync with main and a green CI run.
🚀 PR Preview Install Guide🧰 CLI updatenpm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@f114038a548696dc93398585b84663b74272569c🧩 Skill updatenpx skills add Zhang-986/cli#codex/windows-exec-audit-permissions -y -g |
373da58 to
f114038
Compare
|
Addressed the requested changes:
Local checks run:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/binding/audit_unix.go`:
- Around line 36-40: The error handling in the auditFilePermissions function
when vfs.Stat fails uses fmt.Errorf which downgrades error classification and
loses type information. Replace the fmt.Errorf call that wraps the vfs.Stat
error with errs.NewInternalError(errs.SubtypeFileIO, ...) to use a typed error,
and chain the original error using .WithCause(err) to preserve the underlying
cause while maintaining proper error classification for command-facing
validation.
In `@internal/binding/audit_windows.go`:
- Around line 21-24: The error handling in the auditFilePermissions function on
the vfs.Stat call is using fmt.Errorf instead of the typed error contract
required for command-facing failures. Replace the fmt.Errorf call with
errs.NewInternalError(errs.SubtypeFileIO, ...) to provide a descriptive message,
and chain it with .WithCause(err) to preserve the underlying stat error for
debugging purposes.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 752f8099-282f-4902-a408-d61a6681d386
📒 Files selected for processing (4)
internal/binding/audit.gointernal/binding/audit_unix.gointernal/binding/audit_windows.gointernal/binding/audit_windows_test.go
💤 Files with no reviewable changes (1)
- internal/binding/audit.go
✅ Files skipped from review due to trivial changes (1)
- internal/binding/audit_windows_test.go
evandance
left a comment
There was a problem hiding this comment.
Thanks for the quick reshape — the build-tag split is exactly right and the non-Windows path is unchanged. LGTM.
Summary
Fix Windows exec provider binding failures caused by treating synthesized POSIX mode bits as real NTFS permissions. On Windows, Go reports writable regular files as mode 0666 based on file attributes, which made secure exec providers fail the world-writable audit even when the file was not broadly writable by ACL.
Changes
lark-channel-bridgeexec provider wrappers.Test Plan
GOTOOLCHAIN=go1.23.12 make unit-testgo test ./internal/binding -run TestAssertSecurePath -count=1go test ./internal/binding ./internal/transport -count=1go test -race ./internal/binding -count=1GOOS=windows GOARCH=amd64 go test -c ./internal/binding -o /tmp/larksuite-cli-binding.test.exego vet ./...,gofmt -l .,git diff --checkgo run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6 run --new-from-rev=upstream/mainRelated Issues
Summary by CodeRabbit
Bug Fixes
Tests