SafeFrame2.0のdraft読んでみた

# SafeFrame2.0のdraft

SafeFrame2.0のdraftが完成したようなので読んでみました。
https://iabtechlab.com/wp-content/uploads/2020/07/IAB-Tech-Lab-SafeFrame-2-0-draft-for-public-comment-2020-07-29.pdf

# SafeFrameとは何か？

インターネット広告業界で使われている広告枠の仕様のことです。
ブラウザ上に表示される広告枠は、基本的にhtml/javacript/cssで作成されています。
僕が知る限りだとSafeFrameを実際に導入している広告配信サービスは、Googleアドマネージャーだけです。

# なぜSafeFrameが必要か？

インターネット広告に詳しくない人だと、広告枠に仕様なんて必要なのか？疑問に持つかもしれません。

昨今のインターネット広告の問題と照らし合わせながら説明すると、
例えば、海外サイトや怪しいサイトを訪れた際に、ページを開いた後に、勝手にリダイレクトして、
商品当選のメッセージが表示されたり、エロサイトに誘導された経験はありませんでしょうか。

このようなことを防ぐために、広告枠への制限の掛け方の仕様を定めたのが、SafeFrameという考え方です。

ちなみに、このようなリダイレクトするページには、例えば以下のようなscriptが仕掛けられていたり、
広告として配信されています。

```
<script type="text/javascript">
  var redirect = function(){window.top.location="//www.google.com";};
  setTimeout(redirect, 3000);
</script>
```

これは、3秒後にgoogleのトップページにリダイレクトします。
例えば、このURLを商品当選のページにURLに変更すると、3秒後にそのURLに遷移します。

このscriptが、単純にdivなどで囲まれた広告に配信されるとページが遷移します。

```
<div>
  <script src="https://bad-ad.co.jp">
  <!-- ここから配信される悪意のある広告 -->
    <script type="text/javascript">
      var redirect = function(){window.top.location="//www.google.com";};
      setTimeout(redirect, 3000);
    </script>
  </script>
</div>

```

このようなことを防ぐために、SafeFrameが存在します。

また、様々な広告表現やサービスが増えているなかで、セキュリティを担保しながらこれらを実現するには、
既存の仕様では賄いきれないために、新しいバージョンのSafeFrameを作成するらしいです。

