# [ERC7087] Web3 URLのMIMEタイプ指定仕組みを理解しよう！

> ERC7087は、ERC6860で定義されている web3:// プロトコルを拡張する提案です。

- URL: https://cardene.dev/articles/8625895604e9ffe95f88
- 公開日: 2025-11-25
- 更新日: 2025-11-25
- トピック: Blockchain
- タグ: ethereum, solidity, smartcontract, ブロックチェーン

## はじめに

『DApps開発入門』という本や色々記事を書いているかるでねです。

https://amzn.asia/d/gxvJ0Pw

今回は、ブラウザが誤解釈しないよう、Web3 URLの返却データに適切なMIMEタイプを与える仕組みを提案している**ERC6860**の拡張仕様を提案している**ERC7087**についてまとめていきます！

:::message
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-7087

他にも様々なEIP・BIP・SLIP・CAIP・ENSIP・RFC・ACPについてまとめています。

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

## 概要

**ERC7087**は、**ERC6860**で定義されている `web3://` プロトコルを拡張する提案です。
`web3://` に対応していないスマートコントラクトを「**`auto` モード**」で呼び出したとき、返ってくるデータの種類（MIMEタイプ）が次のどちらかの状態になっています。

:::message
**ERC6860**については以下の記事を参考にしてください。
:::

[\[ERC6860\] HTTPスタイルのWeb3URLを使用してオンチェーンコンテンツにアクセスする仕組みを理解しよう！](/articles/30bdd75be892cf776b88)

* スマートコントラクト側で明示されておらず、利用者から見ると暗黙的になっている
* 返却されるデータの中に、「**RFC 2397 data URL（データそのものとその種別を一体で表現するURL形式）**」として埋め込まれている

ここでいうMIMEタイプとは、「**これはHTMLです**」、「**これは画像です**」、「**これはJSONです**」といった、データの種類を表す識別子のことです。
例えば、 `text/html` や `image/png` のような文字列です。

この標準では、こうしたケースでも `web3://` 経由でデータを取得するときに、追加のクエリパラメータを使ってMIMEタイプを得られるようにします。
さらに、スマートコントラクトが**RFC 2397 data URL**を返す場合、そのデータが**data URL**であることをURL側で指定できるようにし、`web3://` プロトコル側で中身をデコードした上で、**data URL**内で宣言されているMIMEタイプ情報を添えて返せるようにすることを目指しています。

## 動機

Webブラウザでデータを正しく表示するためには、「**このレスポンスはどんな種類のデータか**」を示す `Content-Type` ヘッダーが付いていることが強く推奨されます。
これが無い、あるいは不正確だと、ブラウザが内容を誤解釈し、文字化けやレイアウト崩れ、ダウンロード扱いになるなど、期待しない表示になる可能性があります。

`web3://` プロトコルには「**`manual` モード**」と「**`auto` モード**」の2つのモードがあります。
それぞれの役割はおおまかに以下のようになっています。

| モード名 | 説明  |
| ---------- | --------- |
| `manual` モード | スマートコントラクトが専用のインターフェースを実装し、「**`manual` モードで動作したい**」と明示的に指定するモードです。この場合、**ERC6860**で定義されている仕組みを使って、スマートコントラクト側が返却データの MIMEタイプを明示することが期待されています。  |
| `auto` モード   | 専用のインターフェースで「**`auto` モード**」と明示したスマートコントラクトだけでなく、何も指定していない「**普通の**」スマートコントラクトに対しても使われるモードです。明示的に `auto` モードを選んでいるコントラクトであればMIMEタイプを返してくれることも期待できますが、何も対応していない既存コントラクトについては、MIMEタイプがわからない前提になります。 |

問題は、この `auto` モード側です。
`web3://` を意識して作られていない既存コントラクトは、ブラウザに返したいデータを持っていても、その種類をプロトコル側に正しく伝える手段がありません。
場合によっては、返却データの中に**RFC 2397 data URL**形式でMIMEタイプが含まれていることもありますが、プロトコルから見ると「**ただのバイト列**」であり、それをどう扱うかをURLやブラウザ側が判断しにくくなっています。

