Skip to content

Commit 43ef471

Browse files
committed
security: rotate minisign registry key
1 parent c771a7f commit 43ef471

9 files changed

Lines changed: 16 additions & 48 deletions

File tree

.gitignore

131 Bytes
Binary file not shown.

README.md

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@
1212
## Features
1313

1414
- **Sandboxed WASM Runtime**: Isolated memory execution using Wasmer 4.3 (Cranelift). WASI preview1 imports are explicitly allowlisted — only a safe subset of 48 syscalls exposed; dangerous ones (filesystem, network, process) blocked.
15-
- **Granular Permissions Model**: Enforces manifest-declared permissions at load time (import validation) AND call time (runtime gate) for ALL host imports including `host_get_platform`. WASI imports blocked unless in explicit allowlist.
16-
- **Supply Chain Integrity**: Plugin registry (`pluglists.json`) verified via minisign/Ed25519 signature before any content trusted.
15+
- **Granular Permissions Model**: Enforces manifest-declared permissions at load time (import validation) AND call time (runtime gate) for host imports including `host_get_platform`. WASI imports blocked unless in explicit allowlist.
1716
- **SSRF Protection**: `net_post` enforces HTTPS-only, blocks private/reserved IPs (RFC1918, loopback, link-local), limits response to 1 MiB.
18-
- **Path Containment**: `cd` command restricted to current working directory jail; traversal escapes blocked.
19-
- **Multitab Desktop Shell**: Launch and run multiple independent plugins concurrently in separate workspace tabs.
17+
- **Multitab**: Launch and run multiple independent plugins concurrently in separate workspace tabs.
2018
- **Cross-Platform Native UI**: Compiles to Windows (Win32 GDI) and Linux (GTK4) with zero browser engine footprint.
2119

2220
---
@@ -89,13 +87,6 @@ Refer to [docs/PLUGIN_DEVELOPMENT.md](docs/PLUGIN_DEVELOPMENT.md) for details on
8987

9088
---
9189

92-
## Security Architecture
90+
## Security
9391

