WordPressのwp-content/languagesを確認したところ、
見覚えのないPHPファイルがあり「感染ではないか」と困っていませんか?
翻訳用フォルダにPHPがあると不自然に見えますが、
拡張子だけで削除すると、正規の翻訳ファイルまで失うおそれがあります。
WordPress 6.5以降は、翻訳を高速に読み込む正規形式として.l10n.phpを利用します。
一方、攻撃者が目立ちにくいlanguagesフォルダへ任意のPHPを置く可能性もあるため、名前・内容・生成元・実行記録を分けて確認する必要があります。
WordPressの復旧を多数手がけてきたよこやま良平です。わたしの現場経験をもとに、正規の翻訳PHPを壊さず、不審なファイルだけを安全に確認・隔離する順番を解説します。
- languagesフォルダにある正規ファイルの種類
- 正規の.l10n.phpと不審なPHPの見分け方
- 削除前に残す証拠と安全な確認手順
- 不審ファイルの隔離・復旧・動作確認の順番
- 別の侵入口と再感染経路まで調べる方法
結論は「PHPだから削除」ではなく、
正規の翻訳データか、翻訳と無関係なプログラムかを根拠で分けることです。
まず現在の状態を保存し、その後にWordPressの仕様、言語パック、参照元、ログを照合します。
順番を守れば、表示言語を壊す事故と、感染を残す事故の両方を避けやすくなります。
WordPressのlanguagesフォルダにPHPがある時の結論
WordPressのlanguagesフォルダでPHPを発見したら、
最初に行うのは削除や上書きではなく、ファイル名を含む現状の保全です。
理由は、.l10n.phpという正規ファイルと、
翻訳に不要な任意PHPが同じ拡張子で存在し得るからです。両者は置かれている場所だけでは区別できません。
.l10n.phpはWordPress 6.5以降の正規形式
WordPress 6.5では翻訳処理が刷新され、.moに対応する.l10n.phpがある場合、
PHP形式を優先して読み込む仕組みが導入されました。
そのため、ja.l10n.phpやプラグイン名・ロケールを含む*.l10n.phpを見つけても、
それだけでバックドアと判断してはいけません。WordPress.orgの言語パック更新で生成・配置されることがあります。
任意の.phpは翻訳用途を確認する
反対に、update.php、class.api.php、無作為な英数字名など、.l10n.phpではないPHPが置かれている場合は、由来と役割の確認が必要です。
ただし独自プラグインや保守ツールが独自配置している可能性もあります。
ファイル名の印象だけで感染と決めず、管理者、制作会社、サーバー会社の変更履歴まで照合してください。
- .l10n.phpは正規形式の可能性を先に確認する
- 任意名の.phpは生成元・内容・参照元を調べる
- どちらも証拠を残す前に削除しない
WordPressのlanguagesフォルダにある正規ファイルを知る
不審かどうかを見分けるには、
先にlanguagesフォルダの正常な構成を知ることが重要です。
WordPress本体の翻訳はlanguages直下、プラグインはlanguages/plugins、
テーマはlanguages/themesへ置かれるのが一般的です。環境や独自実装によって別の翻訳ディレクトリを使う場合もあります。
翻訳ファイルは複数の形式で存在する
よく見られるのは、翻訳済み文字列を格納する.mo、
翻訳元情報を含む.po、JavaScript向けの.json、高速読込用の.l10n.phpです。
.l10n.phpはPHPとして実行可能な形ですが、正規ファイルでは翻訳メタデータとメッセージの配列を返します。
任意のURLへ接続したり、別ファイルを書き換えたり、ユーザーを追加したりする役割はありません。
ファイル名はtext domainとlocaleに対応する
プラグイン・テーマの翻訳ファイルは、
通常「text domain+ロケール」の組み合わせで名前が付けられます。
たとえば同じ基礎名の.moと.l10n.phpが並び、
更新時刻も言語パック更新と一致するなら正規である可能性が高まります。ただし一致だけで確定せず、内容と配布元も確認します。
- core・plugins・themesのどこに置かれているか
- text domainとjaなどのlocaleが名前に含まれるか
- 対応する.mo・.po・.jsonが存在するか
- 言語パックやプラグイン更新の時刻と一致するか

