# 「ファイルを送信しません」は本当か。ブラウザだけで動くツールを自分で確かめる方法

- 正規URL: https://oka-project.com/blog/how-to-check-local-browser-processing
- 公開: 2026-09-25
- 著者: oka（https://oka-project.com/about）
- 要約: 「ファイルを送信しない」Webツールを利用者側から確かめる方法を解説。Chrome DevToolsのNetwork、オフライン動作、CSPを組み合わせ、確認できる事実と限界を整理します。
- 分類: guide ／ タグ: ブラウザ,セキュリティ,DevTools,CSP,ローカル処理

---
PDF変換、画像圧縮、Markdownプレビュー、文字起こし。

最近は「ブラウザだけで処理」「ファイルをサーバーへ送信しません」と書かれたオンラインツールをよく見かけます。

自分でもそうしたツールを作っているので、この言葉はかなり気になります。

ただ、利用者側から見ると一つ問題があります。

**「送信しません」と書いてあることと、本当に送信されていないことは別です。**

プライバシーポリシーを読んでも、実装までは見えません。逆に、ブラウザで動いているからといって必ずサーバーへ送っているわけでもありません。File APIやWebAssemblyを使えば、ファイルの読み込みから変換まで端末内で完結できます。

では、利用者自身が「このファイルはどこへ行っているのか」を確認する方法はあるのでしょうか。

調べながら自分のツールでも試してみると、Chrome DevToolsのNetworkを見るだけでもかなり分かります。ただし、それだけで「絶対に何も送信できない」と証明できるわけではありませんでした。

> [!NOTE: この記事のポイント]
> - 「送信しません」と書いてあることと、本当に送信されていないことは別
> - Networkパネルは実際の通信、CSPは許可されている通信、オフラインテストは補助証拠として重ねて判断する
> - どれか一つだけで「完全に安全」とは言えず、通信ゼロと安全も同じ意味ではない

## 先に結論：見るべきなのは「実際の通信」と「許可されている通信」の両方

オンラインツールを確認するときは、次の3つを分けて考えると整理しやすくなります。

**Networkパネル**は、その操作中に実際に何が通信されたかを見るためのものです。

**オフラインテスト**は、その処理がリモートサーバーなしでも成立するかを見る補助材料です。

**Content-Security-Policy（CSP）**は、ブラウザ側でどこへの通信が許可されているかを確認する材料です。

Networkは観測、CSPは制約、オフラインテストは補助証拠です。

どれか一つだけで「完全に安全」と言うのではなく、**実際の挙動と構造を重ねて判断する**のが現実的です。