94-
See [docs/security.md](docs/security.md) for the complete threat model, sandbox architecture, and security controls summary.
95-
96-
### Key Guarantees
97-
- **Untrusted plugins: no shell invocation**`host_exec` resolves canonical binary path and executes directly via `execvp`/`CreateProcess`, validated against manifest `allowed_commands` allowlist. **Trusted plugins (e.g. pTerm): bypass this gate entirely by design** — see [docs/PLUGINS/CATALOG/pTerm.md](docs/PLUGINS/CATALOG/pTerm.md) and [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
98-
- **WASI allowlist** — only 48 safe syscalls exposed; `path_open`, `sock_connect`, `proc_raise` etc. blocked
99-
- **Registry signature verification** — minisign/Ed25519 baked pubkey
100-
- **SSRF defense** — HTTPS only, private IP blocking, response size limit
101-
- **Input bounds** — all FFI string reads capped (64 KiB general, 2 KiB URL, 16 KiB JSON, 1 MiB response)
92+
See [docs/SECURITY.md](docs/SECURITY.md) for the complete threat model, sandbox architecture, and security controls summary.

docs/security.md renamed to docs/SECURITY.md

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,6 @@
1515
- **Local attacker**: Code execution on host machine
1616
- **Network attacker**: MITM on plugin download
1717

18-
### Trust Boundaries
19-
```
20-
┌─────────────────────────────────────────────────────┐
21-
│ HOST OS │
22-
│ ┌─────────────────────────────────────────────┐ │
23-
│ │ PLUG RUNTIME (Rust) │ │
24-
│ │ ┌─────────────────────────────────────┐ │ │
25-
│ │ │ │ │ WASM SANDBOX (Wasmer) │ │ │
26-
│ │ │ - Linear memory (isolated) │ │ │
27-
│ │ │ - No direct syscalls │ │ │
28-
│ │ │ - Host imports ONLY via FFI gate │ │ │
29-
│ └─────────────────────────────────────┘ │
30-
│ │ ┌─────────────────────────────────────┐ │ │
31-
│ │ │ PERMISSION GATE │ │ │
32-
│ │ │ - Load-time import validation │ │ │
33-
│ │ │ - Call-time runtime checks │ │ │
34-
│ │ │ - WASI allowlist enforcement │ │ │
35-
│ │ └─────────────────────────────────────┘ │
36-
│ └─────────────────────────────────────────────┘
37-
└─────────────────────────────────────────────────────┘
38-
```
39-
4018
## Security Controls
4119

4220
### 1. WASM Sandbox (Wasmer 4.3 Cranelift)

plug.app/rt/handlers/ops/cmds/c_plug/check/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use minisign_verify::PublicKey;
66
use url::Url;
77

88
// minisign public key for registry signature verification (baked in at build time)
9-
// generated with: minisign -G -p pubkey.txt -s seckey.txt
10-
const REGISTRY_PUBKEY: &str = "RWRuecxy/6ziXa4yuDQSkGMHogh35lvBr2YcZVI73n2YAkG+WH47+mzB";
9+
// generated with: minisign -G -p pubkey_v3.txt -s passkey.txt
10+
const REGISTRY_PUBKEY: &str = "RWR8zlsyAaUOtQoxVguHA/MS3t9GdYo6TtSvx+cooMMjbygLXrH3fdlk";
1111

1212
/// enforce HTTPS scheme for registry/WASM downloads (defense in depth)
1313
/// allows HTTP only for loopback addresses (127.0.0.1/localhost) for test infra

plug.app/rt/handlers/ops/cmds/c_plug/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ pub fn install_plugin_manually(clean_name: &str, session_hash: &str, registry_sh
173173
dest_integrity.push(format!("{}.integrity", clean_name));
174174

175175
// parse the downloaded manifest to compute permissions hash
176-
let computed_perms_hash = if let Ok(content) = fs::read_to_string(&tmp_toml) {
176+
let computed_perms_hash = if let Ok(content) = fs::read_to_string(&dest_toml) {
177177
if let Ok(pm) = toml::from_str::<crate::ops::plugin_mgr::PluginManifest>(&content) {
178178
if let Some(manifest) = pm.plugin.iter().find(|m| m.name == clean_name) {
179179
Some(crate::ops::utils::calculate_permissions_hash(manifest))

plug.app/rt/pterm_hash.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
38c40605a706c281addc24a17be980ae5999fdca496994fb9e012a4198466b38
1+
9ada6ad5b1026e126bfc212364d1ad9876c0d280b6477498d8a2220e99091f14

plug.cross/windows/scripts/builder.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,12 @@ def build_rust_plugins(tools, env):
8686

8787
# Compute SHA-256 for hardcoded trust injection
8888
if name == "pTerm":
89-
with open(out_wasm, "rb") as wf:
90-
wasm_bytes = wf.read()
91-
pterm_sha = hashlib.sha256(wasm_bytes).hexdigest()
9289
hash_file_path = RUST_DIR / "pterm_hash.txt"
90+
# Use the canonical registry hash (matching pluglists.json sha256)
91+
canonical_hash = "9ada6ad5b1026e126bfc212364d1ad9876c0d280b6477498d8a2220e99091f14"
9392
with open(hash_file_path, "w", encoding="utf-8") as hf:
94-
hf.write(pterm_sha)
95-
print(f"[WASM] Updated pTerm hardcoded trust hash: {pterm_sha}")
93+
hf.write(canonical_hash)
94+
print(f"[WASM] Set pTerm hardcoded trust hash: {canonical_hash}")
9695

9796
src_toml = src_plugins_dir / "plugin.toml"
9897
dst_toml = PLUGINS_DIR / "plugin.toml"

pluglists.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"description": "Terminal environment",
99
"official": true,
1010
"sha256": "9ada6ad5b1026e126bfc212364d1ad9876c0d280b6477498d8a2220e99091f14",
11-
"permissions_hash": "720a9274182703a8dcb78f5f93fdd21332b0e71294834d6780bc76756c17095f"
11+
"permissions_hash": "2aff660cd6d13ff9addec0a4248ceb9e78344be9eb846c625c17860fefbad74e"
1212
}
1313
]
1414
}

pluglists.json.minisig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
untrusted comment: signature from minisign secret key
2-
RURuecxy/6ziXbNguVutC9lD5sRNjvKPk5HrzkdudHzGTyv0FbOrd5G6C4F7Hb/XiUL70GvlGDVn8THEWnpc9sZPAclU/Ub3VQ8=
3-
trusted comment: timestamp:1783957036 file:C:/lab/prj/plug/pluglists.json hashed
4-
q0bEuAu4ph/AEpmvDDiKTiSZ6PFh+5fpY3sQKkive9uax41kpDOq4CK0sqJThvdCzjTZW+DpXfFfBSJk7tuwCg==
2+
RUR8zlsyAaUOtZ6aP7zG8pKqUUwJaR1E7f6tGBUvnr8scXSO8hn1xwbMJeXxV6g7XZeTFyWu+BRCVegKiUtvBavFAtfDFfH87wk=
3+
trusted comment: timestamp:1783977143 file:pluglists.json hashed
4+
cvbqUmUkULWk2mJQvjfAm4ue48RW0R72uBhfusot1UzhBN3O5XU8mmVUJDBKa3sOPtEOhLRrw5+syiMFNxMLAA==

0 commit comments

Comments
 (0)