WordPressのlanguagesフォルダを変更する前に証拠を残す
正規・不正の判定前に、ファイル本体と周辺情報を同じ時点で保存してください。
後から内容や時刻が変わると、侵入経路や再生成元を追えなくなるためです。
パス・時刻・権限・所有者・ハッシュを記録する
最低限、絶対パス、ファイルサイズ、更新時刻、権限、所有者、SHA-256を記録します。
同じディレクトリの一覧と、前後の更新時刻を持つファイルも保存すると時系列を比較しやすくなります。
find /path/to/wp-content/languages -type f -print
find /path/to/wp-content/languages -type f -name '*.php' -exec shasum -a 256 {} \;
find /path/to/wp-content/languages -type f -name '*.php' -exec stat {} \;上記は読み取り用の例です。実際のWordPressパスへ置き換え、
出力に顧客名やサーバーパスが含まれる場合は、共有範囲を制限してください。
ブラウザで直接開かずコピーを解析する
不審なPHPのURLをブラウザで開く確認は避けます。
GETアクセスだけで処理が動くコードなら、外部通信、追加ファイル作成、転送などを自分で起動する可能性があります。
解析は権限を制限した保全コピーで行い、
本番ファイルへエディターの自動整形や保存をかけないでください。改行や時刻が変わるだけでも比較の精度が落ちます。
言語更新とバックアップ履歴を確認する
管理画面の更新履歴、保守記録、バックアップを確認し、
言語パックの更新直後に同名ファイルが追加されたかを調べます。
古いバックアップに同一ハッシュが継続してあり、公式更新と一致するなら正規性の根拠になります。
ただし、長期間存在したことは安全の証明ではないため、内容確認を省略してはいけません。
- URLを推測してブラウザから直接実行する
- 保全前に削除・改名・上書き・権限変更する
- 感染の可能性があるバックアップを正常版と混ぜる
- ファイル内容やサーバーパスを公開の場へ貼る
WordPressのlanguagesフォルダのPHPを正規と判断する条件
正規の可能性が高いPHPは、名前だけでなく、
対応する翻訳ファイル、データ構造、生成元、更新経路が一貫しています。
.l10n.phpの命名と対応ファイルを見る
まず末尾が正確に.l10n.phpであるか、
同じ基礎名を持つ.moや.poがあるかを確認します。
example-ja.l10n.phpに対しexample-ja.moがあり、
対象プラグインのtext domainもexampleなら、命名の整合性があります。似た文字を使う偽装名や二重拡張子には注意してください。
翻訳データを返す構造か確認する
WordPress公式の例では、PHP翻訳ファイルはメタ情報とmessagesを含む配列を返します。
通常は翻訳文字列の読み込みが目的であり、リクエスト処理やファイル操作を行う必要はありません。
配列を返す中に不自然なコードを紛れ込ませることも技術的には可能です。
冒頭と末尾だけで安心せず、外部入力、復号、動的実行、書き込み、通信、認証処理が混ざっていないか全体を確認します。
公式の言語パックと再取得して比較する
対象のWordPress本体・プラグイン・テーマの版とlocaleを特定し、
信頼できる配布元から同じ条件の言語パックを別の安全な場所へ取得します。
本番側とハッシュまたは差分を比較し、完全一致なら強い根拠になります。
版やlocaleが違う比較は誤判定につながるため、「最新版だから」という理由だけで別版と比べないでください。
WordPressのlanguagesフォルダで不審なPHPを見分ける
不審なPHPは、翻訳データとして説明できない機能と、
正規更新では説明できない配置・時系列を組み合わせて判断します。
名前・場所・更新時刻の不整合を探す
.l10n.phpではない任意名、バックアップ風の拡張子、隠しファイル、
プラグイン名と無関係なサブディレクトリは、確認優先度を上げる材料です。
深夜に同時刻で複数サイトへ作られた、所有者が他の翻訳ファイルと違う、
言語更新がないのに単独で変化した、といった不整合も記録します。時刻は改ざんできるため単独では断定しません。
翻訳と無関係な処理がないかを見る
外部入力を受け取る、任意コマンドを組み立てる、別ファイルを作成する、
管理者やデータベースを書き換える、外部サーバーへ通信する処理は翻訳用途では説明しにくい挙動です。
base64_decodeなどの関数名だけで感染と決めるのも避けてください。
正規コードで使われる場合がある一方、文字列分割や多段復号で隠す例もあるため、入力から出力までの流れを確認します。
条件付き実行と再生成の仕組みを確認する
特定のCookie、User-Agent、参照元、IP、時刻だけで動くコードは、
管理者の通常確認を避ける条件付きマルウェアで使われることがあります。
削除後に同じPHPが戻る場合、languages内のファイルだけが原因とは限りません。
Cron、mu-plugins、drop-ins、テーマ、侵害された管理者、サーバー側タスクなど、別の作成元を追う必要があります。
- 翻訳ファイルの命名規則と一致しない
- 対応する.mo・.po・text domainがない
- 翻訳と無関係な実行・通信・書き込みを行う
- アクセスや更新の時系列がサイト症状と一致する
- 隔離後に別経路から同一ファイルが再生成される