**ERC6860**は `manual` モードのスマートコントラクトについては、MIMEタイプをきちんと扱う仕組みを提供していますが、`auto` モードで既存コントラクトを扱うときには空白が残っていました。

この標準は、その空白を埋めることを目的としています。
具体的には、以下の2点を実現しようとしています。

- `web3://` URL に追加のクエリパラメータを導入し、URL側で「**このリクエストで期待するMIMEタイプ**」を指定できるようにすること
    これにより、スマートコントラクトがMIMEタイプを教えてくれない場合でも、`web3://` プロトコルは適切な `Content-Type` を付けてブラウザに返せるようになります。

- スマートコントラクトが**RFC 2397 data URL**を返す場合に、そのデータが**data URL**であることをURLで明示できるようにすること
    こうすることで、`web3://` プロトコルは data URL をいったんデコードし、中に含まれている「**本来のデータ**」と「**そのMIMEタイプ**」を取り出して、ブラウザにとって扱いやすい形で返せるようになります。

このように、ブラウザが期待どおりにコンテンツを解釈・表示できるようにするために、**ERC6860**を補完する形で、`auto` モードや既存コントラクトでもMIMEタイプをきちんと扱えるようにするのが、この標準の狙いです。

## 仕様

#### MIMEタイプを指定する3つのクエリパラメータ

MIMEタイプを決める方法として、以下の3つが用意されています。

| クエリパラメータ | 説明 |
| ----------- | ------------------------ |
| `mime.content=<contentType>` | `<contentType>` に**RFC6838**で定義されている正式なMIMEタイプを指定します。URLデコード後、この値がレスポンスの `Content-Type` ヘッダーにそのまま設定されます。形式がMIMEタイプとして正しくない場合、URLは実行されずエラーが表示されます。   |
| `mime.type=<fileType>`   | `<fileType>` に拡張子（例：svg, png など）を指定します。拡張子から対応するMIMEタイプを特定し、その値が `Content-Type` に設定されます。認識できない拡張子の場合、URLは実行されずエラーになります。   |
| `mime.dataurl` | 返却されるデータを「**RFC 2397 data URL**」として解釈することを示します。返却データが `data:application/json,...` のような形式である前提で処理され、デコード後の本体データがそのまま返却され、data URLに含まれているMIMEタイプが `Content-Type` として使われます。data URLとして解析できない場合はエラーになります。 |

#### クエリパラメータの優先順位と無視されるケース

クエリパラメータが複数指定されている場合、最後に書かれたものが適用されます。
もし `mime.xxx` のいずれも指定されていない場合、MIMEタイプは**ERC6860**に従って処理されます。

また、もし `returns` というクエリパラメータが指定されている場合、`mime.content`、`mime.type`、`mime.dataurl` の設定はすべて無視され、`Content-Type` は**ERC6860**の規定に従います。

#### ABNF記法で示される構文

定義を形式的に示すために、**RFC2234**で使われるABNF記法が用いられています。

https://tex2e.github.io/rfc-translater/html/rfc2234.html

まず、**ERC6860**における従来の構文は以下です。

```
attribute       = attrName "=" attrValue
attrName        = "returns"
                / "returnTypes"
attrValue       = [ "(" [ retTypes ] ")" ]
```

今回の標準では、これにMIME関連の属性が加わります。

```
attribute       = retAttr / mimeCAttr / mimeTAttr / mimeDAttr

retAttr         = retAttrName "=" retAttrValue
retAttrName     = "returns"
                / "returnTypes"
retAttrValue    = [ "(" [ retTypes ] ")" ]

mimeCAttr       = "mime.content=" mimeCAttrVal
mimeCAttrVal    = # ABNF of MIME type as in RFC 6838 

mimeTAttr       = "mime.type=" 1*( ALPHA / DIGIT )

mimeDAttr       = "mime.dataurl"
```

新しい構文により、`returns`と`returnTypes`に加えて、MIMEタイプに関する3つの指定方法が正式に扱われるようになっています。

#### 例

ここでは具体例を挙げながら、各クエリパラメータがどのように解釈されるかを説明します。