詳しくは、[Summary](https://iabtechlab.com/wp-content/uploads/2020/07/IAB-Tech-Lab-SafeFrame-2-0-draft-for-public-comment-2020-07-29.pdf)をご参照ください。

ちなみ、過去のSafeFrame1.1は、2013年にリリースされているので、かなり古いです。

# 具体的なSafeFrame2.0の中身

## セキュリティ

ベースのセキュリティとしては、iframeのsandbox属性を利用しているので、ブラウザに依存します。
https://www.w3schools.com/tags/att_iframe_sandbox.asp

古いブラウザ(IE9以前)や対応していないブラウザでは動かないです。

また、すべてのsandbox属性ではなく、以下の属性を適用することを推奨しています。

allow-top-navigation-by-user-activation
allow-popups-to-escape-sandbox
allow-forms
allow-scripts
allow-same-origin
allow-popups

それぞれどのような挙動をするかは、こちらのページでご確認ください。
https://developer.mozilla.org/ja/docs/Web/HTML/Element/iframe

このページの「サンドボックスのメモ」に

```
埋め込まれた文書のオリジンが埋め込み先のページと同じである場合、 allow-scripts と allow-same-origin を同時に使用すると、埋め込まれた文書から sandbox 属性を削除することができるようになるため、絶対に避けるべきです。 — sandbox 属性をまったく使用しないよりも安全ではなくなります。
```

と書かれていますが、大丈夫なのでしょうか。

```
埋め込まれた文書のオリジンが埋め込み先のページと同じである場合
```

とあるので、仮に、広告を表示するページ(page.html)内に同一オリジンの広告表示用のhtml(ad.html)が存在し、ad.htmlからアドサ-バ/ADNW/SSPなどのタグが設定されると結局、同一オリジンで実行されてしまうってことだと思うので、こういう構成で広告配信をすることはやめましょう。

## API提供

Safeframeには、APIの定義がいくつかされています。

MRAIDとの兼ね合い？とかもあり、バージョン1.1から変更/削除/追加になっているみたいです。

MRAIDとは、Mobile Rich Media Ad Interface Definitionsのことで、
インタラクションがある広告フォーマットを実現するときのjavascript的なお作法などが記載されています。
https://iabtechlab.com/standards/mobile-rich-media-ad-interface-definitions-mraid/

個別のfunctionに関しては、興味のある人はご確認いただければと思います。

APIを提供している意味としては、
枠の大きさを変えたり動的な広告をSafeframe上で表現するためです。

javascriptでの実行を許可するとセキュリティが担保できないので、あらかじめ必要そうなものを準備して、それを活用してもらうようなイメージです。

# Cross Domain iframe with sandbox

せっかくなので、実際にiframeのsandboxを設定して、検証してみましょう。

クロスドメインのhtmlをsandbox付きのiframeで呼び出してみましょう。
まずは、macのchromeで検証します。

## 悪意のあるスクリプト

3秒後にgoogleのトップページにリダイレクトする悪意のあるスクリプトを準備します。
今回はgoogleに飛ばしますが、これが商品当選ページだったりします。

redirect.html

```
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <script type="text/javascript">
    var redirect = function() {
      window.top.location="https://www.google.com";
    };
    setTimeout(redirect, 3000);
  </script>
</body>
</html>
```

### sandboxなし

#### html

page.html

```
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <iframe src="https://adtech-academy.com/reference/redirect.html" width=300 height=250>
</body>
</html>
```

#### 結果

リダイレクトがブロックされましたというメッセージが表示されました。
また、consoleに以下エラーが表示されています。

```
redirect.html:9 Unsafe JavaScript attempt to initiate navigation for frame with origin 'file://' from frame with URL 'https://adtech-academy.com/reference/redirect.html'. The frame attempting navigation is targeting its top-level window, but is neither same-origin with its target nor has it received a user gesture. See https://www.chromestatus.com/features/5851021045661696.

(anonymous) @ redirect.html:11
redirect.html:9 Uncaught DOMException: Failed to set the 'href' property on 'Location': The current window does not have permission to navigate the target frame to 'https://www.google.com'. at redirect (https://adtech-academy.com/reference/redirect.html:9:26)
```

### sandboxあり

#### html

page.html

```
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <iframe 
    src="https://adtech-academy.com/reference/redirect.html" width=300 height=250 
    sandbox="allow-top-navigation-by-user-activation allow-popups-to-escape-sandbox allow-forms allow-scripts allow-same-origin allow-popups"
  >
</body>
</html>
```

#### 結果

consoleに表示されるエラーメッセージは先ほどと同じですが、リダイレクトをブロックするというメッセージが表示されないです。

### sandboxあり+allow-top-navigation

page.html

```
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <iframe 
    src="https://adtech-academy.com/reference/redirect.html" width=300 height=250 
    sandbox="allow-top-navigation-by-user-activation allow-popups-to-escape-sandbox allow-forms allow-scripts allow-same-origin allow-popups allow-top-navigation"
  >
</body>
</html>
```

#### 結果

consoleにエラーが表示されず、3秒後にgoogleのトップページに遷移しました。

## ブラウザごとの挙動

他のブラウザでも試した結果です。

```
chrome(mac): 85.0.4183.121
  sandboxなし: リダイレクトしない
  sandboxあり: リダイレクトしない
  sandboxあり+allow-top-navigation: リダイレクトする

safari(mac): 14.0 (14610.1.28.1.9) 
  sandboxなし: リダイレクトしない
  sandboxあり: リダイレクトしない
  sandboxあり+allow-top-navigation: リダイレクトする

firefox(mac): 81.0 (64 ビット)
  sandboxなし: リダイレクトする
  sandboxあり: リダイレクトしない
  sandboxあり+allow-top-navigation: リダイレクトする  

chrome(pixel3 android11): 85.0.4183.127
  sandboxなし: リダイレクトしない
  sandboxあり: リダイレクトしない
  sandboxあり+allow-top-navigation: リダイレクトする

IE(windows10): 11
  sandboxなし: リダイレクトする
  sandboxあり: リダイレクトしない
  sandboxあり+allow-top-navigation: リダイレクトする

Edge(windows10): 85.0.564.63
  sandboxなし: リダイレクトしない
  sandboxあり: リダイレクトしない
  sandboxあり+allow-top-navigation: リダイレクトする
```

FirefoxとIE11でsandboxなしのiframeだと、リダイレクトしてしまうぽいですね。
いいのか悪いのかはわかりません。

# 感想等々

インターネット広告配信は、なぜその場所にその広告が表示されているのか、言語化して説明するのが不可能なくらい複雑になっています。
そのため、悪意のあるスクリプトが広告として配信されても止めることが難しいことがあります。
このようなことを防ぐためにも広告枠自体に制限をかけるということは、正しいアプローチなのかなと思います。

広告枠に制限をかけることでユーザーを守れる可能性があがりますが、ブラウザから取得できる情報が少なくなるので、その情報をベースにインターネット広告関連サービスを提供している事業者に影響がでるかもしれません。

たぶん、Googleアドマネージャーがそのうち実装すると思うので、それに追従するように他事業者も対応するのかなと思います。
今後もこのへんの情報を収集しながら、注視していきたいです。

# 最後に宣伝

[「Adtech Academy」](https://adtech-academy.com/login)というサービスを提供しています。

今のところ、アドテクに関するプログラミングの問題（特に広告枠の問題）を提供しているので、
興味のある人は、ご利用いただければと思います。