iframeでChrome拡張機能の機密情報を安全に表示する
機密情報が含まれたコメントを、そのままWebページのDOMに置いてはいけない。
Chrome拡張機能が置いたDOMは、Webページ上で実行されるJavaScriptからも読み取れるため。
Webページの制作者は、機密情報を盗聴するスクリプトを仕込める。
annoでは以下のようなDOMをWebページに注入して、マーカーやアイコンを表示している。
code: 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ページの両方からアクセスできるファイルである。
code: annotation.html
<!DOCTYPE html>
<html>
<body>
<script type="module" src="dist/annotation.js"></script>
</body>
</html>
Web Accessible Resourceとして用意したannotation.jsにて、chrome.storageからデータを取り出してアイコンを表示する。 code: (一部)anno/src/annotation.ts
const 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内へのアクセスを防げる。 https://gyazo.com/84f3b90ea0ab2fd7e40b72e8fc42d989
コメントには機密情報が含まれるため、iframe内で扱う必要がある。
コメントを、iframe内に置いたアイコンをhoverしたときのツールチップとして表示する。
DOMとしてツールチップを描画すると、iframeの領域をはみ出して表示できない。
ブラウザ標準のツールチップを使えば、iframeの領域をはみ出して表示できる。
iframe内のアイコンimgにtitle属性をセットすれば、ツールチップを表示できる。 https://gyazo.com/d14e223cdb2a55ebaa3fbb7a7e6ff5f3