iframeでChrome拡張機能の機密情報を安全に表示する
annoのマーカーやアイコンは、Chrome拡張機能によってWebページ上に表示させている。
機密情報が含まれたコメントを、そのままWebページのDOMに置いてはいけない。
Chrome拡張機能が置いたDOMは、Webページ上で実行されるJavaScriptからも読み取れるため。
Webページの制作者は、機密情報を盗聴するスクリプトを仕込める。
annoでは以下のようなDOMをWebページに注入して、マーカーやアイコンを表示している。
html<mark>マークしたテキスト</mark><iframe src="chrome-extension://knaeipbflmbfcmjpekonjedhmfkobdop/annotation.html?id=annodata-3eb6d5edd7091aa5bc234b54e60579d97aa7c4027a523c265b87a8a507133fc5" sandbox="allow-popups allow-popups-to-escape-sandbox allow-scripts" style="width: 28px; height: 28px"></iframe>Web Accessible Resourceは、拡張機能とWebページの両方からアクセスできるファイルである。
annotation.html<!DOCTYPE html><html> <body> <script type="module" src="dist/annotation.js"></script> </body></html>Web Accessible Resourceとして用意した
annotation.js にて、chrome.storageからデータを取り出してアイコンを表示する。(一部)anno/src/annotation.tsconst searchParams = new URLSearchParams(location.search);const id = searchParams.get("id");const { [id]: annodata } = await chrome.storage.local.get(id);const { url, description, iconURL, iconWidth, iconHeight } = annodata as Annodata; const linkElement = document.createElement("a");linkElement.href = url;linkElement.rel = "noopener";linkElement.target = "_blank";linkElement.title = description;
const imageElement = document.createElement("img");imageElement.src = iconURL;imageElement.style.verticalAlign = "middle";imageElement.style.width = `${iconWidth}px`;imageElement.style.height = `${iconHeight}px`;linkElement.append(imageElement);
document.body.append(linkElement);WebサイトとWeb Accessible Resourceは別オリジンになる。
CORSエラーになるため、WebページのJavaScriptからiframe内へのアクセスを防げる。
コメントには機密情報が含まれるため、iframe内で扱う必要がある。
コメントを、iframe内に置いたアイコンをhoverしたときのツールチップとして表示する。
DOMとしてツールチップを描画すると、iframeの領域をはみ出して表示できない。
ブラウザ標準のツールチップを使えば、iframeの領域をはみ出して表示できる。
iframe内のアイコンimgにtitle属性をセットすれば、ツールチップを表示できる。