Tactical Action · Guides & deep dives

V4 Workshop / GameFeature-Plugin UGC Threat Model

A UE GameFeature plugin can contain: cooked assets (meshes, textures, audio, data tables), Blueprint classes (bytecode executed in-process with access to every BlueprintCallable engine API), GameFeature actions (component/ability

8sections10 minread2tables

On this page

Status: Active. Created 2026-06-12 to close the audit gap (V1_V7_PLAN_SET_AUDIT_2026-06-12.md §6.2, V4): the workshop spec asserts that "a mod that crashes is caught, auto-disabled, and reported" (V4/V4_features.md:1728-1731) — a reliability claim — and calls mods "sandboxed GameFeatures plugins" (:1710-1711) without defining the sandbox. This document is the security analysis. Its trust-tier decision (§3) and GA gates (§7) are binding inputs to the workshop launch exit criterion ("Workshop / mod platform live", V4/V4_features.md:2751) and to risk R-08 in V4/docs/planning/program-risk-register.md.

1. What a GameFeature plugin actually is (the gap in the current claim)#

A UE GameFeature plugin can contain: cooked assets (meshes, textures, audio, data tables), Blueprint classes (bytecode executed in-process with access to every BlueprintCallable engine API), GameFeature actions (component/ability injection into live actors), and — for first-party plugins — native C++ modules. Nothing in the GameFeature subsystem is a security boundary: a Blueprint runs with the full privileges of the game process. Crash-catching (V4/V4_features.md:1728-1731) protects against bugs; it does nothing against malice, and "isolated plugin" describes packaging, not privilege.

Adjacent specced surfaces this model must cover: the mission editor's "sandboxed" visual script ("scripts cannot call engine internals or arbitrary code", V4/V4_features.md:1657-1659), the mod manifest/dependency closure (:1716-1719), immutable versioning (:1732-1734), two-stage content moderation + takedown cascade (:1723-1727), Steam Workshop + EOS Player Studio distribution (:1713-1715), and the esports mod whitelist (:1896-1898).

2. Threat enumeration#

ID Threat Vector Worst case Status under current spec
T1 Arbitrary native code in plugins Mod ships a compiled module; GameFeature loader maps it into the game process Full RCE on every subscriber's machine; ransomware/credential theft at workshop scale; console TRC catastrophe Not explicitly forbidden anywhere — must be forbidden (§3)
T2 Blueprint logic mods as de-facto arbitrary code BP bytecode calls exposed engine APIs: file I/O via save-game/paths nodes, console-command execution, process-level side effects via plugins' loaded classes Equivalent to T1 in practice (data theft, cheat injection, griefware), while looking like "just a Blueprint" "Sandboxed" asserted, no mechanism specced — resolved by §3 tiers
T3 UObject / asset deserialization attacks Malicious .uasset exploits parser/serializer bugs (UE asset loaders have a history of memory-safety CVEs); triggers on load, before any "logic" runs RCE from an "asset-only" mod; defeats any logic-tier policy if unmitigated Unaddressed — mitigated by re-cook pipeline + loader fuzzing (§4)
T4 Cheat distribution via cosmetic mods Materials with depth-test disabled (wallhack), high-visibility player skins, foliage/smoke-removing meshes, hitbox-revealing particles, tampered data tables Competitive integrity collapse; EAC (ADR 0008) does not inspect workshop asset semantics Partially addressed: esports whitelist exists (:1896-1898); ranked needs the same guarantee (§5)
T5 Supply-chain via popular-mod update Author account compromise → malicious vN+1 offered to the full subscriber base; immutable versions (:1732-1734) protect pins but the update offer path is the attack One popular mod = distribution to 10⁵–10⁶ clients in hours Unaddressed — author 2FA, rescans per version, staged rollout, kill switch (§4, §6)
T6 Dependency-closure attacks Typosquatted or hijacked dependency in the manifest closure (:1716-1719); client "resolves and downloads the dependency closure" automatically Same blast radius as T5, harder to see Unaddressed — closure pinned by content hash at publish (§4)
T7 Asset-bomb denial of service Pathological Nanite meshes, 8K texture stacks, runaway Niagara emitters, audio loudness bombs OOM/hang on constrained platforms (Switch 2, tablets — V4/V4_features.md:300-304); review-bombing-by-crash Partially: save quotas exist (:1667-1669); needs budget linting at upload (§4)
T8 Data exfiltration / phishing surfaces Web/URL-capable widgets or nodes in logic mods; malicious links in workshop descriptions Credential phishing branded inside the game Moderation queue helps descriptions; logic-tier API allowlist removes in-game vector (§3)
T9 Moderation-evasion content Classifier-evading textures/meshes (the two-stage gate at :1723-1725 is image-classifier + reports) Brand/legal damage, store delisting Accepted residual; takedown cascade + §6 revocation bounds exposure time
T10 Platform-holder/cert violation Any downloaded executable logic on consoles violates TRC/XR content policies Cert rejection of the base game update carrying the workshop client (risk R-02/R-08) Resolved structurally by §3: consoles receive Tier-0/Tier-1 only

3. Trust-tier design — the explicit call#

Decision (binding, planning decision adopted 2026-06-12, to be ratified as an ADR if contested): V4 does NOT distribute arbitrary native code or arbitrary Blueprint GameFeature plugins to client machines. Ever. The workshop's "GameFeatures plugin" packaging is retained, but what a plugin may contain is tiered:

Tier Contents Where it runs Distribution
Tier 0 — Asset-only Cooked assets + data tables conforming to published schemas; zero bytecode of any kind All platforms, incl. consoles via EOS Player Studio After §4 pipeline (re-cook, scans, signing). "Unrestricted" in availability, never in validation
Tier 1 — Interpreted logic Mission-editor visual scripts (V4/V4_features.md:1657-1659) compiled to a restricted interpreted instruction set executed by a V4-owned interpreter: opcode allowlist, capability-scoped API (spawn/objective/dialogue/trigger verbs only), per-tick instruction budget, no file/net/console access All platforms; PvE and custom games only Same pipeline + interpreter-validation pass
Tier 2 — Server-side Blueprint plugins Full Blueprint GameFeature plugins (new modes, mutators, AI behaviors) Dedicated servers only — our fleet's custom-game pools and self-hosted unranked servers. Clients receive only replicated state plus the mod's Tier-0 asset payload; the logic plugin never ships to a client process PC server hosts + first-party fleet; never consoles, never client installs
Tier 3 — Native plugins C++ modules First-party and contracted-partner code only, through the normal build/signing pipeline, code-reviewed Not workshop-distributable. No exceptions; a partner native mod is a game patch, not a mod

Consequences of the call:

  • T1 is closed by fiat (Tier 3 not workshop-distributable); T2 is closed by construction (Blueprint logic exists only behind the server boundary, Tier 2); T10 is closed structurally (consoles get no executable content).
  • The mission editor's existing sandbox claim becomes true by mechanism: Tier 1 is an interpreter we own, not trust in Blueprint.
  • Cost accepted: client-side total-conversion mods (new client logic) are out of scope for V4. That is the price of 9-platform cert and EAC coexistence.

Position relative to V5 and V7#

  • V5 (data-only): V5's workshop is "data-only, cannot ship executable code, and is disabled in ranked PvP and on cert-restricted online surfaces" (V5/V5_features.md:2315-2318). V4 Tier 0 matches V5's line; V4 goes further than V5 by adding Tier 1 (interpreted mission logic) and Tier 2 (server-side Blueprint) because V4's creator suite promises per-cell mission logic, which data alone cannot express.
  • V7 (WASM capability sandbox): V7 lifts the data-only limit with a Wasmtime Component-Model sandbox — capability-typed WIT host interface, fuel/epoch CPU budgets, StoreLimits memory caps, six trust tiers, AOT at upload, per-call audit log (V7/V7_ARCHITECTURE.md:338-369), with content-addressed storage + lock files as the supply-chain primitive (:371-384). V4 deliberately stops short of client-side untrusted execution because it has no such runtime: UE Blueprint offers no capability typing, no deterministic fuel metering, and no memory isolation. V4's line: interpretation (Tier 1) + server isolation (Tier 2) substitute for the sandbox V4 doesn't have. Forward-compatibility requirement: the V4 mod manifest carries a trustTier field whose values map 1:1 onto V7's DataOnly/Scripted/Extended tiers (V7/V7_ARCHITECTURE.md:355-358) so V4 workshop content can migrate when a WASM-class runtime exists; V4 adopts V7's content-addressing model for closure pinning now (§4) since it is runtime-independent.

4. Signing and scanning pipeline (upload → activation)#

  1. Manifest validation — declared cells, asset list, dependencies, semver, author identity (V4/V4_features.md:1716-1719); trustTier declared and verified against contents (a Tier-0 mod containing any bytecode is rejected, not downgraded).
  2. Bytecode & class audit — package is statically walked: Tier 0 must contain zero Blueprint bytecode and only allowlisted UObject classes; Tier 1 scripts compile through the first-party toolchain server-side (the uploaded source graph, not author-supplied bytecode, is authoritative); Tier 2 Blueprint passes an API-usage scan (deny-listed nodes: console command exec, file path access outside mod sandbox dir, process/OS nodes).
  3. Re-cook / re-serialization on trusted infrastructure — every asset is deserialized and re-serialized by our cooker; unknown or malformed structures are dropped, closing the T3 window to the cooker (which we fuzz, §7 G1) rather than every player's client. Clients only ever load first-party-cooked bytes.
  4. Semantic asset scans — material flags (depth-test disable, unusual translucency sort priorities), mesh/texture/emitter budget linting against per-platform caps (T7), audio loudness normalization, data-table values range-checked against schema bounds (T4 partial).
  5. Content moderation — the specced classifier + report queue (V4/V4_features.md:1723-1727) runs after technical scans.
  6. Content-addressed signing — artifact ID = hash(content + full dependency closure) (V7 model, V7/V7_ARCHITECTURE.md:379-384); the workshop service signs {artifact hash, manifest, trustTier, version}. Clients/servers verify signature and the pinned closure hashes before activation — a swapped dependency changes the hash (closes T6).
  7. Per-version re-scan — every update version repeats 1–6 (versions are immutable, :1732-1734); update offers to subscribers roll out staged (1% / 24 h → 25% / 24 h → 100%) with automatic halt on crash/report anomaly (T5).
  8. Author account controls — publishing requires 2FA; a publish from a new device/IP triggers step-up verification; author keys never sign anything (only the service signs), so author compromise cannot mint trusted artifacts directly.

5. Competitive-surface guarantees (T4)#

  • Ranked and tournament processes load zero workshop content — enforced by a build-time assertion in the mode-activation path, the same pattern as the AI-Director PvP exclusion assertion (V4/V4_features.md:1561-1564), not by playlist configuration. Tournament servers already reject non-whitelisted clients (:1896-1898); ranked inherits the stricter rule: no mods, whitelisted or not.
  • Custom/unranked lobbies display the active mod set to all players before ready-up; server-side hit validation and EAC remain active regardless.

6. Kill switch and revocation#

  • Revocation list (CRL-model): workshop service publishes a signed revocation feed; clients fetch at session start and on the existing 30-minute hotfix channel (V4/V4_features.md:1961-1962) for emergency push. Cached CRL is valid offline for 72 h; beyond that, Tier 1/2 content deactivates until the client can revalidate (Tier 0 remains, lower risk — planning assumption adopted 2026-06-12, revisit after Open Beta data).
  • Revocation classes: security (T1–T6 findings — immediate hard-disable, subscribers notified, telemetry snapshot of activation counts preserved for incident response), integrity (T4 cheat assets — disable + ranked-history audit hook for affected lobbies), moderation (existing takedown cascade, :1723-1727, including dependent-mod delisting).
  • Drill requirement: end-to-end revocation (decision → fleet + clients) must complete in ≤15 minutes in staging, exercised quarterly and once before GA (§7 G4).

7. Gates this adds before Workshop GA#

Workshop GA is an exit criterion (V4/V4_features.md:2751). It does not ship until all of:

  • G1 — Cooker hardening: re-cook pipeline operational for all Tier-0 asset classes; ≥500 CPU-hours of coverage-guided fuzzing on the deserialization path with zero outstanding crash/UB findings (planning assumption adopted 2026-06-12 for the fuzz budget); corpus retained and run in CI.
  • G2 — Competitive isolation proven: the §5 build-time assertion exists and a red-team attempt to load a mod into a ranked process fails in CI.
  • G3 — Signing chain live: content-addressed signing + closure pinning verified on all 9 platforms; author 2FA enforced; staged-rollout machinery tested with a forced halt.
  • G4 — Kill-switch drill: ≤15-minute end-to-end revocation demonstrated in staging, all three revocation classes.
  • G5 — Platform-holder signoff: written approval of the per-platform UGC scope (Tier 0/1 on consoles, no executable content) from each console holder — due 2026-07-15 per risk R-08's trigger.
  • G6 — Service pen test: third-party penetration test of workshop-service upload/entitlement/CDN paths with no open high/critical findings.
  • G7 — Interpreter bounty window: Tier-1 interpreter in the security bug-bounty scope for ≥30 days before GA (Open Beta window suffices if the interpreter ships in Open Beta), with sandbox-escape classed as critical.

8. Residual risks (accepted, with eyes open)#

  • T3 residual: a cooker-fuzzing gap could still let a crafted asset through — bounded by trusted re-cook (attacker must exploit our cooker output format, not hand-craft bytes) and the 15-minute kill switch.
  • T4 residual: semantic scans cannot catch every advantage-granting cosmetic; ranked-zero-mods contains the competitive harm; custom games accept it visibly.
  • T9 residual: classifier evasion until report-queue action; bounded by takedown cascade SLA (set: 4 h for confirmed security/integrity, 24 h moderation — planning assumption adopted 2026-06-12).
  • Scope cost: no client-side logic total conversions in V4 (revisit when a V7-class WASM runtime is adoptable in UE).

Owners: Security Lead (Trust & Safety) — document of record; Workshop Service Lead — pipeline (§4); Online/Build leads — §5 assertion; Live Ops Director — §6 drills; Platform & Certification Manager — G5.