Update 2026-05-19: Alle drei Findings (F1+F2+F3) sind im selben Session-Lauf gefixt in commit
d22c3f5aufmcp-replicate-hosted. 84 pytest gruen (vorher 39, neue Test-Dateitest_guard_middleware_blocks.pymit 45 cases), ruff clean. Audit ist als baseline gespeichert — naechster Lauf kann diff machen.
Security-Audit — mcp-replicate-hosted
Daily schnell-Modus (Konfidenz-Gate 8/10) gegen den frisch gebauten Hosted-Replicate-MCP vor AWS-Deploy. Reine Code-Trace, keine Live-API-Calls. Identisches Vorgehen wie Pilot-Audit mcp-papierkram 2026-05-18.
Ergebnis
| Severity | Count |
|---|---|
| CRIT | 0 |
| HIGH | 0 |
| MED | 3 |
| LOW | 0 |
Verdict: Keine Eskalation, kein hartes Deploy-Block. Aber: vor Live-Schaltung an Julian sollten F1 + F2 gefixt sein (~30 Min Aufwand, 1 Datei) — beides sind Cost-/Trust-Boundary-Bypaesse die das im Plan zugesicherte Cost-Cap-Versprechen verletzen. F3 ist Hygiene und kann lokal bleiben.
Sub-MCP mcp-replicate selbst wurde nicht erneut auditiert (gleiche Quelle wie mcp-papierkram-Audit-Run, lokale stdio, hier nur via Proxy-Wrap relevant — die hier gefundenen Issues sind Pattern-Issues im Wrapper, nicht im Sub).
Surface
SURFACE: mcp-replicate-hosted (Commit 068a210)
- MCP-Tools (sichtbar via tools/list): 10 (Default-Whitelist, ohne search_tools auch 9)
- MCP-Tools (aufrufbar via tools/call): ~45 (10 sichtbar + 35 raw replicate_* via Proxy)
- Layer-Tools (custom, mit Brand-Lock-Injection): 5 (create_image/_text_image/_svg_logo/_from_reference/_video)
- Slash-Prompts: 3 (/speaker_card, /save_the_date, /social_post)
- Lambda-Endpoints: 0 (Fargate-only)
- Public-Endpoints: 1 geplant (https://replicate.agenticventures.de/mcp + /health auth-frei)
- Github-Actions: 0 (Repo neu, keine CI/CD)
- Secrets-Stores: .env.local (gitignored), AWS-Secrets-Manager (mcp-replicate-hosted/upstream-tokens + cloudflared-token)
- Trust-Boundary: Cloudflare-Edge -> CF-Tunnel (kein Public-Origin) -> Scalekit-OAuth (JWT, JWKS-cached) -> GuardMiddleware (Rate-Limit + Modell-Whitelist + Audit + Kill-Switch) -> ToolWhitelist (Discovery-Filter) -> Replicate API (Bearer-Token)
Stack: Python 3.12, FastMCP v2 (Prefect-Fork), httpx, pydantic-settings. CDK Fargate + cloudflared-Sidecar (Mirror von mcp-vf-hosted-Pattern).
Mental Model
- Was ist das? Hosted Image-/Video-Gen-MCP. Wrappt
mcp-replicate(35 Tools, Replicate API v1) hinter Scalekit-OAuth + Modell-Whitelist + VF-Brand-Lock. - Wer schickt Input? JWT-authentifizierte VF-User (Julian/Andre/Christoph als geplante User, Marvin als Admin) via Open WebUI VF (vf-nova). Spaeter ggf. claude.ai Pro Custom Connector.
- Wer hat Output-Zugriff? Caller selbst (Replicate gibt Output-URL zurueck). Audit-Log in CloudWatch (7d Retention, PII-scrubbed). Open WebUI persistiert Bilder in seiner DB.
- Trust-Boundaries:
- Aussen → Cloudflare: TLS-Termination, WAF, IP-Rate-Limit
- CF → Fargate (CF-Tunnel-only Ingress): kein Public-Origin
- Vor Tool-Call: Scalekit-JWT-Validation, dann GuardMiddleware (Rate-Limit + Modell-Whitelist + Audit + Kill-Switch)
- Im Tool-Call: Replicate Bearer-Token (Account-Level: voller Account-Zugriff)
Phasen-Findings
Phase 2 — Secrets-Archaeology
- Git-History: 1 Commit (068a210), kein Secret-Format in History (
sk-ant-,AKIA*,ghp_,r8_*alles negativ). .env.exampleenthaelt nur leere Schluessel-Namen..gitignoredeckt.env,.env.local,.env.*.localab.- Nur
.env.examplegetrackt —.env*Wildcards greifen. - Phase 2 clean.
Phase 3 — Dependency Supply Chain
pyproject.tomlpinnt nur>=Untergrenzen (fastmcp>=2.11.0,pyjwt[crypto]>=2.9.0,pydantic>=2.10.0,boto3>=1.35.0), ABERuv.lockist im Repo getrackt. Dies ist die Source-of-Truth fuer Production-Deploys (Dockerfile nutztuv sync --frozen).- Im Gegensatz zu mcp-papierkram-Audit F1: kein Finding, weil
uv.lockvorhanden. uv treezeigt: fastmcp v3.3.1, httpx 0.28.1, h11 0.16.0 (CVE-2025-43859 fixed), cryptography 48.0.0 — alle aktuell, keine known unpatchten CVEs in direkten Deps.- Sub-MCP
mcp-replicateals editable install via[tool.uv.sources](path = "../mcp-replicate") — lokale Quelle. - Phase 3 clean.
Phase 4 — CI/CD
- Keine
.github/workflows/im Repo (Repo neu). Pre-Push-CI sollte vor Public-Repo angelegt werden (gitleaks + pytest + ruff). Aktuell nicht Daily-Finding (Repo bleibt private), aber Tentative-Notiz fuer tief-Modus.
Phase 5 — Infra Shadow Surface
- Dockerfile:
USER mcp(non-root, gid 10000), kein.env-COPY, keineARG-Secrets.EXPOSE 8080ist informativ-only. Clean. - CDK Stack (
infra/lib/mcp-replicate-hosted-stack.ts):ExecRole: nurAmazonECSTaskExecutionRolePolicy(managed) + scopedSecret.grantReadauf 2 spezifische Secret-ARNsTaskRole: leer (Best Practice — keine AWS-API-Calls aus dem Task heraus noetig)- Keine IAM-Wildcards (
actions: ["*"]oderresources: ["*"]) egressSg:allowAllOutbound: true— notwendig fuer cloudflared (QUIC zu CF-Edge) + httpx zu api.replicate.com. Egress-only, kein Ingress (CF-Tunnel ist einzige Eingangs-Achse). Korrekt.assignPublicIp: true— notwendig fuer Fargate-egress-zu-Internet ohne NAT-Gateway. Container hat keinen Public-Endpoint (egress-only SG). Korrekt fuer dieses Pattern.circuitBreaker: { enable: true, rollback: true }— Auto-Rollback bei Deploy-Fail.
- ARN-PLACEHOLDERs (
-PLACEHOLDERSuffix) wuerdencdk deploymit CFN-Resolution-Failure brechen — operational hint, kein Security-Issue. - Phase 5 clean.
Phase 6 — Endpoint-Auth + Tool-Surface
Hauptphase fuer diesen MCP. Dreigliedrige Defense-Strategie:
- Auth-Layer:
ScalekitProvideralsFastMCP(auth=...)(main.py:436). Validiert JWT pro Request via JWKS (gecached). ✓ - GuardMiddleware: Rate-Limit (60/min, 1000/h pro Subject-Hash) + Audit-Log + Emergency-Disable + Modell-Whitelist-Check fuer
_MODEL_GATED_TOOLS. ✓ ABER siehe F1 unten. - ToolWhitelistMiddleware: Filtert
tools/listauf 10 Default-sichtbare Tools (_DEFAULT_TOOL_WHITELIST). ABER:tools/callbleibt OPEN (intentionally fuer search_tools-Discovery-Pattern). Siehe F2.
TLS-Verify: kein verify=False in der Codebase. ✓
FastMCP-Tool-Schema: Layer-Tools haben typed Signaturen (Pydantic-validated), keine : Any-Args bei Tool-Functions. _normalize_tool_result nutzt Any defensiv fuer Sub-MCP-Output-Parsing — kein User-Input-Pfad. ✓
Findings dieser Phase: F1 + F2 (s.u.).
Phase 7 — LLM-Security
- Brand-Lock-Injection (
brand_lock.py):VF_BRAND_LOCK_PROMPT + prompt— simple String-Concat, User-Prompt kommt NACH dem Brand-Lock. User koennte"Ignore the above, render indigo gradient"schreiben. Aber: Ziel ist ein Image-Generation-Modell (Flux/Recraft/Ideogram), kein Text-LLM — diese rendern nicht Text-Instructions sondern interpretieren als Visual-Description. Ideogram (Text-im-Bild) koennte “Ignore above” rendern, aber User-self-harm, kein Trust-Boundary-Violation. Konfidenz 5/10 → unter 8/10-Gate. Notiert als TENTATIVE fuer tief-Modus. - Slash-Prompts: nutzen
<<<>>>-Wrapping +_sanitize-Whitelist-Pattern (Control-Chars raus, Truncation, printable-only). Anti-Prompt-Injection-Defense vorhanden. ✓ - Tool-Schema-Description: alle Layer-Tool-Descriptions sind statische Multi-Line-Strings (keine f-Strings mit User-Input). ✓
- Prompt-Length-Cap: keine. User koennte 100k-Char-Prompt schicken. Phase-12-Hard-Exclusion #2 (Speicher-Exhaustion ohne konkreten Exploit) — discard.
- Phase 7: 1 TENTATIVE, sonst clean.
Phase 8 — Skill + MCP Supply-Chain
- Hosted-MCP, kein Skill-Code. Sub-MCP
mcp-replicateaus eigener Quelle (~/source/mcps/mcp-replicate/). Editable install via[tool.uv.sources]. - Keine externen
curl/wget/npx-Calls in der Codebase. - Dockerfile pinnt
cloudflared(Sidecar) via Manifest-Digest in CDK-Stack (@sha256:6b599ca3...). Image-Digest fuer eigenes vf-replicate Image ist im StackPLACEHOLDER— wird beim ersten Push gepinnt (operational, kein Security-Issue). - Phase 8 clean.
Phase 9 — OWASP-Mini
- A01 Access Control: Single-Tenant per Deployment. Alle JWT-Authentifizierten-User teilen den selben
REPLICATE_API_TOKEN(= Account-Level-Zugriff auf Marvins/VF-Replicate-Account). Per-Design fuer VF-Pilot OK (4 User, alle vertrauenswuerdig). Multi-Tenant (separate Tokens pro User) wuerde Code-Aenderung erfordern — Decision-Fork im Plan dokumentiert. - A03 Injection: kein
os.system, keinsubprocess(shell=True), keineval/exec. httpx-Path-Building im Sub-MCP nutzt String-Interpolation, aber alle Pfad-Parts sind typed (z.B.model: strmit_require_owner_name-Validation). - A05 Misconfig: kein
DEBUG=True, kein CORS-Wildcard, keine Debug-Endpoints. - A07 Auth-Failures: Scalekit-JWT-Issuance ist extern, JWKS-Cache lokal. JWT-Expiry/Refresh-Token-Rotation: Scalekit-Defaults (60-Min-Access-Token + Refresh).
- Phase 9 clean.
Phase 10 — STRIDE (vf-replicate hosted)
KOMPONENTE: mcp-replicate-hosted (Fargate, geplant replicate.agenticventures.de)
S: Spoof - andere User-Tokens? → Scalekit-JWT mit JWKS-Validation, ✓
T: MITM auf Tool-Calls? → CF-Edge-TLS + intern HTTPS-Only, ✓
R: Repudiation - User-Action abstreiten? → Audit-Log mit subject_hash in CloudWatch, ✓
I: Info-Disclosure - andere VF-User-Daten? → Single-Tenant per Deployment, alle JWT-Caller teilen
Replicate-Account-Daten (per-Design fuer VF-Pilot OK)
D: DoS - Fargate lahmlegen? → Rate-Limit (60/min) + Replicate-Spending-Cap $100/Mo
E: Elevation - non-whitelisted Modelle? → **YES, via F1+F2**. Cost-Bypass moeglich.
→ STRIDE-E ist die Lücke (Findings unten).
Phase 11 — DSGVO
| Datentyp | Quelle | Wohin | Wie lang |
|---|---|---|---|
| JWT-Subject (sub claim) | Scalekit | Audit-Log NUR als 8-char SHA256-Hash | 7d CloudWatch |
| Image-Prompt (User-Text) | Julian via Nova | POST-Body an Replicate API | Replicate-Retention (default 30d Prediction-Logs) |
| Output-URL | Replicate | nicht persistent bei uns; OWUI persistiert das Bild | OWUI-DB unbegrenzt |
| Tool-Call-Metadata | GuardMiddleware | CloudWatch /aws/ecs/default/mcp-replicate-hosted | 7d |
| Replicate-API-Token | AWS Secrets Manager | ENV-Var im Container-Speicher | Container-Lifetime |
| Cloudflared-Tunnel-Token | AWS Secrets Manager | ENV-Var im cloudflared-Container | Container-Lifetime |
- PII-scrubbed Audit-Log (JWT, Email, IBAN, Phone-DE, Bearer) — verifiziert via
test_audit_no_pii.py. - Subject-Hash ist 8-Char-SHA-Prefix (kein Plaintext).
- Replicate ist US-HQ Subprozessor — fuer VF-B2B-Eventagentur mit generischen Mood/Hero-Prompts OK unter AVV.
- Risk-Notiz: Wenn VF mal Aftermovie-Stills mit erkennbaren Gaesten generieren will → DSGVO Art. 9 (biometrische Daten) — separater Consent-Workflow noetig.
- Phase 11 clean fuer aktuellen Scope, dokumentierter Risk fuer Personen-Generierung.
Phase 12 — FP-Filter
Discarded:
- Range-pinned Deps mit getrackter
uv.lock: nicht-Finding (Lockfile ist Source-of-Truth). - Brand-Lock-Prompt-Injection: Konfidenz 5/10 < 8/10-Gate. → TENTATIVE-Notiz.
- Prompt-Length-Cap-fehlt: Phase-12-Hard-Exclusion #2.
- Keine CI/CD-Workflows: kein Repo-State-Issue (neu, private).
- ARN-PLACEHOLDERs im Stack: operational, kein Security.
- Single-Tenant-shared-Replicate-Token: per-Design, dokumentiert.
Verified Findings: F1 + F2 + F3 (s.u.).
Findings
F1 — Modell-Whitelist-Bypass via version= oder deployment= Argument
Severity: MED
Confidence: 9/10
Status: VERIFIED
Phase: 6 — Endpoint-Auth
Category: Tool-Surface / Cost-Boundary
File: src/mcp_replicate_hosted/main.py:270-276
Was ist das Problem. Die GuardMiddleware prueft den Modell-Whitelist gegen das model-Argument des Tool-Calls via _extract_model_arg. Der zugrundeliegende mcp-replicate.create_prediction akzeptiert aber DREI alternative Target-Referenzen: model, version ODER deployment (siehe ~/source/mcps/mcp-replicate/src/mcp_replicate/server.py:138-213). Bei version=<hash> und deployment=<owner/name> returnt _extract_model_arg(None) und die Whitelist wird vollstaendig umgangen. Damit ist replicate_create_prediction(version="<irgendeine-version>", input={...}) aus jeder authentifizierten Session moeglich — inklusive aller Modelle die explizit aus der Whitelist gelassen wurden (z.B. bytedance/seedance-pro >$0.20/Bild).
Exploit-Skizze.
- JWT-Authentifizierter VF-User (oder kompromittierte Session) ruft via Open WebUI VF im Chat:
replicate_create_prediction( version="<hash-von-seedance-pro-aus-Replicate-Webseite-kopiert>", input={"prompt": "...", "duration": 10} ) - GuardMiddleware:
_extract_model_arg→ None, kein Whitelist-Check. - Replicate-API laeuft Modell. Cost-Schaden: bis $100/Mo Spending-Cap (das einzige verbleibende Cost-Limit).
Fix (1 Datei, ~20 Zeilen): _extract_model_arg und GuardMiddleware.on_call_tool erweitern, so dass auch version- und deployment-Args gepruft werden — deployment muss vollqualifiziert (owner/name) gegen einen separaten Deployment-Whitelist gepruft werden (zur Zeit keiner definiert, also: deployment-Pfad komplett blocken). Fuer version: schwierig, da Version-IDs nicht human-readable an Modelle gebunden sind ohne API-Call. Pragmatisch: Version- und Deployment-Pfade pauschal blocken (Block mit Hinweis “nutze model=‘owner/name’”) — verliert keine Funktionalitaet weil Layer-Tools model= benutzen.
Patch-Skizze in patches/F1-model-whitelist-bypass.md.
Quelle / Beleg.
src/mcp_replicate_hosted/main.py:270-276(_extract_model_argschaut nur aufmodel)src/mcp_replicate_hosted/main.py:200-220(GuardMiddleware ruft nur_extract_model_arg, kein Fallback)../mcp-replicate/src/mcp_replicate/server.py:138-213(create_predictionakzeptiert version/model/deployment alternativ)tests/test_model_whitelist.pytestet nurmodel=-Pfad, nicht version/deployment.
F2 — Account-Admin- und Raw-Escape-Hatch-Tools via tools/call ohne Whitelist erreichbar
Severity: MED
Confidence: 9/10
Status: VERIFIED
Phase: 6 — Endpoint-Auth / Tool-Surface
Category: Tool-Surface / Trust-Boundary
File: src/mcp_replicate_hosted/main.py:103-118 (Default-Whitelist), 651-660 (Sub-MCP-Mount)
Was ist das Problem. ToolWhitelistMiddleware filtert tools/list-Responses auf 10 sichtbare Tools, aber tools/call bleibt bewusst offen (Discovery-Pattern via search_tools). Per Proxy gemountete Sub-MCP-Tools sind alle unter replicate_* callable. Darunter:
replicate_raw_get(path=...)/replicate_raw_post(path=..., body=...)— beliebige Replicate-API-Calls, auch Admin-Endpointsreplicate_create_model,replicate_delete_model,replicate_delete_model_versionreplicate_create_training,replicate_cancel_training(Fine-Tunings: 100 pro Lauf)replicate_create_deployment,replicate_update_deployment,replicate_delete_deployment(ongoing $/h Cost)replicate_get_account(Leak: Account-Username + Email + GitHub-URL)replicate_get_webhook_secret(Leak: HMAC-Signing-Key)replicate_upload_file,replicate_delete_file
_MODEL_GATED_TOOLS enthaelt nur replicate_create_prediction + die 4 Layer-Tools — alle obigen Admin/Raw-Tools laufen ohne Whitelist-Check direkt durch.
Exploit-Skizze.
- JWT-Auth-User entdeckt via
search_tools(query="raw")diereplicate_raw_post-Tool-Schema. - Ruft:
→ komplette Whitelist umgangen (gleiche Folge wie F1 plus: jeder Replicate-Endpoint inklusivereplicate_raw_post(path="/predictions", body={"version":"<seedance-pro-hash>", "input":{...}})/account,/webhooks/default/secret,/deployments). - Alternativ:
replicate_delete_model(model="black-forest-labs/flux-2-pro")(loescht zwar nur einen Reference — Flux selbst gehoert nicht uns — aberreplicate_delete_model(model="<unser-owner>/<unser-trained-fine-tune>")waere destruktiv). replicate_get_account()→ leakt Marvins/VF-Replicate-Email und Username.replicate_get_webhook_secret()→ leakt HMAC-Secret. Wer das hat kann faked-Webhooks an unsere Endpoints senden.
Schutz-Reste (mildernd):
- Spending-Cap $100/Mo im Replicate-Dashboard (vor Cost-Explosion, nicht vor Data-Leak)
- Audit-Log faengt alle Calls mit subject_hash auf — Forensik, nicht Praevention
- Trust-Circle ist klein (4 User, alle VF/Marvin) — Insider-Threat unwahrscheinlich, aber JWT-Kompromittierung waere voller Account-Zugriff
Fix (1 Datei, ~30 Zeilen). Defense-in-Depth analog mcp-vf-hosted-_BLOCKED_TOOLS-Pattern:
_ALLOWED_REPLICATE_TOOLSFrozenset definieren — nur die im_DEFAULT_TOOL_WHITELISTaufgefuehrtenreplicate_*-Tools (get_prediction, wait_for_prediction, cancel_prediction, list_predictions).GuardMiddleware.on_call_tool: wenn Tool-Name mitreplicate_startet UND nicht im Allow-Set → 403 mit klarer Refusal-Message + Audit-Log.- Layer-Tools rufen
create_predictionintern via_build_sub_mcp_client(bypassed Middleware → bleibt funktional). - Test
test_blocked_replicate_admin_toolsergaenzen.
Patch-Skizze in patches/F2-replicate-admin-tools-block.md.
Quelle / Beleg.
src/mcp_replicate_hosted/main.py:103-118(Default-Tool-Whitelist nur 10 Tools)src/mcp_replicate_hosted/main.py:171-178(_MODEL_GATED_TOOLSschliesst keine Admin-Tools ein)src/mcp_replicate_hosted/main.py:651-660(Sub-MCP-Mount viaapp.mount(proxy, namespace=...)→ alle replicate_* werden via tools/call adressierbar)../mcp-replicate/src/mcp_replicate/server.pyZeilen 491-547 (create_model/delete_model), 589-651 (Training), 697-791 (Deployment), 908-940 (raw_get/raw_post), 875-900 (Account + Webhook-Secret)
F3 — HTTP-Bind default 0.0.0.0 ohne Auth-Sanity-Check (lokal-debug-Pfad)
Severity: MED
Confidence: 8/10
Status: VERIFIED
Phase: 6 — Endpoint-Auth (Lokal-Debug-Pfad)
Category: Misconfiguration / Defense-in-Depth
File: src/mcp_replicate_hosted/settings.py:62
Was ist das Problem. Settings.host defaultet auf "0.0.0.0" (Bind auf alle Interfaces). Im Production-Container ist das korrekt (CF-Tunnel-Sidecar verbindet ueber loopback, egress-only SG verhindert externen Ingress). Aber bei lokalem uv run python -m mcp_replicate_hosted.main zu Debug-Zwecken auf einem Entwickler-Laptop bindet der Service ohne Warnung auf alle Interfaces — einschliesslich WLAN/Tailscale/etc. Die ScalekitProvider-Auth ist davor (kein Bypass), aber:
- Marvin koennte aus Bequemlichkeit lokal-debug ohne realen Scalekit-Token starten (z.B. mit Mock-Bypass /
auth=NoneEdit) → exponiert - JWKS-URL-Resolution braucht Internet → bei Netzwerk-Problem koennte ScalekitProvider degrade-Pfad nehmen (verifiziert: tut es nicht, hard-fails, aber wertvoll dokumentiert zu sein)
- Hygiene-Hinweis: lokales Debug sollte explizit auf
127.0.0.1binden
Identisch zu mcp-papierkram-Audit F3 (Bind-Sanity).
Exploit-Skizze (begrenzt, Defense-in-Depth-Issue).
- Marvin startet lokal
uv run python -m mcp_replicate_hosted.mainaus Debug-Bedarf. - Sitzt in fremdem WLAN (Cafe / Co-Working).
- Bind auf
0.0.0.0:8080ist von anderen Geraeten im selben WLAN sichtbar. - Scalekit-Auth blockt unautorisierte Calls (CRIT-Faktor weg), ABER:
- Andere koennen sehen dass dort ein MCP laeuft (
/healthist auth-frei) - Wenn Auth-Bypass-Code irgendwann drinsteckt (zukuenftige Debug-Edit) sind Tools direkt erreichbar
- Replicate-Token in Container-Speicher (lokal-debug nutzt
.env.localdirekt) → wenn jemand eine Memory-Exfiltration findet, Token weg
- Andere koennen sehen dass dort ein MCP laeuft (
Fix (1 Datei, ~5 Zeilen). In main.py:run() einen Sanity-Warn-Log ergaenzen wenn s.host == "0.0.0.0" und os.environ.get("AWS_EXECUTION_ENV") nicht gesetzt (= nicht in ECS):
def run() -> None:
import os
s = get_settings()
if s.host == "0.0.0.0" and not os.environ.get("AWS_EXECUTION_ENV"):
log.warning({
"event": "bind_sanity_warning",
"host": s.host,
"hint": "binding to 0.0.0.0 outside ECS — use HOST=127.0.0.1 for local debug",
})
...Quelle / Beleg.
src/mcp_replicate_hosted/settings.py:61(host: str = Field(default="0.0.0.0"))src/mcp_replicate_hosted/main.py:670-685(run()ohne Bind-Sanity-Check)
Tentative-Findings (unter 8/10 Konfidenz-Gate — Re-Evaluate im tief-Modus)
T1 — Brand-Lock-User-Prompt-Concat ohne <<<>>>-Wrapping in Layer-Tools
Konf 5/10. Image-Modelle folgen nicht Text-Instructions, User-self-harm.
Im Gegensatz zu Slash-Prompts (die das Wrapping HABEN). Konsistenz-Issue,
keine echte Vuln. Re-evaluate vor erstem Industriekunden-Einsatz.
T2 — Keine CI/CD-Workflows (pytest + gitleaks + ruff)
Repo neu, private. Bevor Repo public oder bevor weitere Devs committen:
GitHub-Action mit den Local-Checks aufsetzen. Aktuell Daily-Hygiene-Notiz.
T3 — _normalize_tool_result fail-tolerant (json.JSONDecodeError -> _text-Wrap)
Konf 4/10. Bei Sub-MCP-Output-Corruption kein Crash aber stiller Daten-
Verlust. Audit-Log kein Tool-Fehler -> Forensik verliert Spur. Robustness,
nicht Security.
Top-3 Naechste Schritte
-
F2 fixen vor AWS-Deploy —
_ALLOWED_REPLICATE_TOOLS-Blocklist inGuardMiddlewareeinbauen. Defense-in-Depth gegen jeglichen Admin-Tool-Missbrauch. ~30 Min, 1 Datei + 1 Test. Patch-Skizze inpatches/F2-replicate-admin-tools-block.md. -
F1 fixen mit F2 zusammen —
_extract_model_argum version/deployment-Block erweitern. Logik wandert beim F2-Fix sowieso in dieselbeon_call_tool-Branche. Beide zusammen = 1 PR. Patch-Skizze inpatches/F1-model-whitelist-bypass.md. -
F3 nach F1/F2 (Hygiene) — Bind-Sanity-Warn-Log. ~5 Zeilen. Kann auch in PR mit F1+F2 mit rein. Patch-Skizze in
patches/F3-bind-sanity-warning.md.
Zusammen ~45 Min Aufwand, 1 PR, alle 3 Findings weg. Danach sauber genug fuer AWS-Deploy + Live-Schaltung an Julian (nach AVV-Sign).
Regression vs. mcp-papierkram-Audit
- F1 (uv.lock): mcp-papierkram hatte das Issue, mcp-replicate-hosted nicht. Pattern verbessert.
- F3 (Bind-Sanity): hier wieder. Pattern in Skeleton-Template aufnehmen.
- F1+F2 hier: neue Klasse von Issue (Wrapper-MCP-Pattern mit Proxy-mounted Sub-MCPs). Sollte ins Pattern-File
intern/wissen/prozesse/mcp-hosting-fargate-tunnel.mdals Audit-Checkliste-Punkt.
Run-Konfiguration
Audit-Run: 2026-05-19 (post-Build)
Scope: ~/source/mcps/mcp-replicate-hosted/, commit 068a210
Mode: schnell
Konfidenz-Gate: 8/10
Phasen-Filter: keine (alle 13)
Auditor: claude-opus-4-7 (1M context)
Methodik: intern/capabilities/skills/security-audit/SKILL.md
Vergleichs-Audit: intern/runs/2026-05-18-security-audit-mcp-papierkram/report.md
Cross-Ref
- Cross-Repo-Tracker (wachsende Liste aller MCP-Audit-Findings): mcp-audit-findings-cross-repo
- Letzter Voll-Lauf (Vault + alle Repos): report
- Pilot-Audit (mcp-papierkram): report
- Build-Run: _index
- Plan-Source: 2026-05-19-design-stack-julian
- Capability: mcp-replicate-hosted
- Pattern-Doku: mcp-hosting-fargate-tunnel