参考：[Chrome DevTools: Network panel](https://developer.chrome.com/docs/devtools/network/overview)

## まずは「実際に何が通信されたか」を見る

一番分かりやすいのがChrome DevToolsのNetworkパネルです。

### ファイルを選ぶ前にNetworkを開く

Chromeでは、ページを開いた状態でDevToolsを起動し、Networkを選びます。

Windowsなら `F12` や `Ctrl + Shift + I`、Macなら `Command + Option + I` などで開けます。

重要なのは、**確認したい操作より先にNetworkパネルを開くこと**です。

NetworkはDevToolsを開いている間のリクエストを記録します。そこで、

1. ツールを開く
2. Networkを開く
3. ログをクリアする
4. ファイルを選ぶ
5. 変換・プレビューなどの処理を実行する
6. その瞬間に増えた通信を見る

という順で確認します。

ページを開いただけでも、JavaScript、フォント、アクセス解析などの通信が発生することがあります。

知りたいのは、**ファイルを選んだ瞬間や処理ボタンを押した瞬間に何が増えたか**です。

### Fetch/XHRだけではなく、Allで見る

ファイルアップロードなら `fetch()` や `XMLHttpRequest` が使われることは多いので、Fetch/XHRで絞るのは有効です。

ただし、それだけを見て「送信されていない」と判断するのは早すぎます。

通信経路にはWebSocket、Beacon、画像、フォーム送信などもあります。

例えばMarkdownに、

```md
![](https://example.com/pixel.png)
```

という外部画像が含まれていたとします。

ツールがMarkdown本文そのものをAPIへ送っていなくても、画像を表示するために `example.com` へHTTPリクエストが出る可能性があります。

つまり、**「本文をアップロードしていない」と「外部通信が一切ない」は別です。**

確認時はNetworkをAllにして、全体を見る方が安全です。

### 怪しい通信があれば、送信先・Payload・Initiatorを見る

リクエストを選択すると、ChromeではHeaders、Payload、Response、Initiator、Timingなどを確認できます。

特に見たいのは、

- どのドメインへ送っているか
- POSTなどで何を送っているか
- どの処理が通信を開始したか

です。

ファイルを選んだ瞬間に未知のAPIへPOSTが発生し、Payloadにファイルデータが含まれているなら、少なくとも「ブラウザ内だけで処理している」とは言えません。

一方、通信があること自体が直ちに危険という意味でもありません。

アクセス解析、エラーログ、Webフォント、WebAssemblyファイル、AIモデルの初回ダウンロードなど、ファイル本文とは関係のない通信もあります。

重要なのは、**通信の有無ではなく、何を・どこへ・いつ送っているか**です。

参考：[Chrome DevTools: Network features reference](https://developer.chrome.com/docs/devtools/network/reference)

## 次に「ネットがなくても処理できるか」を試す

Networkで実通信を確認した後、処理場所のヒントになるのがオフラインテストです。

### オフラインで最後まで動けば、ローカル処理の材料にはなる

Chrome DevToolsではネットワーク条件をOfflineへ切り替えられます。

一度ページと必要なリソースを読み込んだあと、Offlineにして同じファイル処理を試します。

例えばMarkdown変換や画像圧縮がオフラインでも最後まで動くなら、少なくとも**その処理を完了するために毎回リモートサーバーへ問い合わせる必要はない**可能性が高くなります。

ただし、これも証明ではありません。

Service Workerやキャッシュに必要なデータが残っているかもしれません。オンライン時だけ利用ログを送る実装もあり得ます。

逆に、初回だけWebAssemblyやAIモデルをダウンロードするツールは、初回オフラインでは起動できなくても、ユーザーファイル自体は外部へ送っていない場合があります。

**オフラインで動く＝オンライン時にも通信ゼロ**ではありません。

## もう一段見るなら「通信できる範囲」をCSPで確認する

Networkで「今は送っていなかった」ことを確認できても、実装上は送れる状態かもしれません。

そこで見る価値があるのがContent-Security-Policyです。

### `connect-src` はJavaScriptからの外向き通信を制限する

CSPは、Webページがどこからスクリプトや画像を読み込めるか、JavaScriptがどこへ接続できるかなどをブラウザ側で制限します。

例えば、

```http
Content-Security-Policy: connect-src 'none'
```

と設定されていれば、CSPの対象となるJavaScript通信は許可されません。

MDNによると `connect-src` は、`fetch()`、`XMLHttpRequest`、`WebSocket`、`EventSource`、`Navigator.sendBeacon()` などの接続先を制限します。

これは「通信しません」と説明文に書くこととは性格が違います。

JavaScriptが通信しようとしても、ポリシーに反すれば**ブラウザ自身が止める**からです。

参考：[MDN: CSP connect-src](https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/connect-src)

### 実際に作ってみると、`connect-src 'none'` だけでは足りなかった

ここは自分でMarkdown Viewerを作ったときに実際に引っかかった部分です。

最初はAPI通信を止めれば十分だと考えていました。

ところが監査すると、画像について `https:` からの読み込みを許可していました。

つまり `fetch()` などを止めても、Markdown内に外部画像URLがあれば、その画像を取得する通信経路が残ります。

そこで現在は `img-src` も制限し、外部画像をそのまま読み込まない構成に変更しています。

この経緯は、[ブラウザ完結ツールの「送信しない」を、約束ではなく構造にする](https://oka-project.com/blog/browser-only-tools-csp)にも残しています。

CSPでは、`connect-src` 以外にも `img-src`、`media-src`、`font-src`、`frame-src`、`form-action` など、通信や読み込みの種類ごとに制御があります。

そのため、**一つのディレクティブだけを見て「外向き通信は完全に不可能」と断定するべきではありません。**

### `default-src 'none'` から必要なものだけ許可する方が読みやすい

CSPを読むとき、個人的に分かりやすいのがdeny-by-default型です。

```http
Content-Security-Policy:
  default-src 'none';
  script-src 'self';
  style-src 'self';
  img-src 'self' data:;
```

のように、最初に原則禁止し、必要な種類だけ許可します。

この方が「書き忘れた種類が暗黙に自由になる」状態を減らしやすくなります。

ただし、CSPはWebセキュリティ全体を解決する仕組みではありません。

ブラウザ拡張や端末のマルウェアまで止めるものではなく、「このPCから一切情報が外へ出ない」ことを数学的に証明する機能でもありません。

**CSPは強い構造的な証拠にはなるが、万能な安全証明ではない**という位置づけが妥当です。

参考：[MDN: Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP)

参考：[MDN: CSP img-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/img-src)

## 調査するときに間違えやすいポイント

NetworkやCSPを見ればかなり判断材料は増えますが、誤判定しやすい点もあります。

### ブラウザ拡張の通信を、サイト自身の通信と勘違いする

広告ブロッカー、パスワードマネージャー、翻訳、AIアシスタントなどの拡張機能が、ページへスクリプトを挿入したり独自の通信をしたりすることがあります。

厳密に確認したい場合は、拡張機能を無効にした新しいブラウザプロファイルなどで試す方が切り分けやすくなります。

「知らないドメインがある＝そのツールが送った」と即断しないことも重要です。

### 「通信ゼロ」と「安全」を同じ意味にする

仮に外部通信が完全にゼロでも、そのツールが安全とは限りません。

ファイルを壊すバグがあるかもしれません。生成結果が意図と違うかもしれません。悪意ある入力でブラウザが重くなる可能性もあります。

ローカル処理で減らせるのは、**処理のために第三者サーバーへデータを渡すという一つのリスク**です。

セキュリティ全体の保証とは分ける必要があります。

### 自分で確認できても、組織の利用ルールは別

契約書、コード、未公開原稿、顧客データなどを扱う場合、Networkを確認して問題が見えなかったから自由に使ってよい、ということにはなりません。

会社や組織のセキュリティポリシー、利用許可、データ分類のルールがあれば、それが優先されます。

## 実際に確認するなら、この順番が分かりやすい

開発者でなくても、最低限次の順番なら確認できます。

1. DevToolsのNetworkを開いてログを消す
2. ファイルを読み込ませ、処理直後に増えた通信を見る
3. 外部ドメインへのPOSTやPayloadを確認する
4. Offlineにして同じ処理が成立するか試す
5. Response HeadersのCSPを確認し、`connect-src` や `img-src` などを見る

この5段階で完全な監査ができるわけではありません。

それでも、「プライバシーポリシーにそう書いてあるから信じる」状態からはかなり前へ進めます。

## よくある質問

### Networkパネルはいつ開けばいい？

確認したい操作より先に開きます。Networkは開いている間のリクエストを記録するので、ログをクリアしてからファイルを選び、その瞬間に増えた通信を見ます。

### Fetch/XHRに何もなければ送信されていないと言える？

早すぎます。通信経路にはWebSocket、Beacon、画像、フォーム送信などもあり、Markdown内の外部画像URLだけでもリクエストは出ます。NetworkはAllにして全体を見る方が安全です。

### オフラインで動けばローカル処理と断定できる？

証明にはなりません。Service Workerやキャッシュに必要なデータが残っていたり、オンライン時だけ利用ログを送る実装もあり得ます。オフラインで動くことと、オンライン時に通信ゼロであることは別です。

### CSPに `connect-src 'none'` があれば外部へは何も送れない？

`connect-src` は `fetch()` や `XMLHttpRequest` などJavaScriptからの接続先を制限しますが、`img-src` などが緩ければ外部画像の取得経路は残ります。一つのディレクティブだけで「外向き通信は完全に不可能」と断定すべきではありません。

### 知らないドメインへの通信があれば、そのツールが送っている？

即断はできません。広告ブロッカーやパスワードマネージャーなどブラウザ拡張が独自の通信をすることがあります。厳密に確認するなら、拡張機能を無効にした新しいプロファイルで試す方が切り分けやすくなります。


## 「送信しません」は、宣言より検証できる構造の方が強い

最初は、サービス提供者が「ファイルを送信しません」と言えば、利用者はそれを信じるしかないと思っていました。

実際にはそうでもありません。

Networkを見れば、その操作中に発生した通信を確認できます。

Offlineにすれば、処理にネットワークが必須か試せます。

CSPを見れば、JavaScriptや画像などにどんな通信先が許可されているか確認できます。

もちろん完全な証明ではありません。

それでも、**宣言しかない状態と、利用者自身が挙動と制約を確認できる状態ではかなり違います。**

自分でブラウザ完結ツールを作る側としても、ここは重要だと思っています。

「データを送りません」と書くだけではなく、Networkを見れば実際に送っていない。さらにCSPを見れば、外へ通信しようとしてもブラウザ側で制約がかかる。

Webツールのプライバシーは、説明文だけでなく**観測できる挙動と、検証できる構造**でも示せる。

今回調べてみて、一番大きかったのはそこでした。

### 参考資料

- [Chrome DevTools: Network panel](https://developer.chrome.com/docs/devtools/network/overview)
- [Chrome DevTools: Network features reference](https://developer.chrome.com/docs/devtools/network/reference)
- [MDN: Content-Security-Policy connect-src](https://developer.mozilla.org/ja/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/connect-src)
- [MDN: Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP)
- [MDN: Content-Security-Policy img-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy/img-src)