feat: Implement Prompt Builder functionality in Popup and Options
Some checks failed
CI — Test & Build / Test & Build (push) Failing after 39s

- Added a new "Prompt Builder" tab in the Popup for generating AI prompts with customizable parameters.
- Introduced new state variables for managing prompt styles, personas, formats, and models.
- Enhanced the Options page to fetch and display models based on the provided API key.
- Updated the actions and types to include the new 'prompt' action and its associated parameters.
- Implemented migration logic for legacy plaintext API keys to encrypted storage.
- Updated the getSystemPrompt function to incorporate prompt parameters for better instruction generation.
- Added tests for the new functionality, including context menu entries and prompt generation logic.
This commit is contained in:
john kevin asprec
2026-07-15 15:27:41 +08:00
parent 0fef9848cb
commit acea99d7ad
40 changed files with 1971 additions and 177 deletions

48
docs/attacksurface.md Normal file
View File

@@ -0,0 +1,48 @@
# Attack surface — LexAI
> Living inventory of LexAI's exposure. Updated whenever manifest/permissions, storage, or provider handling changes, and before any Chrome Web Store push. Contains **no secrets** — only references. Maintained via the `attack-surface` skill; security review via `security-auditor`.
## Assets
| Asset | Type | Tech | Hosted | Auth in | Exposure | Defenses | Review cadence |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Content script | injected code | WXT/TS | client | n/a | **`<all_urls>`, all frames** | `data-lexai` guard; inline styles; max z-index | every manifest/permission change |
| Background service worker | LLM proxy | WXT/TS | client | user's provider key | reachable only via extension messages | key never logged; provider-only fetch | every key/provider change |
| `chrome.storage.local` | local store | Chrome | client | extension-only | holds `apiKeyEnc`+`encKey` (+ legacy plaintext `apiKey`) | tweetnacl secretbox (see weakness) | every key-handling change |
| Provider endpoints | 3rd-party API | HTTPS | OpenAI/Anthropic/Groq/OpenRouter | user's API key | outbound only, user-initiated | HTTPS; key in header only | on provider add/change |
| Gitea CI | pipeline | Gitea workflows | self/3p | `GITEATOKEN`, `CWS_*`, `TELEGRAM_*` | build + publish to CWS | secrets in Gitea; **but** `http.sslVerify false` (see gap) | on workflow change |
## Per-asset notes
### Content script — `<all_urls>`
- **Exposure:** injects into every frame of every site, including banking, email, internal apps. Biggest privacy surface and the #1 Chrome Web Store review slowdown.
- **Mitigation (proposed):** narrow to `activeTab` + on-demand injection, or a user allowlist (TASKS #1 / D-PROPOSED). Decide before a serious CWS push.
### API-key storage — obfuscation, not protection
- **Exposure:** `encKey` is stored in `chrome.storage.local` next to `apiKeyEnc`; anyone who can read storage can decrypt. The "encrypted" claim over-promises.
- **Secrets location:** `chrome.storage.local` (user's own browser). Never in repo, never logged.
- **Mitigation (proposed):** derive the key from `chrome.storage.session` / WebCrypto / a passphrase, and describe it honestly in the UI (TASKS #2 / D-...-06).
### Debug logging leak
- **Exposure:** `content.ts` logs selection text and element values to the host-page console — readable by the page.
- **Mitigation:** gate behind `import.meta.env.DEV` (TASKS #3).
### CI TLS verification disabled
- **Exposure:** both Gitea workflows set `http.sslVerify false` and `git clone` into `/tmp`.
- **Mitigation:** use the checked-out workspace and restore TLS verification (TASKS #17).
## Model / harness input surface (prompt-injection)
The extension sends **user-selected page text** to the chosen LLM with a fixed system prompt. Page-controlled text is untrusted input to the provider call.
| Input avenue | Consuming model | Reachable actions | Exposure | Defense in place |
| --- | --- | --- | --- | --- |
| Selected page text → `ANALYZE_TEXT` | user's provider | returns text shown in modal; user chooses Replace/Copy | injected instructions in page text could steer the model's output | user reviews output before Replace; no tool-calling; output is inert text |
- **Note:** exposure is low because the model output is inert (no tool execution) and the user gates Replace. Run `prompt-injection-audit` if LexAI ever adds auto-apply, tool use, or agentic actions.
## Gaps / unknowns
- Host-permission narrowing not yet decided (TASKS #1).
- Key-derivation redesign not yet done (TASKS #2).
- No automated check that production builds exclude debug logs (TASKS #3).