Commit d505fa0
committed
fix(models-config): security & correctness fixes from PR review
Five issues raised by Aisle / Codex / Greptile review on PR #72869,
addressed inline rather than deferred:
1. CWE-59 symlink-following chmod (Aisle high #1)
ensureModelsFileModeForModelsJson called fs.chmod on a path that
may be replaced by a symlink. If an attacker can write to the agent
dir (or OPENCLAW_AGENT_DIR points there), the chmod followed the
link and changed perms on an arbitrary owned file. Now lstat first
and refuse to chmod symlinks or non-regular files.
2. Prototype pollution via JSON keys (Aisle medium #3 / CWE-1321)
stripAuthProfilesVolatileFields() copied untrusted keys into a
plain {} object. Special keys '__proto__', 'constructor',
'prototype' could mutate the result's prototype chain. Now uses
Object.create(null) for the result and explicitly filters those
three keys (belt-and-suspenders).
3. DoS via unbounded auth-profiles fingerprinting (Aisle medium #4)
readAuthProfilesStableHash had no size or depth limits.
- Added MAX_AUTH_PROFILES_BYTES = 8 MiB. Above the cap we hash raw
bytes instead of running JSON.parse + recursive transform +
stable-stringify.
- Added MAX_AUTH_PROFILES_DEPTH = 64 with a depth-cap marker so
the recursive walk can't stack-overflow on pathologically nested
input.
4. 'token' incorrectly stripped from fingerprint (Codex P2 / Greptile P2)
AUTH_PROFILE_VOLATILE_FIELDS included 'token' to keep OAuth session
token rotation from invalidating the cache. But profiles with
type: 'token' use the literal 'token' key as a long-lived static
credential — stripping it would mask real auth-state changes when
a user rotates a static API token. Removed 'token' from the
volatile set and documented the boundary inline. OAuth session
fields ('access', 'refresh') and timing fields stay stripped.
Skipped from this commit (will reply on threads):
- Cache short-circuit on stale on-disk credentials (Codex/Greptile P1):
separate concern from the security fixes; needs design discussion
on whether to validate disk-vs-config or remove the short-circuit.
- models.json drift in cache key (Codex P1): same — touches the
fingerprint shape and overlaps with the targetProvider short-circuit.
- targetProvider short-circuit untested (Greptile P2): test follow-up
once the short-circuit semantics are settled.
- Aisle medium #5 (raw secrets in fingerprint cache): structurally
larger refactor; needs to land separately to keep this commit\'s
blast radius clear.
Lint: 0 errors. TS: clean.1 parent 6d309f6 commit d505fa0
1 file changed
Lines changed: 91 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
32 | 39 | | |
33 | 40 | | |
34 | 41 | | |
| |||
39 | 46 | | |
40 | 47 | | |
41 | 48 | | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
42 | 78 | | |
43 | 79 | | |
44 | 80 | | |
| |||
49 | 85 | | |
50 | 86 | | |
51 | 87 | | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
52 | 105 | | |
53 | 106 | | |
54 | 107 | | |
| |||
63 | 116 | | |
64 | 117 | | |
65 | 118 | | |
66 | | - | |
| 119 | + | |
67 | 120 | | |
68 | 121 | | |
69 | 122 | | |
70 | | - | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
71 | 131 | | |
72 | 132 | | |
73 | 133 | | |
74 | 134 | | |
75 | | - | |
| 135 | + | |
76 | 136 | | |
77 | | - | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
78 | 142 | | |
79 | 143 | | |
80 | 144 | | |
81 | 145 | | |
82 | | - | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
83 | 150 | | |
84 | 151 | | |
85 | 152 | | |
| |||
152 | 219 | | |
153 | 220 | | |
154 | 221 | | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
155 | 240 | | |
156 | 241 | | |
157 | 242 | | |
| |||
0 commit comments