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

旧版・バックアップファイルの露出とは?ソースコードが見える仕組み・探し方・拒否設定・診断基準

旧版・バックアップファイルの露出とは、index.php.bakやconfig.php~などの残置ファイルがURLで取得できる状態です。ソースや認証情報が漏れる仕組み、棚卸し方法、Apache・nginx・IISの拒否設定、診断基準を解説します。

結論(旧版・バックアップファイルの露出)

旧版・バックアップファイルの露出とは、サーバー上の直接編集や退避作業で残った index.php.bak、login.php.old、config.php~ のようなファイルが、Web公開領域からURLで取得できる状態のことです。元のファイルと拡張子が異なるため、Webサーバーがプログラムとして実行せず、ソースコードのままテキストとして配信してしまうことがあります。データベースの接続情報やAPIキーが漏れる起点になるため、公開領域から削除し、サーバー設定でも拒否します。

この記事のポイント

  • 手作業のコピー、テキストエディターの自動バックアップ(末尾~)、更新作業時の退避などで旧版・バックアップが残ります。
  • 拡張子が変わるとPHPなどとして実行されず、ソースコードがそのまま配信されることがあります。
  • 元のファイル名はリンクから分かるため、.bakを付けるだけで推測でき、攻撃ツールはこの組み合わせを自動で試します。
  • 公開領域からの削除と運用ルールの見直しを基本に、FilesMatchやlocationでの拒否設定を保険として加えます。
  • セキュリティAIチェッカーは実在ファイル1件に.bak・.old・~を付けて確認し、実体のある200応答があれば△と判定します。
診断項目名旧版・バックアップファイルの露出
項目IDpublic.old-backup-variants
分類公開ファイル・情報露出
重大度・配点の重み重要(high) 重み 3
関連する標準・ガイドラインOWASP WSTG-CONF-04(古い・バックアップ・未参照ファイルの機密情報確認)、OWASP ASVS 5.0.0 V13.4.7(Web層は特定の拡張子のファイルだけを配信し、情報・設定・ソースコードの漏えいを防ぐ/L3)、CWE-530(Exposure of Backup File to an Unauthorized Control Sphere)、IPA「安全なウェブサイトの作り方」2.1-5)(公開を想定していないファイルをウェブ公開用ディレクトリに置かない)

旧版・バックアップファイルの露出とは

旧版・バックアップファイルの露出とは、index.php.bak、login.php.old、config.php~ のような旧版やバックアップのファイルが、Web公開領域に残ってURLで取得できる状態のことです。

サーバー上でファイルを直接編集すると、こうしたファイルが残ることがあります。手作業のコピー、テキストエディターの自動バックアップ(末尾 ~)、更新作業時の退避などが原因です。

これらは元のファイルと拡張子が異なるため、Webサーバーがプログラムとして実行せず、ソースコードのままテキストとして配信してしまうことがあります。ソースにはデータベースの接続情報、APIキー、内部の処理ロジックが含まれていることが多く、漏えいすると深刻な被害につながります。セキュリティAIチェッカーのこの項目は、サイト内の実在ファイルを起点に、代表的なバックアップ名でアクセスし、実体のある応答が返らないかを確認します。

なぜバックアップファイルからソースコードが見えてしまうのか

WSTGの説明

OWASP WSTG-CONF-04は、login.asp.old のように元ファイルと異なる名前・拡張子で残ったファイルは、実行されずにテキストやソースとして配信されやすく、サーバー側コード、認証情報、内部情報を露出させると説明しています。WSTGは確認すべき拡張子として .bak、.old、.orig、.save、.swp、~、.zip、.tar、.gz などを挙げています。

Apacheの複数拡張子の扱い

Apacheの mod_mime は複数の拡張子を持つファイルを扱う際、拡張子の順序を通常は問わず、ハンドラーと関連付けられた拡張子があればそのハンドラーで処理する場合があります。そのため index.php.bak が「PHPとして実行される」「テキストとして配信される」「ダウンロードされる」のいずれになるかは、AddHandler と FilesMatch+SetHandler のどちらで設定しているかなど、サーバー設定に依存します。どの場合でも、公開領域に残すべきではありません。

OWASP ASVS 5.0.0 V13.4.7(L3)は、Web層は特定の拡張子のファイルだけを配信し、情報・設定・ソースコードの漏えいを防ぐことを求めています。IPA「安全なウェブサイトの作り方」2.1-5)も、公開を想定していないファイルをウェブ公開用ディレクトリに置かないよう求めています。

バックアップファイルについてよくある誤解

  • 「リンクしていないので見つからない」:元のファイル名はリンクから分かるため、.bak を付けるだけで推測できます。攻撃ツールはこの組み合わせを自動で試します。
  • 「静的HTMLのバックアップなら無害」:内容が古い情報(旧連絡先、廃止した手続き、公開前の文案)を含むことがあり、住民の誤認や情報の先出しにつながります。
  • 「バックアップはサーバーの中にあるから安全」:Web公開ディレクトリの内側にある限り、URLで取得できます。

