結論(Web App Manifestの公開)
Web App Manifestの公開とは、サイトをアプリとしてホーム画面に追加するときの設定を書いたJSONファイルを、link rel="manifest" で参照して公開することです。ファイルには名前・アイコン・起動URL(start_url)・範囲(scope)などを書きます。誰でも取得できるため、検証環境のURLや利用者を識別する値を含めないよう内容を確認する必要があります。セキュリティAIチェッカーは参照があれば△(要確認)、無ければ対象外とします。
この記事のポイント
- マニフェストは誰でも取得できる公開ファイルで、推奨拡張子は.webmanifest、MIMEタイプはapplication/manifest+jsonです。
- start_urlやiconsに検証環境や委託事業者の作業用URLが残っていると、内部構成の手がかりを与えます。
- W3C仕様は、start_urlに利用者を一意に識別する情報を含めることを悪い慣行としています。
- start_urlが文書と別オリジンなら無視され、scopeがstart_urlを含まなければ既定値が使われます。
- nginxでserver直下にtypesを書くとmime.typesの対応表が置き換わるため、location内で個別に指定します。
- 診断は参照の有無だけを見て、あれば△(重み1×0.45=0.45点)、無ければ対象外です。
| 診断項目名 | Web App Manifestの公開 |
|---|---|
| 項目ID | html.manifest |
| 分類 | HTML・JavaScript・外部資産 |
| 重大度・配点の重み | 低(low) 重み 1 |
| 関連する標準・ガイドライン | W3C Web Application Manifest(Working Draft)/OWASP WSTG-INFO-05「Review Web Page Content for Information Leakage」(公開ファイルからの情報露出の確認)/CWE-200(権限のない者への機密情報の露出)※開発用URL等が記載されていた場合 |
Web App Manifestの公開とは
**Web App Manifest(Webアプリマニフェスト)**は、サイトを「アプリ」としてスマートフォンのホーム画面などにインストールするときの名前、アイコン、起動URL、表示モード、テーマ色などを記述したJSONファイルです。HTMLの <head> に次のように書くことでブラウザに参照されます。
<link rel="manifest" href="/manifest.webmanifest">
Progressive Web App(PWA)化したサイトや、CMSのテーマが標準でマニフェストを出力するサイトで見られます。
Web App Manifestの公開で問題になるのは、マニフェストが誰でも取得できる公開ファイルだという点です。そこに次のような情報が含まれていると、意図しない情報公開になります。
- 検証環境のURL
- 内部向けのホスト名
- 開発者向けのメモ
- 利用者を識別するパラメータ
また、start_url や scope の設定が不適切だと、ホーム画面から起動したときに想定外の画面が開きます。セキュリティAIチェッカーのこの項目は、トップページがマニフェストを参照しているかを確認し、参照がある場合に内容の確認を促す△(要確認)を出します。
Web App Manifestの仕組みと主なメンバー
拡張子とMIMEタイプ
MDNによると、推奨される拡張子は .webmanifest、MIMEタイプは application/manifest+json で、.json(application/json)でも一般に動作します。仕様はW3CのWeb Application Manifest(Working Draft)です。
主なメンバーと確認のポイント
| メンバー | 内容 | 確認のポイント |
|---|---|---|
name/short_name | アプリ名 | 正式な自治体名・サイト名か |
start_url | 起動時に開くURL | 本番URLか。利用者を識別する値を含めていないか |
scope | アプリとして扱うURL範囲 | 必要な範囲に限定されているか |
id | アプリの識別子 | 起動URLと整合しているか |
display | 表示モード(standalone 等) | アドレスバー非表示で困る機能がないか |
icons | アイコン画像 | 公式ロゴか、HTTPSで取得できるか |
theme_color/background_color | 色 | 表示上の確認のみ |
W3C仕様が定める処理の規則
W3Cの仕様の処理手順では、次のように扱われます。
start_urlが文書のURLと同一オリジンでない場合は指定が無視され、文書のURLが起動URLになります。idがstart_urlと同一オリジンでない場合も指定が無視されます。scopeは、start_urlがその範囲内に収まっていない場合に指定が無視され、既定値(start_urlを基準にした.、つまり起動URLのあるディレクトリ)が使われます。- 仕様は、
start_urlに利用者を一意に識別する情報を含めることを、サイトデータを消去しても残る指紋になるため悪い慣行だとしています。
取得時の資格情報(Cookie)
マニフェストはCORSモードで取得され、<link> の crossorigin 属性で資格情報(Cookie)の扱いが決まります。MDNは、資格情報が必要な場合は同一オリジンでも crossorigin="use-credentials" を付ける必要があると説明しています。逆に言えば、通常のマニフェストはCookieなしで取得されるため、ログインしないと取得できない情報を入れる設計にはしません。
Web App Manifestについてよくある誤解
- 「マニフェストがあるのは危険」:マニフェスト自体は表示情報を記述するだけで、それ自体がスクリプトを実行するわけではありません。本項目の△は「公開内容を確認すべき」という意味です。
- 「マニフェストがあればPWAとしてオフライン動作する」:オフライン動作にはService Workerが必要です。Service Workerの登録は「Service Workerの利用を把握」の項目で確認します。
- 「CMSが自動生成するので確認不要」:テーマの初期値のまま、名前が「My App」や開発会社のデモURLになっている例があります。
Web App Manifestの公開の診断基準(セキュリティAIチェッカー)
取得対象
- 診断URLへのGETで取得したトップページ(最終URL)のHTML本文(最大2MB)。
- マニフェストファイル自体は取得・解析しません(内容の確認は運用者が行います)。
検出方法
正規表現 <link\b[^<>]*\brel\s*=\s*["']?manifest\b(大文字小文字を区別しない)で、rel="manifest" を持つ <link> 要素を検索します。属性の順序(href が先でも可)、= 前後の空白、引用符なしの rel=manifest(HTMLを圧縮するツールが出力する形式)にも対応します。
判定条件
| 判定 | 条件 | 得点への影響 |
|---|---|---|
| ○ 問題なし(pass) | 使用しない(内容の妥当性はHTMLだけでは確認できないため) | — |
| △ 要確認(warn) | マニフェストへの参照がある(根拠欄「manifest参照があります。」) | 1×0.45=0.45点(要確認) |
| × 要改善(fail) | 使用しない | — |
| 対象外(na) | 参照が見当たらない | 得点計算から除外 |
この項目は「公開している設定ファイルを運用者が把握し、内容を確認すること」を促す情報収集型の判定です。重み1のため総合スコアへの影響は小さく、利用していないサイトとの差は確認作業が残っていることを示すに過ぎません。
自治体サイトでの判定例
| トップページの状態 | 判定 |
|---|---|
CMSのテーマが <link rel="manifest" href="/site.webmanifest"> を出力している | △(根拠をもとにマニフェストを開き、start_url や名前が適切か確認) |
| PWA化した防災ポータルのトップページ | △ |
| マニフェストを使っていない | 対象外 |
診断の限界
relに複数の値を並べ、manifestが先頭にない記述は検出できません。relより前の属性値に<や>を含む<link>も検出できません。- HTML内のコメントや
<template>内に残った参照も検出します(実際には読み込まれない場合があります)。 - 外部JavaScriptで動的に
<link>を追加する方式は検出できません。
Web App Manifestの内容に問題があるとどんなリスクがあるか
- 情報露出:
start_urlやiconsに検証環境(例:https://stg-cms.example.local/)や委託事業者の作業用URLが残っていると、攻撃者に内部構成の手がかりを与えます(CWE-200「権限のない者への機密情報の露出」に当たります)。OWASP WSTG-INFO-05「Review Web Page Content for Information Leakage」でも、公開ファイルからの情報露出の確認が求められています。 - 追跡の懸念:
start_urlに利用者ごとのIDやトークンを含めると、インストールした利用者を識別できてしまい、仕様が指摘するプライバシー上の問題になります。 - なりすましに見える表示:
nameやiconsがCMSの初期値のままだと、ホーム画面に正式な自治体名ではないアプリ名が表示され、利用者が公式かどうか判断できません。 - 想定外の起動先:
scopeが広すぎると、同じオリジンで運用する別システム(申請フォーム等)がアドレスバーのないアプリ表示で開き、URLを確認できない状態で個人情報を入力させることになります。
これらはいずれも単独で重大な侵害につながるものではありませんが、公開ファイルの管理不足として指摘される典型例です。
Web App Manifestの確認方法と設定例(Apache・nginx・IIS・Next.js)
1. 内容の確認
# トップページから参照先を確認
curl -s https://www.city.example.lg.jp/ | grep -oiE '<link[^>]*rel=["'"'"']?manifest[^>]*>'
# マニフェスト本体とContent-Typeを確認
curl -sI https://www.city.example.lg.jp/site.webmanifest
curl -s https://www.city.example.lg.jp/site.webmanifest
2. 適切なマニフェストの例
{
"name": "○○市公式ホームページ",
"short_name": "○○市",
"id": "/",
"start_url": "/",
"scope": "/",
"display": "browser",
"lang": "ja",
"icons": [
{ "src": "/img/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/img/icon-512.png", "sizes": "512x512", "type": "image/png" }
],
"theme_color": "#004098",
"background_color": "#ffffff"
}
start_urlに計測用パラメータを付ける場合も、利用者を識別する値は入れません。- アドレスバーで公式URLを確認できるよう、特段の理由がなければ
display: "browser"または"minimal-ui"も選択肢になります。
3. MIMEタイプと配信設定
Apache(.htaccess)
# Apache (.htaccess)
AddType application/manifest+json .webmanifest
<Files "site.webmanifest">
<IfModule mod_headers.c>
Header set X-Content-Type-Options "nosniff"
</IfModule>
</Files>
nginx
# nginx:標準のmime.typesには.webmanifestが無いため、location内で個別に指定する
location ~ \.webmanifest$ {
types { }
default_type application/manifest+json;
}
# server直下に types { application/manifest+json webmanifest; } だけを書くと、
# 継承していたmime.typesの対応表が置き換わり、CSSや画像のContent-Typeが壊れるので避ける
IIS(web.config)
<!-- IIS web.config -->
<system.webServer>
<staticContent>
<remove fileExtension=".webmanifest" />
<mimeMap fileExtension=".webmanifest" mimeType="application/manifest+json" />
</staticContent>
</system.webServer>
Next.js(App Router)
Next.js(App Router)では app/manifest.ts(または manifest.json)を置くとマニフェストが生成・配信され、参照タグも自動で出力されます。内容は同様に確認します。
4. ブラウザでの確認
Chrome/Edgeの開発者ツールでは「Application」→「Manifest」を開くと、ブラウザが解釈したマニフェストの内容(名前、start_url、scope、id、アイコン)と、解析時の警告やエラーが一覧表示されます。curl で取得した生のJSONと合わせて、次の観点で確認します。
| 観点 | 確認内容 |
|---|---|
| URL | start_url、scope、id、アイコンのURLに、本番以外のホスト名や http:// が含まれていない |
| 名称 | name/short_name が自治体の正式名称で、テーマの初期値や事業者名のままになっていない |
| 識別子 | start_url のクエリに利用者IDやセッションを示す値がない |
| 範囲 | scope が、同一オリジンで動く申請システムや職員向け画面まで含んでいない |
| 配信 | HTTPSで200応答し、Content-Typeが application/manifest+json または application/json |
5. 運用ルール
マニフェストはCMSのテーマ更新やリニューアル時に、委託事業者が気付かないうちに追加・変更されることがあります。公開ファイルの一覧(robots.txt、sitemap.xml、security.txt など)と同じ台帳でマニフェストも管理し、リニューアルの受入検査項目に「マニフェストの有無と内容確認」を加えておくと、確認漏れを防げます。
6. 不要な場合は削除
PWAとして使う予定がないのにCMSテーマが出力している場合は、テンプレートから <link rel="manifest"> を削除し、マニフェストファイルも撤去します。
サイトを壊さないための注意点
- 既にホーム画面へ追加している利用者がいる場合、
idやstart_urlを変更すると別アプリとして扱われることがあります。変更は告知のうえで行います。 - マニフェストの削除はService Workerの解除とは別です。Service Workerを使っている場合は、別途解除手順を検討します。
- アイコン画像のパスを変更した場合は、アイコンが表示されなくならないよう、旧パスからのリダイレクトも検討します。
よくある質問(FAQ)
Web App Manifestを公開していると危険ですか?
マニフェスト自体は表示情報を記述するだけで、それ自体がスクリプトを実行するわけではありません。この項目の△は「公開している内容を確認すべき」という意味です。
マニフェストのMIMEタイプは何にすればよいですか?
MDNによると、推奨される拡張子は.webmanifest、MIMEタイプはapplication/manifest+jsonです。.json(application/json)でも一般に動作します。
マニフェストがあればPWAとしてオフラインで動きますか?
動きません。オフライン動作にはService Workerが必要です。Service Workerの登録状況は別の診断項目で確認します。
マニフェストにログインが必要な情報を入れてもよいですか?
入れないでください。マニフェストはCORSモードで取得され、資格情報が必要な場合は同一オリジンでもcrossorigin="use-credentials"が必要です。通常はCookieなしで取得されるため、誰でも見られる前提で設計します。
start_urlやidを変更しても問題ありませんか?
既にホーム画面へ追加している利用者がいる場合、idやstart_urlを変更すると別アプリとして扱われることがあります。変更は告知のうえで行います。
CMSが自動で出力するマニフェストも確認が必要ですか?
必要です。テーマの初期値のまま、名前が「My App」や開発会社のデモURLになっている例があります。PWAとして使わないなら、テンプレートから参照タグとファイルを撤去します。
この項目を含む127項目を、URLを入れるだけで無料診断します。