feat: implement browser extension UI with WebAssembly integration
This commit is contained in:
@@ -29,8 +29,67 @@ The browser extension is the main user interface for interacting with the modula
|
||||
|
||||
---
|
||||
|
||||
## Script Permissions & Security
|
||||
- **Session Password Handling**: The extension stores the keyspace password (or a derived key) securely in memory only for the duration of an unlocked session. The password is never persisted or written to disk/storage, and is zeroized from memory immediately upon session lock/logout, following cryptographic best practices (see also Developer Notes below).
|
||||
## Security Considerations
|
||||
|
||||
### Restricting WASM and Session API Access to the Extension
|
||||
|
||||
To ensure that sensitive APIs (such as session state, cryptographic operations, and key management) are accessible **only** from the browser extension and not from arbitrary web pages, follow these best practices:
|
||||
|
||||
1. **Export Only Safe, High-Level APIs**
|
||||
- Use `#[wasm_bindgen]` only on functions you explicitly want to expose to the extension.
|
||||
- Do **not** export internal helpers, state singletons, or low-level APIs.
|
||||
|
||||
```rust
|
||||
// Safe to export
|
||||
#[wasm_bindgen]
|
||||
pub fn run_rhai(script: &str) -> Result<JsValue, JsValue> {
|
||||
// ...
|
||||
}
|
||||
|
||||
// NOT exported: internal state
|
||||
// pub static SESSION_MANAGER: ...
|
||||
```
|
||||
|
||||
2. **Do Not Attach WASM Exports to `window` or `globalThis`**
|
||||
- When loading the WASM module in your extension, do not attach its exports to any global object accessible by web pages.
|
||||
- Keep all WASM interaction within the extension’s background/content scripts.
|
||||
|
||||
3. **Validate All Inputs**
|
||||
- Even though only your extension should call WASM APIs, always validate inputs to exported functions to prevent injection or misuse.
|
||||
|
||||
4. **Use Message Passing Carefully**
|
||||
- If you use `postMessage` or similar mechanisms, always check the message origin and type before processing.
|
||||
- Only process messages from trusted origins (e.g., your extension’s own scripts).
|
||||
|
||||
5. **Load WASM in Extension-Only Context**
|
||||
- Load and instantiate the WASM module in a context (such as a background script or content script) that is not accessible to arbitrary websites.
|
||||
- Never inject your WASM module directly into web page scopes.
|
||||
|
||||
#### Example: Secure WASM Export
|
||||
|
||||
```rust
|
||||
// Only export high-level, safe APIs
|
||||
#[wasm_bindgen]
|
||||
pub fn run_rhai(script: &str) -> Result<JsValue, JsValue> {
|
||||
// ...
|
||||
}
|
||||
// Do NOT export SESSION_MANAGER or internal helpers
|
||||
```
|
||||
|
||||
#### Example: Secure JS Loading (Extension Only)
|
||||
|
||||
```js
|
||||
// In your extension's background or content script:
|
||||
import init, { run_rhai } from "./your_wasm_module.js";
|
||||
|
||||
// Only your extension's JS can call run_rhai
|
||||
// Do NOT attach run_rhai to window/globalThis
|
||||
```
|
||||
|
||||
By following these guidelines, your WASM session state and sensitive APIs will only be accessible to your browser extension, not to untrusted web pages.
|
||||
|
||||
### Session Password Handling
|
||||
- The extension stores the keyspace password (or a derived key) securely in memory only for the duration of an unlocked session. The password is never persisted or written to disk/storage, and is zeroized from memory immediately upon session lock/logout, following cryptographic best practices (see also Developer Notes below).
|
||||
- **Signer Access**: Scripts can access the session's signer only after explicit user approval per execution.
|
||||
- **Approval Model**: Every script execution (local or remote) requires user approval.
|
||||
- **No global permissions**: Permissions are not granted globally or permanently.
|
||||
|
@@ -54,7 +54,7 @@ async fn main() {
|
||||
use kvstore::{KVStore, WasmStore};
|
||||
|
||||
// Must be called from an async context (e.g., JS Promise)
|
||||
let store = WasmStore::open("mydb").await.unwrap();
|
||||
let store = WasmStore::open("vault").await.unwrap();
|
||||
store.set("foo", b"bar").await.unwrap();
|
||||
let val = store.get("foo").await.unwrap();
|
||||
// Use the value as needed
|
||||
|
@@ -39,7 +39,7 @@ sal/
|
||||
|
||||
- **Each core component (`kvstore`, `vault`, `evm_client`, `rhai`) is a separate crate at the repo root.**
|
||||
- **CLI binary** is in `cli_app` and depends on the core crates.
|
||||
- **WebAssembly target** is in `web_app`.
|
||||
- **WebAssembly target** is in `wasm_app`.
|
||||
- **Rhai bindings** live in their own crate (`rhai/`), so both CLI and WASM can depend on them.
|
||||
|
||||
---
|
||||
|
Reference in New Issue
Block a user