ディレクトリの一覧表示は「ディレクトリ一覧を公開していない」、.env などの管理ファイルは「代表的な管理ファイルが公開されていない」、旧版のログイン画面やテスト画面は「旧版・別ログイン・テスト画面の露出」、存在しないURLの扱いは「存在しないURLのステータス」で確認します。このページは「実在ファイルのバックアップ名」に絞って解説します。

旧版・バックアップファイルの露出の診断基準(セキュリティAIチェッカー)

取得対象

  1. トップページと追加ページ(トップページを含め最大3ページ)の最終URLのうち、最初に見つかった拡張子 .php・.asp・.aspx・.jsp・.html・.htm・.js・.css のURLを起点ファイルとします。
  2. 起点ファイルのパス(クエリを除く)に .bak・.old・~ を付け、対象オリジンに連結した3つのURLを作り、リダイレクトを追跡せずにGETします(タイムアウト5秒。180KBを超える応答は先頭180KBだけで判定)。

例:起点が /kurashi/index.html なら、/kurashi/index.html.bak、/kurashi/index.html.old、/kurashi/index.html~ を確認します。

「実体のあるバックアップ応答」の条件

次をすべて満たす応答を「実体のあるバックアップ応答」と数えます。

  • HTTPステータスが200
  • 本文の前後空白を除いた長さが80文字を超える
  • 本文のハッシュ(先頭100,000文字のSHA-256。nonce-… の値は正規化)が、取得済みのトップページ・追加ページのいずれとも一致しない(同じ内容を返すsoft-404を除外)
  • 本文の先頭2,000文字に、エラーページを示す次の語が含まれない(大文字小文字を区別しない):404、not found、ページが見つかりません、ページは見つかりません、ページが存在しません、ページは存在しません

判定条件

判定条件得点への影響
○ 問題なし(pass)3件とも上記に該当しない(404、403、リダイレクト、短い応答、エラーページ、取得済みページと同一内容、通信失敗)重み3を満点で加算
△ 要確認(warn)1件以上が実体のある200応答重み3×0.45を加算
× 要改善(fail)使用しない—
対象外(na)拡張子付きの起点ファイルが見つからない(全ページが / や拡張子なしのURL)分母・分子から除外

×ではなく△とするのは、存在しないURLにも通常ページを200で返す「soft-404」のサイトで、返る内容が取得済みページと完全には一致しない場合(時刻やトークンを本文に埋め込むページ、巡回していない別ページを返す場合など)に、バックアップがなくても条件を満たしてしまうためです。根拠にも「soft-404の可能性を含め確認が必要」と表示します。△が出た場合は、実際に返った内容がソースコードや旧版かどうかを人が確認してください。

判定の範囲と限界

  • 確認するのは起点ファイル1件×3種類の名前だけです。.orig、.swp、.zip、_old.html、コピー〜 のような別の命名、別ディレクトリのバックアップは確認しません。
  • エラーページの判定は文言によるため、独自の文言を使うsoft-404は△になり得ます。存在しないURLの扱いは「存在しないURLのステータス」で別途確認できます。

自治体サイトでの判定例

状況判定
/kurashi/index.html.bak が404○
/cgi-bin/form.php.old がPHPソースをテキストで返す△(内容確認で漏えいと確定。重大な事案として扱う)
存在しないURLにもトップページと同一の内容を200で返すCMS○(取得済みページと本文ハッシュが一致するため除外)
存在しないURLに、アクセスのたびに本文が変わるページや独自文言の案内ページを200で返すCMS△(soft-404による誤検知の可能性。response.soft-404 の結果とあわせて確認)
トップページだけで拡張子付きURLがない対象外

バックアップファイルが露出するとどんなリスクがあるか

  • 認証情報の漏えい:PHPやASPのソースに書かれたデータベースのユーザー名・パスワード、APIキー、メール送信用アカウントが読まれ、データベースへの不正接続や外部サービスの悪用につながります。
  • 脆弱性の発見:入力チェックやSQL組み立ての処理が読めるため、SQLインジェクションやアクセス制御の欠落を効率よく探されます。
  • 旧情報の流通:旧版のページが検索エンジンに登録されると、廃止された手続きや古い連絡先が住民に参照され続けます。
  • 公開前情報の先出し:更新前の作業ファイルに、公開前の発表内容や入札関連情報が含まれていた場合、情報管理上の事故になります。

バックアップファイルの削除と拒否設定の方法(Apache・nginx・IIS・Next.js)

1. 公開領域から削除し、作業手順を改める

# 公開ディレクトリ内のバックアップ類を棚卸し(サーバー上)
find /var/www/html -type f \( -name "*.bak" -o -name "*.old" -o -name "*~" \
  -o -name "*.orig" -o -name "*.save" -o -name "*.swp" -o -name "*.tmp" \) -ls

見つかったファイルは内容を確認のうえ、Web公開領域の外へ移すか削除します。今後はサーバー上で直接編集せず、バージョン管理(Git等)とデプロイ手順で更新し、バックアップは公開領域外に置くことを運用ルールにします。

