#13471: fix: security audit distinguishes internal hooks from external webhooks
stale
Cluster:
Security Enhancements and Guardrails
## Problem
`openclaw security audit` reports `hooks: disabled` even when internal (bundled) hooks are enabled and active. This is because the check only looks at `hooks.enabled` (the external webhook endpoint flag) and ignores `hooks.internal.enabled`.
Fixes #13466
## Changes
In `src/security/audit-extra.sync.ts`, the hooks status now distinguishes between:
- **`webhooks: enabled`** — external webhook endpoint is on
- **`webhooks: disabled, internal: enabled (N active)`** — external webhooks off but internal hooks are running
- **`disabled`** — both systems off
## Before / After
**Before:**
```
hooks: disabled
```
**After** (with 2 internal hooks active):
```
hooks: webhooks: disabled, internal: enabled (2 active)
```
## Testing
Tested against a live gateway running v2026.2.9 with `hooks.internal.enabled: true` and two active internal hooks (`session-memory`, `command-logger`). Before the fix, audit showed `hooks: disabled`; after, it correctly reflects the internal hooks state.
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates the security audit “attack surface summary” to report hooks in a more granular way:
- Distinguishes external webhook endpoint state (`hooks.enabled`) from internal/bundled hooks (`hooks.internal.enabled`).
- Includes an “N active” count for internal hook entries when internal hooks are enabled.
The change is localized to `collectAttackSurfaceSummaryFindings` (used by `runSecurityAudit` in `src/security/audit.ts`).
One correctness issue remains: the new internal hook activity count is computed only from `hooks.internal.entries`, but the runtime hook loader also supports legacy `hooks.internal.handlers`. In configs using only legacy handlers, audit will still show `hooks: disabled` even though internal hooks will load and run.
<h3>Confidence Score: 4/5</h3>
- Mostly safe to merge, but hook status may be incorrect for legacy internal hook configs.
- The change is small and isolated, but the internal hook “active” detection only considers `hooks.internal.entries` while the runtime loader also supports `hooks.internal.handlers`, which can lead to incorrect audit output in real configurations.
- src/security/audit-extra.sync.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#6405: feat(security): Add HTTP API security hooks for plugin scanning
by masterfung · 2026-02-01
78.1%
#23019: fix(hooks): use globalThis singleton for internal hooks handlers Map
by karmafeast · 2026-02-21
77.4%
#11339: fix: resolve bundled hooks path on npm global install
by matthewpoe · 2026-02-07
77.4%
#19690: fix: security audit suppression, MoE false positive, and hook prefi...
by adityuhkapoor · 2026-02-18
77.2%
#11817: fix(build): compile bundled hook handlers into dist
by AnonO6 · 2026-02-08
76.0%
#15877: fix(hooks): add debug logging to triggerInternalHook
by Shuai-DaiDai · 2026-02-14
75.9%
#11778: fix(plugins): enforce monotonic hook deny merges
by coygeek · 2026-02-08
75.4%
#9914: fix(hooks): resolve bundled hook dist paths and packaging checks
by zimmra · 2026-02-05
75.2%
#14746: fix(hooks): use globalThis for handler registry to survive bundler ...
by openperf · 2026-02-12
75.2%
#17930: fix: evaluate tool_result_persist hooks lazily to avoid race condition
by TheArkifaneVashtorr · 2026-02-16
75.1%