Phase 1: security & CWS hygiene fixes#4
Conversation
Точечные правки безопасности и CWS-гигиены без рефакторинга поведения: - Gemini API-ключ передаётся заголовком x-goog-api-key вместо ?key= в URL, чтобы он не попадал в performance-логи браузера и логи прокси. - chrome.runtime.onMessage теперь валидирует sender: разрешены только собственные страницы расширения и фреймы x.com/twitter.com. До этого любой iframe из all_frames=true мог дёргать TTA_* команды. - http://localhost/* и http://127.0.0.1/* перенесены из host_permissions в optional_host_permissions: дефолтный CWS-листинг чище, MCP-разрешение запрашивается runtime'ом только когда пользователь включит фичу. - document.execCommand('insertText') трижды дублировался; вынесен в один helper ttaInsertText() с цепью: InputEvent (modern) → execCommand (legacy) → прямое присваивание value/textContent. - options.js: persona hint рендерится через DOM API (replaceChildren + textContent), а не innerHTML — убирает XSS-вектор если hint когда-либо будет содержать user-controlled данные. - dev-logger.js: удалены URL-флаг ?tta_debug=1 и localStorage 'tta_debug' как источники включения; оба контролируются страницей x.com и могли быть взведены вредоносной ссылкой. Остался только chrome.storage и isDevBuild. - content_script.js: boot() запускается только в top-frame. Манифест по-прежнему all_frames=true ради совместимости с возможными nested фреймами X, но MutationObserver и подписки больше не множатся. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3451f7fb81
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "optional_host_permissions": [ | ||
| "http://127.0.0.1/*", | ||
| "http://localhost/*" | ||
| ], |
There was a problem hiding this comment.
Request localhost permission before MCP fetches
When MCP is configured to http://127.0.0.1:* or http://localhost:*, moving these origins into optional_host_permissions means they are no longer granted at install time, but I found no chrome.permissions.request path for the saved mcpUrl (rg "permissions.request|chrome.permissions" returns none). In MV3 the background fetch(url + path) used by TTA_MCP_STATUS, profile, and tweets therefore loses the host permission for existing/new users unless it was granted some other way, causing the MCP features to report offline despite a valid local gateway.
Useful? React with 👍 / 👎.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Первая партия правок по итогам кодревью. Точечные исправления безопасности и подготовка к Chrome Web Store submission — без рефакторинга поведения. Остальные фазы (i18n, provider abstraction, options split, selectors fallback, tooling, docs) пойдут отдельными PR-ами.
Что изменилось
background.jsx-goog-api-keyheader вместо?key=в URL — чтобы не утекал в performance-логи браузера и логи проксиbackground.jschrome.runtime.onMessageвалидируетsender: разрешены только страницы самого расширения и фреймы*.x.com/*.twitter.com. До этого любой iframe мог дёргатьTTA_*manifest.jsonhttp://localhost/*иhttp://127.0.0.1/*перенесены вoptional_host_permissions— CWS-листинг чище, MCP-разрешение запрашивается runtime'омcontent_script.jsdocument.execCommand('insertText')свёрнуты в один helperttaInsertText()с цепью InputEvent → execCommand → direct assignmentoptions.jsreplaceChildren/textContent), а неinnerHTML— закрыт потенциальный XSS, если hint когда-либо станет user-controlleddev-logger.js?tta_debug=1иlocalStorage 'tta_debug'как триггеры — оба контролируются страницей x.com и могли быть взведены вредоносной ссылкойcontent_script.jsboot()запускается только в top-frame; манифест по-прежнемуall_frames: true, но MutationObserver и подписки больше не множатся в nested iframesЧто НЕ трогалось в этом PR
_locales/— отдельный PR (объёмный)Test plan
chrome://extensions…/generateContent(без?key=в URL); ключ в заголовкеx-goog-api-keychrome.runtime.sendMessage('<extension-id>', {type:'TTA_GET_PREFS'})— должно отказать сsender_not_allowedx.com/?tta_debug=1(если пользователь не включал его явно через options)chrome.storage.local.set({ttaDebugLogs:true})→ overlay появляется (canonical path работает)🤖 Generated with Claude Code