2. サーバー設定で拒否する(設定喪失時の保険)

# Apache(.htaccess または httpd.conf)
<FilesMatch "(?i)(\.(bak|old|orig|save|swp|tmp|sql|zip|tar|gz)|~)$">
  Require all denied
</FilesMatch>
# nginx
location ~* (\.(bak|old|orig|save|swp|tmp|sql)|~)$ {
    return 404;
}
<!-- IIS web.config:拡張子を拒否 -->
<system.webServer>
  <security>
    <requestFiltering>
      <fileExtensions allowUnlisted="true">
        <add fileExtension=".bak" allowed="false" />
        <add fileExtension=".old" allowed="false" />
        <add fileExtension=".orig" allowed="false" />
      </fileExtensions>
    </requestFiltering>
  </security>
</system.webServer>

ASVS V13.4.7が求めるように、配信してよい拡張子を許可リストで限定する方式はより確実ですが、既存サイトでは影響範囲が大きいため、段階的に導入します。

3. PHPの実行設定を見直す

AddHandler application/x-httpd-php .php のような設定は、.php を含む複数拡張子のファイルも実行対象にする場合があります。最後の拡張子だけで判定するよう FilesMatch を使います。

<FilesMatch "\.php$">
  SetHandler application/x-httpd-php
</FilesMatch>

ハンドラー名は環境(PHP-FPM、レンタルサーバー)により異なるため、既存設定の書式に合わせてください。この変更後は index.php.bak のようなファイルがPHPとして実行されず、ソースコードのまま配信される可能性が高くなります。必ず1.の削除と2.の拒否設定を先に済ませてから切り替えてください。

4. Next.js(Vercel)・CMS

  • Next.jsでは public/ 配下のファイルがそのまま配信されます。public/ に作業ファイルを置かず、ビルド成果物だけをデプロイします。
  • CMSでは、テーマやプラグインのファイルをサーバー上で直接編集した際のバックアップが残りやすいため、更新後の棚卸しを手順に含めます。

修正後の確認方法

base="https://www.example.lg.jp/kurashi/index.html"
for s in .bak .old "~"; do
  printf "%s%s " "$base" "$s"
  curl -s -o /dev/null -w "%{http_code}\n" "$base$s"
done

200が返った場合は本文を表示し、ソースコードや旧版かを確認します。漏えいが確定した場合は、ファイルの削除に加えて、含まれていた認証情報・APIキーを直ちに変更してください。修正後はセキュリティAIチェッカーで再診断し、この項目が○になることを確認します。

サイトを壊さないための注意点

  • FilesMatch の対象に .zip や .gz を入れると、正規に配布している圧縮ファイルや、事前圧縮した静的ファイル(.gz)も拒否されます。配布ファイルがある場合は対象から外すか、ディレクトリを限定してください。
  • .htaccess で Require を使うには AllowOverride AuthConfig 相当の許可が必要で、許可がないと500エラーになります。追加後に主要ページの表示を確認します。
  • 削除前に、そのファイルが本当に未使用か(インクルードされていないか)をアクセスログと grep で確認します。

よくある質問(FAQ)

なぜ旧版・バックアップファイルからソースコードが見えてしまうのですか?

login.php.old のように元ファイルと異なる名前・拡張子で残ったファイルは、Webサーバーがプログラムとして実行せず、テキストやソースとして配信しやすいためです。ApacheではAddHandlerとFilesMatch+SetHandlerのどちらで設定しているかなど、サーバー設定によって挙動が変わります。

リンクしていなければバックアップファイルは見つかりませんか?

見つかります。元のファイル名はリンクから分かるため、.bak を付けるだけで推測でき、攻撃ツールはこの組み合わせを自動で試します。

静的HTMLのバックアップなら無害ですか?

無害とは限りません。旧連絡先、廃止した手続き、公開前の文案などの古い情報を含むことがあり、住民の誤認や情報の先出しにつながります。

公開ディレクトリのバックアップファイルはどうやって探しますか?

サーバー上で find コマンドを使い、*.bak、*.old、*~、*.orig、*.save、*.swp、*.tmp などを棚卸しします。見つかったファイルは内容を確認のうえ、公開領域の外へ移すか削除します。

旧版・バックアップファイルの露出が診断で△になったら、何をすればよいですか?

実際に返った内容がソースコードや旧版かを人が確認します。存在しないURLにも通常ページを返すsoft-404による誤検知の場合もあります。漏えいが確定した場合は、ファイルの削除に加えて、含まれていた認証情報・APIキーを直ちに変更してください。

旧版・バックアップファイルの露出は、セキュリティAIチェッカーでどう判定されますか?

取得ページのうち最初に見つかった拡張子付きURL(.php、.html、.js等)に .bak・.old・~ を付けた3つのURLを確認し、実体のある200応答が1件でもあれば「△ 要確認」(重み3の45%)、なければ「○ 問題なし」、拡張子付きの起点ファイルがなければ「対象外」です。soft-404の誤検知があり得るため×にはしていません。

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

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

参考資料