[{"data":1,"prerenderedAt":282},["ShallowReactive",2],{"content-/chrome-extension-security-review":3,"related-/chrome-extension-security-review":235,"all-pages-for-dir":280,"og-image-/chrome-extension-security-review":281},{"id":4,"title":5,"body":6,"category":217,"description":218,"extension":219,"meta":220,"navigation":129,"path":221,"project_name":222,"published":223,"publishedAt":224,"seo":225,"stem":226,"tags":227,"todo":233,"unpublished":223,"updatedAt":233,"__hash__":234},"pages/2026-06/2026-06-11/chrome-extension-security-review.md","自作Chrome拡張の一括セキュリティレビューとGit履歴からの機密データ除去",{"type":7,"value":8,"toc":203},"minimark",[9,13,17,21,24,27,30,34,37,50,58,61,65,73,76,81,84,88,95,102,105,109,112,115,118,168,171,197],[10,11,5],"h1",{"id":12},"自作chrome拡張の一括セキュリティレビューとgit履歴からの機密データ除去",[14,15,16],"p",{},"クラウド会計ソフトAと連携する自作のChrome拡張機能を、まるごとセキュリティレビューにかけた。脆弱性、行儀の悪いAPIの叩き方、バグ。気になっていたものを全部洗い出して直すつもりで頼んだら、コードの問題よりも先に背筋が冷える発見があった。顧客名やスプレッドシートIDの実値が、Git履歴の中に残っていた。",[18,19,20],"h2",{"id":20},"依頼の出し方",[14,22,23],{},"依頼はシンプルに「全コードをレビューして、問題点をMarkdownに書き出してから、全部修正をかけて」とした。レビューと修正を分けたのは、何を直したのか後から追えるようにしたかったから。",[14,25,26],{},"着手前にひとつ条件を足した。未コミットの変更が残っていたら、先にステージング＆コミットして、クリーンな状態からやってもらうこと。これが効いた。レビュー対象の差分と修正の差分が混ざらず、後のセルフレビューで「どの修正がどの指摘に対応するか」を差分単位で追えた。",[14,28,29],{},"ちなみにコミットされた未コミット変更は sessionStorage → chrome.storage.local への移行だった。このコミットに対して自動セキュリティレビューが走り、「タブ単位・セッション単位だった状態がグローバル・永続に変わり、消費側がその寿命を安全装置として当てにしていた」という指摘を別途返してきた。自分では「保存先を変えただけ」のつもりだった変更に、状態の寿命という観点が刺さった。",[18,31,33],{"id":32},"レビュー結果-critical-4-high-10-medium-9","レビュー結果: Critical 4 / High 10 / Medium 9",[14,35,36],{},"全コードを6並列でレビューしてもらい、検出されたのは以下。",[38,39,40,44,47],"ul",{},[41,42,43],"li",{},"Critical: 4件",[41,45,46],{},"High: 10件",[41,48,49],{},"Medium: 9件",[14,51,52,53,57],{},"指摘内容は ",[54,55,56],"code",{},"memo/2026-06-11/code-review-findings.md"," に書き出した上で、22件を修正してもらった。修正対象は import.js の自動クリックフラグ、CSRF・エラーハンドリング不備、bridge.js、content.js のXSS、storage.js、background.js の4ハンドラなど多岐にわたる。",[14,59,60],{},"修正後は構文チェックとテストを実行し、392件全パス。コミット前にリスクの高い変更（autoclick の書き換えと try/finally ラップ）だけは差分でセルフレビューさせてからコミットした。",[18,62,64],{"id":63},"発覚-defaultsjson-の顧問先実名がgit履歴に残っていた","発覚: defaults.json の顧問先実名がGit履歴に残っていた",[14,66,67,68,72],{},"レビューの残り1件として「defaults.json に顧問先の実名が入っている」という判断事項が上がってきた。defaults.json 自体は .gitignore 済みだったが、",[69,70,71],"strong",{},"過去のコミットには残ったまま","だった。.gitignore は「これから追跡しない」だけで、すでに歴史に刻まれたものは消してくれない。",[14,74,75],{},"対応として、defaults.json を全Git履歴から除去してもらい、GitHubへ force push した。ローカルのファイルは無傷なので、拡張機能はそのまま動く。",[77,78,80],"h3",{"id":79},"turso化は見送り","Turso化は見送り",[14,82,83],{},"このとき「機密データはTurso（SQLiteベース）に入れてレプリカから読み出す方がいいのか」も検討した。Chrome拡張からそれが機能するのかも分からないまま投げてみたが、結論は「Turso化は不要」。gitignore済みのローカルJSONで運用は成り立っており、履歴からの除去さえ済めば、わざわざDB層を足す理由がない。提案して、理由を聞いて、やらないと決める。この往復が数分で終わるのはありがたい。",[18,85,87],{"id":86},"第二波-実データ入りダンプが14ファイル","第二波: 実データ入りダンプが14ファイル",[14,89,90,91,94],{},"defaults.json で終わりかと思ったら、続きがあった。memo配下に ",[54,92,93],{},"page.html"," というスナップショットがあり、正体を確認してもらったところ、会計ソフトAの画面をまるごと保存した実データ入りのHTMLダンプだった。",[14,96,97,98,101],{},"調査を広げると、当初把握していた3件に加えて同類のスナップショットが11件見つかり、",[69,99,100],{},"計14ファイル","を作業ツリーと全Git履歴から除去して force push。さらにスクリーンショット27件も履歴ごと消した。memo のファイル名（作業記録としての名前）は温存し、実データを含む中身だけを消すという仕分けにした。",[14,103,104],{},"開発中に「とりあえず保存」したページダンプやスクリーンショットが、機密データの倉庫になっていた。コードの脆弱性より、こっちの方がよほど現実的なリスクだったと思う。",[18,106,108],{"id":107},"仕上げ-chrome-devtoolsでスモークテスト","仕上げ: Chrome DevToolsでスモークテスト",[14,110,111],{},"履歴書き換えという荒療治の後なので、拡張機能が壊れていないかのスモークテストまでやってもらった。Chrome DevTools MCP経由で、ログイン済みの自分のChromeに接続し、実データを書き込まない範囲でコンソールエラーと拡張パネルの描画を確認。全項目グリーン。",[14,113,114],{},"並行して、全refで機密ファイルの残存ゼロも確認してもらった。",[18,116,117],{"id":117},"最終状態",[38,119,122,132,138,144,150,156,162],{"className":120},[121],"contains-task-list",[41,123,126,131],{"className":124},[125],"task-list-item",[127,128],"input",{"checked":129,"disabled":129,"type":130},true,"checkbox"," 全コードレビュー: Critical 4 / High 10 / Medium 9 を検出、22件修正",[41,133,135,137],{"className":134},[125],[127,136],{"checked":129,"disabled":129,"type":130}," テスト392件全パス",[41,139,141,143],{"className":140},[125],[127,142],{"checked":129,"disabled":129,"type":130}," defaults.json（顧問先実名）を全Git履歴から除去、force push",[41,145,147,149],{"className":146},[125],[127,148],{"checked":129,"disabled":129,"type":130}," 実データ入りダンプ14ファイルを履歴ごと除去",[41,151,153,155],{"className":152},[125],[127,154],{"checked":129,"disabled":129,"type":130}," スクリーンショット27件を履歴ごと除去",[41,157,159,161],{"className":158},[125],[127,160],{"checked":129,"disabled":129,"type":130}," Chrome DevTools MCPでスモークテスト、全項目グリーン",[41,163,165,167],{"className":164},[125],[127,166],{"disabled":129,"type":130}," Turso化 → 検討の結果、不要と判断して見送り",[18,169,170],{"id":170},"学び",[38,172,173,179,185,191],{},[41,174,175,178],{},[69,176,177],{},".gitignore は過去を消さない","。機密ファイルをignoreに足して安心していたが、追加前のコミットには全部残っていた。「いつからignoreしたか」を一度も確認していなかった",[41,180,181,184],{},[69,182,183],{},"開発中の「とりあえず保存」が一番危ない","。ページダンプ・スクリーンショットといった作業の副産物に実データが詰まっていた。コードレビューを頼んだら、コード外から機密が出てきた",[41,186,187,190],{},[69,188,189],{},"レビューの前にクリーンコミット","。未コミット変更を先に片付けてから始めると、指摘と修正が差分単位で対応づく",[41,192,193,196],{},[69,194,195],{},"「やらない判断」も外部化できる","。Turso化のような構成変更は、自分で調べると半日かかる。投げて、理由付きで「不要」と返ってきたら、それで閉じられる",[14,198,199,200,202],{},"作業記録は ",[54,201,56],{}," に残してある。",{"title":204,"searchDepth":205,"depth":205,"links":206},"",2,[207,208,209,213,214,215,216],{"id":20,"depth":205,"text":20},{"id":32,"depth":205,"text":33},{"id":63,"depth":205,"text":64,"children":210},[211],{"id":79,"depth":212,"text":80},3,{"id":86,"depth":205,"text":87},{"id":107,"depth":205,"text":108},{"id":117,"depth":205,"text":117},{"id":170,"depth":205,"text":170},"dev","クラウド会計ソフトA連携の自作Chrome拡張を対象に、脆弱性・バグの一括コードレビューと修正を実施。途中で顧客名入りファイルがGit履歴に残っていることが発覚し、履歴書き換えで除去するまでの記録。","md",{},"/chrome-extension-security-review","misc-dev",false,"2026-06-11T00:00:00.000Z",{"title":5,"description":218},"2026-06/2026-06-11/chrome-extension-security-review",[228,229,230,231,232],"Chrome拡張","セキュリティレビュー","Git履歴書き換え","Claude Code","機密情報管理",null,"rKSgSUgimdl4NMs76by_E9TAoAb77sND5ifgSJJhpjg",[236,244,253,262,270],{"title":237,"description":238,"path":239,"tags":240,"publishedAt":243,"updatedAt":233},"Claude Code のセキュリティレビュー・プラグインは、ローカル一人運用ならユーザーレベルだけで十分だった","Claude が書いたコードを自動でセキュリティレビューするプラグインを導入する話。プラグインの有効化スコープ（ユーザーレベル vs プロジェクトの settings.json）という判断軸を整理し、一人ローカル運用なら settings.json は不要と決めた記録。","/claude-code-security-review-setup",[231,229,241,242],"プラグイン","開発環境","2026-05-27T00:00:00.000Z",{"title":245,"description":246,"path":247,"tags":248,"publishedAt":224,"updatedAt":233},"簿記学習ノートの演習を自作問題集ベースに再設計し、クラウド会計風の帳簿アプリを実装した日","自動生成した70問を捨てて検証済みの自作仕訳問題集に演習を置き換えた記録。長大ページの分割、学習方法ページの不整合解消、紙の帳簿前提の出題への違和感から仕訳帳・総勘定元帳・補助元帳をテーブルで再現する帳簿アプリも新規実装した。","/bookkeeping-notes-practice-redesign",[249,250,251,231,252],"簿記","教材設計","Nuxt","開発日記",{"title":254,"description":255,"path":256,"tags":257,"publishedAt":224,"updatedAt":233},"蔵書DBの技術書を自分用に全編リライト——Miller Column学習コンテンツとQ&A図解化をClaude Codeで作った日","蔵書DBに取り込んだ設計系技術書を自分向けにリライトする計画を立て、別セッションで13章62トピックを並列生成。Q&A形式の投資実務書77問もカード分割・矢印キー移動・SVG図解付きで作り直した記録。","/coding-principles-and-book-qa",[231,258,259,260,261],"蔵書DB","学習コンテンツ","SVG図解","スキル改善",{"title":263,"description":264,"path":265,"tags":266,"publishedAt":224,"updatedAt":233},"スクショ1枚からSynthesia風ピアノロールWebアプリを作ってもらった日——88鍵Canvas＋Web Audio合成＋運指表示","「ピアノアプリ作ってもらいたいんですけど」と画像1枚を見せたところから、Synthesia風ピアノロール /piano-roll が完成するまでの記録。再生時計が止まる謎、devサーバーの古いコード配信、公開化で見つかったOGメタタグ不足14件の一括修正まで。","/piano-roll-web-app",[267,268,269,231,251],"ピアノロール","Web Audio","Canvas",{"title":271,"description":272,"path":273,"tags":274,"publishedAt":279,"updatedAt":233},"会計学習ノート全26章の抜本見直しと連結精算表コンテンツの総点検","連結精算表の全19論点をバグチェックし、貸借不一致を含む実バグ3件を修正。さらにドキュメント作成の専門書から生成したスキルで学習ノート全26章を見直す計画を立て、次セッションへ引き継いだ記録。","/accounting-notes-overhaul",[275,276,277,278,231],"コンテンツ設計","テスト","連結会計","ドキュメント作成","2026-06-10T00:00:00.000Z",[],"https://log.eurekapu.com/og/blog/chrome-extension-security-review.png?v=2026-06-11T00%3A00%3A00.000Z&title=%E8%87%AA%E4%BD%9CChrome%E6%8B%A1%E5%BC%B5%E3%81%AE%E4%B8%80%E6%8B%AC%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E3%81%A8Git%E5%B1%A5%E6%AD%B4%E3%81%8B%E3%82%89%E3%81%AE%E6%A9%9F%E5%AF%86%E3%83%87%E3%83%BC%E3%82%BF%E9%99%A4%E5%8E%BB&author=Kei%20Komatsu&sig=8a4ce2cbce9ba333",1781333880380]