@miller-tech/uap 1.172.6 → 1.172.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/src/policies/enforcers/enforcement_infra_protect.py +47 -0
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
package/package.json
CHANGED
|
Binary file
|
|
@@ -98,6 +98,48 @@ REASON = (
|
|
|
98
98
|
)
|
|
99
99
|
|
|
100
100
|
|
|
101
|
+
# Scripts invoked by the command, e.g. `bash deploy.sh`, `sh ./x.sh`, `./x.sh`,
|
|
102
|
+
# `source x.sh`. Every rule above reads the command TEXT, so moving a
|
|
103
|
+
# service-restart of the inference stack one level down -- into a file -- slipped
|
|
104
|
+
# past all of them. Not theoretical: it was used during this project's own
|
|
105
|
+
# sessions to cycle the stack while the gate reported nothing to block.
|
|
106
|
+
_SCRIPT_INVOCATION_RE = re.compile(
|
|
107
|
+
r"(?:^|[|;&]|\bsudo\b|\benv\b\s)\s*"
|
|
108
|
+
r"(?:(?:ba|z|k|da)?sh\s+|source\s+|\.\s+)?"
|
|
109
|
+
r"((?:\./|/|~/|\.\./)[^\s;|&<>()'\"]+|[\w./-]+\.(?:sh|bash|zsh))"
|
|
110
|
+
)
|
|
111
|
+
# Only small local files are worth reading; the cap keeps this off the hot path.
|
|
112
|
+
_MAX_SCRIPT_BYTES = 256 * 1024
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _referenced_script_bodies(cmd: str, limit: int = 4) -> list[tuple[str, str]]:
|
|
116
|
+
"""(path, contents) for scripts this command would execute.
|
|
117
|
+
|
|
118
|
+
Best-effort and deliberately shallow: one level, at most `limit` files, and
|
|
119
|
+
any read error is skipped. A miss must degrade to today's behaviour
|
|
120
|
+
(text-only scanning), never to an exception that takes the whole gate down.
|
|
121
|
+
"""
|
|
122
|
+
found: list[tuple[str, str]] = []
|
|
123
|
+
seen: set[str] = set()
|
|
124
|
+
for m in _SCRIPT_INVOCATION_RE.finditer(cmd):
|
|
125
|
+
raw = m.group(1)
|
|
126
|
+
if raw in seen:
|
|
127
|
+
continue
|
|
128
|
+
seen.add(raw)
|
|
129
|
+
try:
|
|
130
|
+
p = Path(raw).expanduser()
|
|
131
|
+
if not p.is_absolute():
|
|
132
|
+
p = Path.cwd() / p
|
|
133
|
+
if not p.is_file() or p.stat().st_size > _MAX_SCRIPT_BYTES:
|
|
134
|
+
continue
|
|
135
|
+
found.append((str(p), p.read_text(errors="replace")))
|
|
136
|
+
except Exception: # noqa: BLE001 - unreadable/oddly-named file: skip it
|
|
137
|
+
continue
|
|
138
|
+
if len(found) >= limit:
|
|
139
|
+
break
|
|
140
|
+
return found
|
|
141
|
+
|
|
142
|
+
|
|
101
143
|
def main() -> None:
|
|
102
144
|
operation, args = parse_cli()
|
|
103
145
|
if operation not in BASH_OPS:
|
|
@@ -108,6 +150,11 @@ def main() -> None:
|
|
|
108
150
|
for rule in RULES:
|
|
109
151
|
if rule.search(cmd):
|
|
110
152
|
emit(False, REASON)
|
|
153
|
+
# Same rules, applied to the body of any script the command would run.
|
|
154
|
+
for path, body in _referenced_script_bodies(cmd):
|
|
155
|
+
for rule in RULES:
|
|
156
|
+
if rule.search(body):
|
|
157
|
+
emit(False, f"{REASON} (matched inside the invoked script {path})")
|
|
111
158
|
emit(True, "no infra-destructive pattern")
|
|
112
159
|
|
|
113
160
|
|
|
Binary file
|