##### 例1：mime.content による MIMEタイプの直接指定

```
web3://0x91cf36c92feb5c11d3f5fe3e8b9e212f7472ec14/accessorizedImageOf/1289?mime.content=image/svg%2Bxml
```

コントラクトは `auto` モードです。
指定された `mime.content=image/svg+xml` が `Content-Type` に設定されます。

##### 例2：mime.type による拡張子からの判定

```
web3://0x91cf36c92feb5c11d3f5fe3e8b9e212f7472ec14/accessorizedImageOf/1289?mime.type=svg
```

コントラクトは `auto` モードです。
`mime.type=svg` から MIMEタイプが解決され、`image/svg+xml` が `Content-Type` として設定されます。

##### 例3：`mime.dataurl` によるdata URLのデコード

```
web3://0xff9c1b15b16263c61d017ee9f65c50e4ae0113d7/tokenURI/100?mime.dataurl
```

`auto` モードのコントラクトが戻すデータは以下のような**data URL**形式です。

```
data:application/json,["xx"]
```

`mime.dataurl` が指定されているため、返却データは**data URL**として解析・デコードされます。

結果として返されるデータは `["xx"]` になり、`Content-Type` には `application/json` が設定されます。

## 補足

**ERC6860**では、3つの異なるクエリパラメータを用意しています。
これは、ひとつのパラメータに複数の形式を詰め込むと、開発者や利用者が「**このURLは最終的にどのMIMEタイプになるのか**」を判断しづらくなるためです。

`mime.content`、`mime.type`、`mime.dataurl` の3種類が分かれていることで、URLを見るだけで意図が明確になります。
例えば、`mime.content=` があれば「**MIMEタイプを直接指定している**」、**`mime.type=` なら「拡張子から判断する**」、`mime.dataurl` なら「**返却データをdata URLとして扱う**」ことがすぐにわかります。

さらに、`auto` モードではクエリパラメータがEVMメッセージ（`calldata` など）を構築する時に影響を与えません。
そのため、新しいパラメータを追加しても既存仕様を壊すことがなく、安全に拡張できます。

## セキュリティ

これらの新しいクエリパラメータは、クロスサイトスクリプティング（XSS）を誘発する可能性があります。
悪意のある攻撃者が、スマートコントラクトが返す文字列やバイト列を自分の思うように操作できると、そのデータをHTMLとして解釈させるURLを組み上げ、被害者に送信することができます。

もし `web3://` のホスト名が広く知られており信頼されている場合、被害者はそのURLを安全だと勘違いし、攻撃に気づかずに開いてしまうおそれがあります。

こうした攻撃で可能になる行動は幅広く、例えば以下のようなものがあります。

| 攻撃内容  | 説明 |
| -------------- | ------------- |
| Webストレージのデータ取得 | cookie、localStorage、sessionStorage、indexedDB などの内容を盗み出し、攻撃者に送信できます。 |
| ウォレット操作の誘発     | JavaScript 経由で署名要求やトランザクション確認を強制的に表示させることができます。                     |

クロスサイトスクリプティングはHTTPの世界では古くから存在する一般的な攻撃手法です。
開発者は当然注意すべきですが、`web3://` の仕組みでは「**URL側からMIMEタイプを指定できる**」点が通常と異なるため、特に注意が必要です。

そのため、`auto` モードで動作するウェブサイトは安易に使わないことが推奨されます。
また、こうした攻撃ベクトルは十分に説明し、利用者や開発者が理解して対策を取れるようにすることが重要です。











## 引用

Qi Zhou (@qizhou), Nicolas Deschildre (@nand2), "ERC-7087: MIME type for Web3 URL in Auto Mode [DRAFT]," Ethereum Improvement Proposals, no. 7087, May 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7087.

## 最後に

今回は「ブラウザが誤解釈しないよう、Web3 URLの返却データに適切なMIMEタイプを与える仕組みを提案している**ERC6860**の拡張仕様を提案している**ERC7087**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

他の媒体でも情報発信しているのでぜひ他も見ていってください！

https://zenn.dev/heku

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4