WordPressのlanguagesフォルダのPHPが実行されたか確認する
コードが不審でも、実際の被害範囲は実行経路とログを見なければ分かりません。
ファイルの存在、読み込み、Webからの直接アクセスを分けて調べます。
include・requireと翻訳読み込みを追う
正規の.l10n.phpはWordPressの翻訳コントローラーから読み込まれます。
任意PHPがテーマやプラグインからinclude・requireされていないか、読み取り検索で参照元を確認します。
grep -R --line-number --fixed-strings 'suspicious-file.php' /path/to/wordpress
grep -R --line-number 'wp-content/languages' /path/to/wordpress/wp-content検索対象にはバックアップやキャッシュが混ざる場合があります。
一致したという事実だけで実行済みと断定せず、現在読み込まれるコードかを確認してください。
Webから直接実行できる設定か確認する
languages配下が公開URLに対応し、サーバーがPHPとして処理するなら、
直接リクエストで起動される可能性があります。ただし確認のために自分でURLへアクセスするのは避けます。
Webサーバー設定、PHPハンドラー、アクセス制御を確認し、
既存ログから該当パスへのGET・POST、応答コード、送信元、時刻を調べるのが安全です。
同時刻のファイル・DB・ユーザー変更を結ぶ
該当PHPへのアクセス前後に、別PHPの生成、.htaccess変更、
不審管理者追加、予約処理、データベース更新がないかを同じ時系列へ並べます。
ログが保存されていない場合は「実行されていない」とは言えません。
確認できた事実、推測できる範囲、追加調査が必要な項目を分けて記録してください。
WordPressのlanguagesフォルダから安全に隔離・復旧する
不正の可能性が高いPHPは、削除ではなく、
戻せる状態を確保して公開領域外へ一つずつ隔離します。
隔離前に復元経路と影響範囲を用意する
保全コピー、データベース、設定、ログを分離して保存し、
正規の言語パックを再取得できることを確認します。
業務サイトでは、メンテナンス表示、問い合わせ停止時間、担当者、切り戻し条件も決めます。
感染疑いがあるバックアップを正常バックアップへ上書きしないでください。
公開領域外へ一つずつ移して動作確認する
隔離先はWebから実行できない場所を選び、アクセス権を制限します。
複数ファイルを一度に動かすと、どの変更で翻訳やサイト機能が壊れたか分からなくなります。
1ファイルずつ読み込み対象から外し、公開画面、管理画面、ログイン、フォーム、決済、
日本語表示、プラグイン・テーマ画面を確認します。単にトップページが表示されたことだけで完了にしません。
公式の言語パックで復元してキャッシュを確認する
正規翻訳が欠損・改ざんしていた場合は、
同じWordPress・プラグイン・テーマ版に合う信頼できる言語パックから復元します。
翻訳キャッシュ、オブジェクトキャッシュ、OPcache、CDN、ブラウザキャッシュが残ると、
復旧前の表示が続く場合があります。削除対象を広げず、層ごとに消去して再確認してください。
- 原本・属性・ハッシュ・ログを保全する
- 正規の再取得元と切り戻し方法を確認する
- 公開領域外へ一つずつ隔離する
- 同じ版の正規ファイルを必要な範囲だけ復元する
- 翻訳・主要機能・ログ・再生成を確認する
WordPressのlanguagesフォルダ以外も調査して再感染を防ぐ
不正PHPを隔離しても、侵入口や再生成元が残れば再発します。
languagesだけをきれいにして復旧完了と判断しないでください。
同時刻に変わった永続化ポイントを確認する
管理者ユーザー、WP-Cron、Action Scheduler、mu-plugins、drop-ins、
有効・未使用テーマ、uploads、wp-config.php、データベースを確認します。
同一サーバーに別のWordPressや古いCMSがある場合は、そちらも調査対象です。
一つのサイトだけ直しても、共有アカウントや別サイトから再侵入される可能性があります。
認証情報と脆弱性を安全な順番で処理する
安全な端末から、サーバー、SFTP、WordPress管理者、データベース、API連携など、
影響範囲に応じて認証情報を変更します。
古いWordPress、テーマ、プラグイン、不要な管理者、外部公開設定も見直します。
原因を塞ぐ前のパスワード変更は、攻撃者に新しい情報を再取得される場合があるため順番が重要です。
短期監視とクリーンな基準を残す
復旧直後はアクセスログ、ファイル変更、管理者、予約処理、外部通信を重点的に確認します。
数時間正常だっただけで終わらせず、数日・数週間の監視期間を決めてください。
再発がないことを確認した後に、正規ファイルのハッシュ一覧とクリーンなバックアップを作り直します。
次回は「正常との差分」を短時間で確認できる状態にしておくことが、最も実用的な再発防止です。
- 不審管理者・セッション・Application Passwords
- Cron・Action Scheduler・mu-plugins・drop-ins
- テーマ・プラグイン・uploads・wp-config.php
- 同一サーバーの別WordPress・古いCMS・メール
- アクセスログ・ファイル変更・外部通信の再発
WordPressのlanguagesフォルダに関するよくある質問
WordPressのlanguagesフォルダに不審なPHPがある時のまとめ
languagesフォルダのPHPは、拡張子だけで正規・不正を判断できません。
WordPress 6.5以降の.l10n.phpは正規の翻訳形式であり、誤削除すると日本語表示や翻訳機能へ影響します。
最初に原本、属性、ハッシュ、ログを保存し、
ファイル名、対応する.mo、text domain、locale、配列構造、配布元、更新履歴を照合してください。
翻訳と無関係な実行・通信・書き込みがあるPHPは、
公開領域外へ一つずつ隔離し、公式言語パックから必要な範囲だけ復元します。
最後に管理者、Cron、mu-plugins、drop-ins、テーマ、uploads、データベース、同一サーバーの別サイトまで確認し、
再生成元と侵入口を塞いでからクリーンなバックアップを作り直しましょう。
languagesフォルダの不審なPHPを自分で判断できない時は

正規の翻訳PHPとバックドアの区別、実行記録、再生成元まで自分で追えない場合は、
クイックレスキューが証拠保全から駆除・復旧・再発防止まで対応します。
- .l10n.phpが正規か改ざん済みか判断できない
- languages内のPHPを消してよいか分からない
- 隔離しても同じファイルが再生成される
- 別のバックドアや不正管理者も残っていそう
- 日本語表示や業務機能を壊さず復旧したい
- 万一復旧できない場合やマルウェア駆除できない場合は全額返金保証で安心
- 90日間再感染保証・動作保証で安心
- 初期費用・調査費用0円で安心








