openclaw - ✅(Solved) Fix [Security] Windows ACL audit bypass: Anonymous and Guest SIDs are misclassified as "group" instead of "world" [3 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#74350Fetched 2026-04-30 06:25:10
View on GitHub
Comments
2
Participants
2
Timeline
6
Reactions
2
Timeline (top)
cross-referenced ×3commented ×2referenced ×1

In the Windows file permission auditing mechanism (src/security/windows-acl.ts), the classifyPrincipal function categorizes Windows ACL entries into trusted, world, or group.

Currently, WORLD_PRINCIPALS and WORLD_SIDS strictly cover Everyone (S-1-1-0), Authenticated Users (S-1-5-11), and Users (S-1-5-32-545).

However, it omits several critical Well-Known SIDs that represent unauthenticated or extremely broad access. If a sensitive file (e.g., config, credentials, or agent harnesses) grants write access to Anonymous Logon or Guests, classifyPrincipal falls through the WORLD_* checks and mistakenly categorizes them as just group.

Consequently, in src/security/audit-fs.ts:

worldWritable: acl.untrustedWorld.some((entry) => entry.canWrite), // Evaluates to FALSE
groupWritable: acl.untrustedGroup.some((entry) => entry.canWrite), // Evaluates to TRUE

This causes worldWritable to return false for files that are practically writable by anyone (including entirely unauthenticated actors), potentially bypassing strict worldWritable audit guards during OpenClaw's security scans.

Root Cause

In the Windows file permission auditing mechanism (src/security/windows-acl.ts), the classifyPrincipal function categorizes Windows ACL entries into trusted, world, or group.

Currently, WORLD_PRINCIPALS and WORLD_SIDS strictly cover Everyone (S-1-1-0), Authenticated Users (S-1-5-11), and Users (S-1-5-32-545).

However, it omits several critical Well-Known SIDs that represent unauthenticated or extremely broad access. If a sensitive file (e.g., config, credentials, or agent harnesses) grants write access to Anonymous Logon or Guests, classifyPrincipal falls through the WORLD_* checks and mistakenly categorizes them as just group.

Consequently, in src/security/audit-fs.ts:

worldWritable: acl.untrustedWorld.some((entry) => entry.canWrite), // Evaluates to FALSE
groupWritable: acl.untrustedGroup.some((entry) => entry.canWrite), // Evaluates to TRUE

This causes worldWritable to return false for files that are practically writable by anyone (including entirely unauthenticated actors), potentially bypassing strict worldWritable audit guards during OpenClaw's security scans.

Fix Action

Fixed

PR fix notes

PR #74383: fix(security): classify broad Windows SIDs as world principals

Description (problem / solution / changelog)

Made-with: Cursor

Summary

  • Problem: Windows ACL audit currently classifies several broad/unauthenticated principals (for example Anonymous Logon, BUILTIN\Guests) as group instead of world.
  • Why it matters: This can downgrade filesystem findings from worldWritable (critical) to groupWritable (warn), reducing severity for effectively world-accessible paths.
  • What changed: Expanded Windows world-equivalent SID/principal lists and added regression tests at both classifier and filesystem-audit levels.
  • What did NOT change (scope boundary): No POSIX permission logic changes, no ACL parsing format changes, no unrelated security policy changes.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #74350
  • Related #74350
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: classifyPrincipal only treated a narrow world-equivalent set as world (Everyone, Authenticated Users, BUILTIN\Users), so other broad-access principals fell through to group.
  • Missing detection / guardrail: Tests did not cover classification for S-1-5-7, S-1-5-32-546, S-1-5-4, S-1-2-0, S-1-5-2, or audit severity impact from those entries.
  • Contributing context (if known): Audit findings differentiate worldWritable (critical) and groupWritable (warn), so misclassification directly affects security signal strength.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
    • src/security/windows-acl.test.ts
    • src/security/audit-filesystem-windows.test.ts
  • Scenario the test should lock in:
    • Added SIDs are classified into untrustedWorld (not untrustedGroup).
    • A Windows state-dir ACL using *S-1-5-7:(F) triggers fs.state_dir.perms_world_writable with critical severity.
  • Why this is the smallest reliable guardrail:
    • The bug is in ACL principal classification and filesystem finding mapping; these tests hit both directly without requiring host-specific E2E setup.
  • Existing test that already covers this (if any):
    • Existing SID tests covered only a narrower world SID set.
  • If no new test is added, why not:
    • N/A (new tests added).

User-visible / Behavior Changes

  • On Windows, ACL entries for broad principals such as Anonymous Logon, Guests, Interactive, Local, and Network are now treated as world-equivalent in security audit classification.
  • Security audit can now correctly elevate affected state-dir findings to worldWritable critical severity.

Diagram (if applicable)

Before:
[state dir ACL includes *S-1-5-7:(F)] -> [classified as group] -> [groupWritable warn]

After:
[state dir ACL includes *S-1-5-7:(F)] -> [classified as world] -> [worldWritable critical]

## Changed files

- `src/security/audit-filesystem-windows.test.ts` (modified, +36/-0)
- `src/security/windows-acl.test.ts` (modified, +65/-0)
- `src/security/windows-acl.ts` (modified, +24/-1)


---

# PR #74400: fix(security): classify Anonymous/Guests/Interactive/Local/Network as world in Windows ACL audit (#74350)

- Repository: openclaw/openclaw
- Author: hclsys
- State: closed | merged: False
- Link: https://github.com/openclaw/openclaw/pull/74400

## Description (problem / solution / changelog)

## Root cause

`summarizeWindowsAcl` classifies a Windows ACL entry as `world` only when the principal matches `Everyone`, `Authenticated Users`, or `BUILTIN\Users`. Principals like **Anonymous Logon** (`S-1-5-7`), **BUILTIN\Guests** (`S-1-5-32-546`), **Interactive** (`S-1-5-4`), **Local** (`S-1-2-0`), and **Network** (`S-1-5-2`) fell through to `untrustedGroup`, silently passing `worldWritable` audit guards even when they had Full Control.

## Fix

Add 5 SIDs to `WORLD_SIDS` and 9 principal-name variants to `WORLD_PRINCIPALS`:

**New SIDs:**
- `s-1-5-7` — Anonymous Logon
- `s-1-5-32-546` — BUILTIN\Guests
- `s-1-5-4` — Interactive
- `s-1-2-0` — Local
- `s-1-5-2` — Network

**New principal names:** `anonymous logon`, `anonymous`, `guests`, `builtin\guests`, `interactive`, `local`, `network`, `nt authority\interactive`, `nt authority\network`

All five principals give unauthenticated or broad-access coverage equivalent to world-access semantics. Including them closes the audit bypass without changing behavior for genuinely trusted groups.

## Tests

7 new regression tests in `windows-acl.test.ts` covering both raw-SID (`/sid S-1-5-7`) and localized-name shapes for each newly-classified principal.

Fixes #74350. Thanks @clawsweeper (confirmed bug live).

## Changed files

- `CHANGELOG.md` (modified, +1/-0)
- `src/security/windows-acl.test.ts` (modified, +91/-0)
- `src/security/windows-acl.ts` (modified, +33/-1)


---

# PR #74407: fix(onboard): clarify keyed vs keyless skill setup prompts

- Repository: openclaw/openclaw
- Author: dwc1997
- State: open | merged: False
- Link: https://github.com/openclaw/openclaw/pull/74407

## Description (problem / solution / changelog)

Made-with: Cursor

## Summary

- Problem: `openclaw onboard` can show keyless skill dependency install options (for example local `openai-whisper`) and later ask for API keys for different keyed skills, which is easy to misread as contradictory.
- Why it matters: Users may think onboarding is requesting unnecessary secrets, reducing trust and increasing setup friction.
- What changed: Added a dedicated "Skill credentials" note that explicitly separates dependency installation from credential setup, and lists only skills that actually require env secrets.
- What did NOT change: No skill capability semantics changed; no security ACL logic changed; no install backend behavior changed.

## Linked Issue/PR

- Closes #74382
- Related #74382
- [x] This PR fixes a bug or regression

## Root Cause

- Root cause: Onboarding mixed install and credential steps without an explicit transition note, so keyless/keyed skills appeared conflated in the user flow.
- Missing guardrail: No regression test covered a mixed keyless (`openai-whisper`) + keyed (`openai-whisper-api`, `sag`) scenario.

## Regression Test Plan

- Coverage: Unit test
- Target: `src/commands/onboard-skills.test.ts`
- Scenario: Mixed keyless + keyed skills only prompts for keyed env vars and shows a credentials summary note.

## User-visible / Behavior Changes

- Onboarding now shows a "Skill credentials" note before secret prompts.
- Secret prompts only target skills with missing required env vars.

## Security Impact

- New permissions/capabilities? No
- Secrets/tokens handling changed? No (prompt clarity only)
- New/changed network calls? No
- Command/tool execution surface changed? No
- Data access scope changed? No

## Changed files

- `src/commands/onboard-skills.test.ts` (modified, +103/-0)
- `src/commands/onboard-skills.ts` (modified, +17/-4)

Code Example

worldWritable: acl.untrustedWorld.some((entry) => entry.canWrite), // Evaluates to FALSE
groupWritable: acl.untrustedGroup.some((entry) => entry.canWrite), // Evaluates to TRUE

---

const WORLD_SIDS = new Set([
  "s-1-1-0",        // Everyone
  "s-1-5-11",       // Authenticated Users
  "s-1-5-32-545",   // BUILTIN\Users
  "s-1-5-7",        // Anonymous Logon
  "s-1-5-32-546",   // BUILTIN\Guests
  "s-1-5-4",        // Interactive
  "s-1-2-0",        // Local
  "s-1-5-2"         // Network
]);

const WORLD_PRINCIPALS = new Set([
  "everyone",
  "users",
  "builtin\\users",
  "authenticated users",
  "nt authority\\authenticated users",
  "anonymous logon",
  "nt authority\\anonymous logon",
  "guests",
  "builtin\\guests",
  "interactive",
  "nt authority\\interactive",
  "network",
  "nt authority\\network",
  "local"
]);
RAW_BUFFERClick to expand / collapse

Description

In the Windows file permission auditing mechanism (src/security/windows-acl.ts), the classifyPrincipal function categorizes Windows ACL entries into trusted, world, or group.

Currently, WORLD_PRINCIPALS and WORLD_SIDS strictly cover Everyone (S-1-1-0), Authenticated Users (S-1-5-11), and Users (S-1-5-32-545).

However, it omits several critical Well-Known SIDs that represent unauthenticated or extremely broad access. If a sensitive file (e.g., config, credentials, or agent harnesses) grants write access to Anonymous Logon or Guests, classifyPrincipal falls through the WORLD_* checks and mistakenly categorizes them as just group.

Consequently, in src/security/audit-fs.ts:

worldWritable: acl.untrustedWorld.some((entry) => entry.canWrite), // Evaluates to FALSE
groupWritable: acl.untrustedGroup.some((entry) => entry.canWrite), // Evaluates to TRUE

This causes worldWritable to return false for files that are practically writable by anyone (including entirely unauthenticated actors), potentially bypassing strict worldWritable audit guards during OpenClaw's security scans.

Missing Critical SIDs / Principals

The following should be considered "world" equivalent to prevent audit bypasses:

  • S-1-5-7 / anonymous logon (Any user connected without supplying credentials)
  • S-1-5-32-546 / builtin\guests, guests (Guest privileges)
  • S-1-5-4 / interactive (Any user logging on locally)
  • S-1-2-0 / local (Local Terminal Users)
  • S-1-5-2 / network (Network Logon Users)

Steps to Reproduce

  1. Create a sensitive file in a Windows environment where OpenClaw runs.
  2. Use icacls to grant Full Control exclusively to Anonymous Logon (S-1-5-7).
  3. Run OpenClaw's security scanner (inspectPathPermissions / safeStat).
  4. Observation: The audit returns worldWritable: false and groupWritable: true.
  5. Expected: It should return worldWritable: true due to the unauthenticated nature of the principal.

Proposed Fix

Append the missing unauthenticated/broad-access SIDs and string constants to WORLD_SIDS and WORLD_PRINCIPALS in src/security/windows-acl.ts:

const WORLD_SIDS = new Set([
  "s-1-1-0",        // Everyone
  "s-1-5-11",       // Authenticated Users
  "s-1-5-32-545",   // BUILTIN\Users
  "s-1-5-7",        // Anonymous Logon
  "s-1-5-32-546",   // BUILTIN\Guests
  "s-1-5-4",        // Interactive
  "s-1-2-0",        // Local
  "s-1-5-2"         // Network
]);

const WORLD_PRINCIPALS = new Set([
  "everyone",
  "users",
  "builtin\\users",
  "authenticated users",
  "nt authority\\authenticated users",
  "anonymous logon",
  "nt authority\\anonymous logon",
  "guests",
  "builtin\\guests",
  "interactive",
  "nt authority\\interactive",
  "network",
  "nt authority\\network",
  "local"
]);

extent analysis

TL;DR

Update the WORLD_SIDS and WORLD_PRINCIPALS sets in src/security/windows-acl.ts to include the missing critical Well-Known SIDs and principals.

Guidance

  • Verify that the classifyPrincipal function correctly categorizes Windows ACL entries into trusted, world, or group after updating the WORLD_SIDS and WORLD_PRINCIPALS sets.
  • Test the updated function with the provided Steps to Reproduce to ensure that the audit returns the expected result (worldWritable: true) for files with write access granted to unauthenticated or broad-access principals.
  • Review the inspectPathPermissions and safeStat functions in src/security/audit-fs.ts to ensure they correctly handle the updated worldWritable and groupWritable values.
  • Consider adding additional test cases to cover different scenarios and ensure the fix does not introduce any regressions.

Example

The proposed fix includes the updated WORLD_SIDS and WORLD_PRINCIPALS sets:

const WORLD_SIDS = new Set([
  "s-1-1-0",        // Everyone
  "s-1-5-11",       // Authenticated Users
  "s-1-5-32-545",   // BUILTIN\Users
  "s-1-5-7",        // Anonymous Logon
  "s-1-5-32-546",   // BUILTIN\Guests
  "s-1-5-4",        // Interactive
  "s-1-2-0",        // Local
  "s-1-5-2"         // Network
]);

const WORLD_PRINCIPALS = new Set([
  "everyone",
  "users",
  "builtin\\users",
  "authenticated users",
  "nt authority\\authenticated users",

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING