• 診断項目 No.72/127
  • 公開ファイル・情報露出
  • 重大度 中(medium)

sitemapに非公開ページを含めていないか?ステージング・テスト・管理URLの混入対策と診断基準

sitemapに非公開ページを含めていないかの確認方法を解説。sitemap.xmlは誰でも読めるため、テスト・ステージング・管理画面のURLが載ると入口一覧を渡すことになります。混入の原因、生成設定の見直し、点検コマンドと診断基準を紹介します。

結論(sitemapに非公開ページを含めていない)

sitemapに非公開ページを含めていないとは、検索エンジン向けのXMLサイトマップ(/sitemap.xml)の<loc>に、テストページ、ステージング環境、管理画面、公開前のページのURLが載っていない状態です。サイトマップは誰でも取得でき、OWASP WSTGでも偵察対象に挙げられているため、非公開のつもりのURLが載ると攻撃者や第三者に「入口一覧」を渡すことになります。

この記事のポイント

  • サイトマップは誰でも取得でき、サイト構造を効率よく把握する偵察対象になります。
  • 混入の典型は、ステージングURLの残存、公開状態のテストページ、CMSのプレビューURL、移行時の一括生成です。
  • サイトマップから外すだけでは保護にならず、削除・認証・IP制限を先に行います。
  • noindexにしても、サイトマップ自体は誰でも読めるためURLの存在は露出します。
  • セキュリティAIチェッカーは、<loc>のURLにstaging・stg・test・dev・admin・privateが独立した語として含まれると△と判定します。
診断項目名sitemapに非公開ページを含めていない
項目IDpublic.sitemap
分類公開ファイル・情報露出
重大度・配点の重み中(medium) 重み 2
関連する標準・ガイドラインSitemaps XML format(sitemaps.org のプロトコル 0.9)、OWASP WSTG-INFO-03(Webサーバーのメタファイルから情報漏えいを確認。サイトマップを確認対象に含む)、OWASP ASVS 5.0.0 V13.4.5(内部向けのドキュメントや監視エンドポイントを意図なく公開しない)、CWE-200(権限のない者への機密情報の露出)

sitemapに非公開ページを含めていないとは

sitemapに非公開ページを含めていないとは、XMLサイトマップ(/sitemap.xml)に掲載したURLに、テスト用ページ、ステージング環境のURL、管理画面、公開前・非公開のページが含まれていない状態のことです。

XMLサイトマップは、検索エンジンにサイト内のページ一覧を伝えるためのファイルです。CMSの多くは公開ページから自動生成しますが、設定や運用の誤りにより、非公開のはずのURLが含まれてしまうことがあります。

サイトマップは誰でも取得でき、OWASP WSTGでもサイト構造を効率よく把握するための偵察対象として挙げられています。非公開のつもりのURLが載っていれば、そのまま攻撃者や第三者に「入口一覧」を渡すことになります。

この項目は、/sitemap.xml に掲載されたURL(<loc> 要素)に、テスト・開発・管理・非公開を示す語が含まれていないかを確認します。robots.txtに管理画面などのパスを書いてしまう問題は「robots.txtに機密パスを列挙していない」で別に確認します。

サイトマップの仕様と非公開ページが紛れ込む原因

サイトマップの仕様の要点(Sitemaps XML format 0.9)

  • ルート要素 <urlset> の中に <url> を並べ、それぞれに必須の <loc>(完全なURL)を書きます。<lastmod> 等は任意です。
  • 1ファイルあたり50,000URL・非圧縮50MBまで。超える場合はサイトマップインデックス(<sitemapindex>)で複数ファイルに分けます。gzip圧縮も使えます。
  • サイトマップを置いたディレクトリより上位のURLや、別のホスト・プロトコルのURLは含められません。
  • robots.txtに Sitemap: https://... と書いて場所を知らせることができます。
  • Googleは「検索結果に表示させたいURL」を、重複のない正規URLで掲載するよう案内しています。
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://www.city.example.lg.jp/kurashi/gomi/index.html</loc>
    <lastmod>2026-09-30</lastmod>
  </url>
</urlset>

非公開ページが紛れ込む典型例

原因例
ステージング環境のURLが残るhttps://stg.city.example.lg.jp/...、https://dev-cms.example.jp/...
テストページを公開状態で作成/test/index.html、/kosodate/test-page.html
CMSの管理画面・プレビューURL/admin/preview?id=...
公開期限前・限定公開ページ/private/...、URLを知る人だけに見せるつもりのページ
移行時の一括生成旧サーバーの全ファイルを機械的に列挙

サイトマップについてよくある誤解

  • 「サイトマップに載せなければ見つからない」:サイトマップから外しても、リンクやURL推測で見つかります。非公開にすべきページは認証・削除で保護します。
  • 「noindexにすればサイトマップに載っていても問題ない」:検索結果からは外れても、サイトマップ自体は誰でも読めるため、URLの存在は露出します。

sitemapに非公開ページを含めていないの診断基準(セキュリティAIチェッカー)

取得方法

  • 診断の最終URLのオリジンに対し /sitemap.xml をGETします(リダイレクトは追跡しない、タイムアウト4秒、最大100,000バイト。上限を超える大きなサイトマップは先頭部分で打ち切り、その範囲に含まれる完全な <loc> を評価)。
  • 本文から <loc>…</loc> の値(URL)を抽出します。CDATA形式(<loc><![CDATA[…]]></loc>)で書かれたURLも読み取ります。

判定条件

各URLから https:// 等のスキームを除いた文字列(ホスト名+パス)について、次の語が区切り文字で区切られた独立した語(直前が /、.、-、_ または文字列の先頭、直後が /、.、-、_、?、# または文字列の末尾)として現れるかを確認します(大小文字を区別しない)。

staging / stg / test / dev / admin / private

latest(testを含む)、device(devを含む)、administration(adminを含む)のような、語の一部として含まれるだけのものは一致させません。

判定条件得点への影響
○ 問題なし(pass)該当URLがない重み2 × 1.00
△ 要確認(warn)上記の語を含むURLが1件以上ある(根拠欄に件数と例を表示)重み2 × 0.45
対象外(na)sitemap.xmlがない(200以外)、または200でも <loc> が1件もない(HTMLのエラーページ等)計算から除外

× 要改善(fail)はありません。語が含まれていても正当な公開ページである場合(例: 試験・検定の案内ページを /test/ に置いている)があるため、「要確認」の △ としています。

判定の限界

  • /sitemap.xml 1ファイルだけを確認します。サイトマップインデックスの場合、その中の子サイトマップのURL(<loc>)は評価しますが、子サイトマップの中身までは取得しません。
  • robots.txtの Sitemap: で別の場所を指定している場合や、sitemap.xml.gz のみの場合は確認できません。
  • 日本語ローマ字(kanri、shiken 等)や製品固有のパスは対象外です。

自治体サイトでの判定例

サイトマップの <loc>判定
https://stg.city.example.lg.jp/top.html(ステージング環境)△
https://www.city.example.lg.jp/kosodate/test/△(目視確認。正当な公開ページなら問題なし)
https://www.city.example.lg.jp/news/latest.html○(語の一部のため一致しない)
sitemap.xmlが404対象外

sitemapに非公開ページが含まれているとどんなリスクがあるか

  • 未公開情報の漏えい:公開日前の報道発表、入札情報、選挙関連資料などが公開状態で作成されサイトマップに載ると、予定より早く閲覧されるおそれがあります。
  • ステージング環境への到達:テスト環境は本番より保護が弱いことが多く、既知の脆弱性や初期パスワード、テスト用の個人情報が残っている場合があります。
  • 管理画面の露出:管理画面のURLが分かると、パスワード総当たりや脆弱性探索の対象になります。
  • 信頼性の低下:検索結果にテストページが表示されると、住民に誤った情報が伝わるおそれがあります。

サイトマップから非公開ページを除く方法(CMS・Next.js・Apache・nginx)

1. 該当URLの扱いを決める

  • 不要なページは削除し、サイトマップからも外す。
  • テスト環境は本番から到達できない場所に移すか、認証・IP制限をかける。
  • 公開前ページは、CMSの「非公開」「公開予約」機能を使い、公開状態で作らない。

2. サイトマップの生成設定を見直す

  • CMSのサイトマップ機能で、除外するディレクトリ・ページ種別を設定する(WordPressなら標準のサイトマップやSEOプラグインの除外設定)。
  • 自前で生成している場合は、公開フラグが立ったページだけを出力する。

Next.js(App Router)の例:

// app/sitemap.ts
import type { MetadataRoute } from "next";
import { getPublishedPages } from "@/lib/pages";

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const pages = await getPublishedPages(); // 公開済みのみ
  return pages
    .filter((p) => !/^\/(?:test|admin|private)(?:\/|$)/.test(p.path))
    .map((p) => ({ url: `https://www.city.example.lg.jp${p.path}`, lastModified: p.updatedAt }));
}

3. ステージング環境を保護する

Apache(ステージング側の .htaccess):

AuthType Basic
AuthName "Staging"
AuthUserFile /etc/apache2/.htpasswd-staging
Require valid-user
Header set X-Robots-Tag "noindex, nofollow"

nginx:

server {
    server_name stg.city.example.lg.jp;
    auth_basic "Staging";
    auth_basic_user_file /etc/nginx/.htpasswd-staging;
    add_header X-Robots-Tag "noindex, nofollow" always;
}

IIS:ステージングサイトで匿名認証を無効にし、Windows認証またはIP制限を設定します。Vercelでは、プレビューデプロイに Deployment Protection(パスワードやVercel認証)を設定できます。

4. 大規模サイト・サイトマップインデックスの点検

自治体の公式サイトはページ数が多く、サイトマップインデックスで複数ファイルに分かれていることがよくあります。セキュリティAIチェッカーは先頭のファイルしか見ないため、定期点検では子サイトマップも含めて全URLを確認します。

# インデックスから子サイトマップを列挙し、全<loc>を1ファイルにまとめる
curl -s https://www.city.example.lg.jp/sitemap.xml | grep -oE '<loc>[^<]+</loc>' | sed -E 's#</?loc>##g' > index.txt
while read -r u; do curl -s "$u" | grep -oE '<loc>[^<]+</loc>'; done < index.txt > all-locs.txt
wc -l all-locs.txt

点検の観点は、ホスト名(本番以外のホスト名が混じっていないか)、パス(テスト・管理用の語)、公開日(公開予定前のページが載っていないか)の3点です。

5. 確認方法

curl -s https://www.city.example.lg.jp/sitemap.xml \
  | grep -oE '<loc>[^<]+</loc>' \
  | grep -iE '([/._-]|//)(staging|stg|test|dev|admin|private)([/._?#-]|</loc>)'

一致したURLを1件ずつ開き、公開してよいページかを確認します。<loc> をCDATA形式で出力しているサイトマップでは、grep -oE の部分を <loc>.*</loc> に置き換えて確認します。対処後はセキュリティAIチェッカーで再診断し、根拠欄に該当URLが残っていないことを確かめます。

検索流入を失わないための注意点(ガードレール)

  • サイトマップからURLを外すだけでは保護になりません。削除・認証を先に行います。
  • 生成ルールを変更したら、主要な公開ページが引き続き掲載されていることを確認します(誤って全ページを除外すると検索流入が減ります)。
  • テスト環境に認証をかける際は、本番と同じ証明書・ドメイン設定を流用して本番を止めないよう、対象ホスト名を確認してから適用します。

よくある質問(FAQ)

サイトマップに載せなければ非公開ページは見つかりませんか?

見つかります。サイトマップから外しても、リンクやURL推測で見つかります。非公開にすべきページは認証や削除で保護してください。

noindexにしたページがサイトマップに載っていても問題ありませんか?

検索結果からは外れても、サイトマップ自体は誰でも読めるため、URLの存在は露出します。非公開のページはサイトマップに載せず、認証・削除で保護してください。

試験・検定の案内ページを/test/に置いていますが、問題ですか?

正当な公開ページであれば問題ありません。語が含まれていても正当な公開ページである場合があるため、セキュリティAIチェッカーは×ではなく△(要確認)とし、根拠欄に件数と例を表示します。一致したURLを開いて公開してよいページか確認してください。

latestやdeviceのようなURLも△になりますか?

なりません。区切り文字で区切られた独立した語(直前が / . - _ または先頭、直後が / . - _ ? # または末尾)だけを対象にするため、latest(testを含む)、device(devを含む)、administration(adminを含む)のように語の一部として含まれるだけのものは一致しません。

サイトマップインデックスを使っている場合、子サイトマップも診断されますか?

/sitemap.xml 1ファイルだけを確認し、インデックス内の子サイトマップのURL(loc)は評価しますが、子サイトマップの中身までは取得しません。定期点検では子サイトマップも含めて全URLを確認してください。

ステージング環境のURLがサイトマップに載っていました。どう対処すればよいですか?

テスト環境を本番から到達できない場所に移すか、Basic認証やIP制限をかけ、サイトマップの生成設定から除外します。テスト環境に認証をかける際は、本番と同じ証明書・ドメイン設定を流用して本番を止めないよう、対象ホスト名を確認してから適用してください。

セキュリティAIチェッカーを利用する

この項目を含む127項目を、URLを入れるだけで無料診断します。

参考資料