Traccar:空のパスワードによる LDAP 認証の回避(CVE-2026-126777)
Traccar 3.15から6.16.0は LDAP ログインで空のパスワードを受け入れるため、ユーザー名を知る攻撃者が管理者を含む任意のアカウントでサインインできます。
要点
- Traccar は空の LDAP パスワードをディレクトリに送り、その結果として生じる非認証バインドを正常なログインとして扱います。VulnCheck は 2026 年 11 月 11 日に CVE-2026-126777 として公開しました。
- LDAP 認証が有効で、ディレクトリが非認証バインドを受け入れる場合、Traccar 3.15 から 6.16.0 までのすべてのリリースが影響を受けます。
- スコアは CVSS v4.0 9.1 の重大、CVSS v3.1 7.4 の高です。悪用は確認されておらず、2026 年 11 月 12 日時点で CISA の KEV カタログに登録されていません。
- 2026 年 11 月 1 日に公開された 6.17.0 に更新してください。更新できない場合は、LDAP 認証を無効にするか、更新できるまでセッションエンドポイントへのアクセスを遮断してください。
影響を受けますか?
次の4つの条件がすべて当てはまると影響を受けます。
- Traccar 3.15 から 6.16.0 を実行している。
- LDAP 認証が設定されている。Traccar は
ldap.url設定が存在するときに LDAP プロバイダーを作成します。 - LDAP ディレクトリが、既知のアカウント名に対する非認証バインドを受け入れる。長さゼロのパスワードを拒否するディレクトリは、この方法では悪用できません。
- 攻撃者が、メールアドレスやログイン名などの有効なアカウント名を知っている。
脆弱性はログイン経路にあり、Web API と HTTP Basic 認証を使うすべてのクライアントに影響します。Traccar の Web インターフェースには依存しません。管理者アカウントも他のアカウントと同じように露出します。
ldap.force 設定は、すべてのログインが LDAP を使うか、ローカルアカウントと並行して LDAP を試すかを決めます。ldap.force が無効な展開でも、ディレクトリに存在するアカウント名を通じて攻撃できます。
| 分岐 | 影響を受けるバージョン | 修正版 |
|---|---|---|
| すべてのリリース | 3.15 から 6.16.0 | 6.17.0(2026-11-01 公開) |
Traccar のサーバーエンドポイントは、認証なしで実行中のバージョンを返します。
curl -s https://<traccar-host>/api/server | python3 -c "import json,sys; print(json.load(sys.stdin)['version'])"
コンテナまたはインストールディレクトリの設定ファイルで LDAP が有効か確認します。
docker exec traccar sh -c 'grep -n "ldap\." /opt/traccar/conf/traccar.xml'
パッケージインストールの traccar.xml にも同じ設定があります。ldap.url のない展開は脆弱なプロバイダーを使いません。
修正方法
Traccar 6.17.0 に更新してください。このリリースには、ディレクトリへのバインドを始める前に null または空のパスワードを拒否する3行のチェックが含まれます。
- composeファイルのイメージタグを
traccar/traccar:6.17.0に変更してから、イメージを取得してコンテナを再作成します。別のタグを参照したままのcomposeファイルでは、脆弱なイメージが動き続けます。docker pull traccar/traccar:6.17.0 docker compose up -d - 実行中のバージョンを確認します。
curl -s https://<traccar-host>/api/server | python3 -c "import json,sys; print(json.load(sys.stdin)['version'])" - パッケージインストールでは、6.17.0 のリリースをダウンロードし、サービスを停止してプログラムファイルを置き換え、再起動します。
- 正しいパスワードでの LDAP ログインと、空のパスワードでのログインを試します。空のパスワードの試行は失敗するはずです。
すぐに更新できない場合は、次の対策で露出を減らしてください。どれも修正の代わりにはなりません。
ldap.url設定を削除して LDAP 認証を無効にし、使用できるローカル管理者アカウントを少なくとも1つ残します。Traccar はローカルのユーザーストアに戻ります。- プロキシで
/api/sessionと HTTP Basic 認証を信頼できるネットワークに制限します。これでリモートのログイン経路は閉じますが、パスワード確認の欠落は修正されません。 - 期間中に不要であれば、LDAP が認証するアカウントを無効にします。攻撃者には有効なアカウント名が必要なので、名前を外せば経路も外れます。
根本原因は何ですか?
LdapProvider.login() は空文字列を含む任意のパスワードを受け入れ、ディレクトリの応答をパスワードが正しかった証拠として使います。
このメソッドは最初にアカウントを検索し、次にそのアカウントとして、渡されたパスワードでバインドします。
public boolean login(String username, String password) {
try {
SearchResult ldapUser = lookupUser(username);
if (ldapUser != null) {
auth(ldapUser.getNameInNamespace(), password).close();
return true;
}
} catch (NamingException e) {
return false;
}
return false;
}
lookupUser はサービスアカウントで実行されます。要求されたアカウントの識別名を返します。その後のバインドは、攻撃者が指定したパスワードを使います。
private InitialDirContext auth(String accountName, String password) throws NamingException {
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, url);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, accountName);
env.put(Context.SECURITY_CREDENTIALS, password);
return new InitialDirContext(env);
}
Java の JNDI は、識別名とパスワードを伴う単純バインドを送ります。パスワードが空の場合、要求は長さゼロの資格情報を持ちます。RFC 4513 はこれを非認証バインドと定義しており、ディレクトリはこれを受け入れて成功結果を返すことができます。Traccar は結果がパスワード認証済みのバインドから来たかを確認しないため、true を返します。
検索があるため攻撃は正確になります。攻撃者はパスワードや識別名を推測する必要がなく、有効なアカウント名だけを知っていれば十分です。
どのように悪用されますか?
- 攻撃者は有効なアカウント名と空のパスワードで
POST /api/sessionにログイン要求を送ります。 - Traccar はその名前と空のパスワードで
LdapProvider.login()を呼びます。 lookupUser()はサービスアカウントを使って、ディレクトリ内のアカウントの識別名を探します。auth()はその識別名と長さゼロのパスワードで単純バインドを送ります。- 非認証バインドを許可するディレクトリはコンテキストを返します。Traccar はそのコンテキストをパスワード確認の成功として扱います。
- Traccar はそのアカウントのセッションを作成します。名前が管理者アカウントのものであれば、管理者セッションになります。
同じ経路は HTTP Basic 認証でも到達できます。同じログインサービスを使うためです。公開された実証コードはなく、要求に特別なツールは必要ありません。
攻撃の流れは?
有効なアカウント名と空のパスワードが、パスワードを確認せずに応答する LDAP バインドに達し、Traccar はその応答をログインとして受け入れます。
POST /api/session"] --> B["LdapProvider.login()"] B --> C["lookupUser() がアカウントの
識別名を検索"] C --> D["パスワード確認なしの
JNDI 単純バインド"] D --> E["ディレクトリが非認証
バインドを実行"] E --> F["対象アカウントの
セッションを発行"]
攻撃者に何ができますか?
管理者アカウントの名前を知る攻撃者は、パスワードなしで管理者セッションを得ます。Traccar の管理者は、すべてのデバイスの現在位置、走行履歴、イベントレポート、整備記録を見られ、すべてのユーザー、デバイス、ジオフェンス、通知、保存済みレポートを一覧表示して管理できます。管理者は対応しているデバイスにコマンドを送ることもでき、車両を停止させたり設定を変えたりできます。
管理者以外のアカウントのセッションでは、そのアカウントのデバイスと位置にアクセスできます。フリート展開では、それでも多くの車両の現在位置が露出します。読み取り専用のオペレーターアカウントでも、見えるデバイスの同じ位置履歴を露出し、これは依然として機密性の高いフリートデータです。
この脆弱性自体はサーバー上のコード実行を与えません。影響はアカウントの権限であり、重要なのは管理者アカウントです。攻撃者にはログインエンドポイントへのネットワークアクセスと、1つの有効なアカウント名が必要です。ユーザーの操作は不要です。
修正が機能する理由
修正は、検索やバインドの前に null または空のパスワードを拒否します。
public boolean login(String username, String password) {
+ if (password == null || password.isEmpty()) {
+ return false;
+ }
try {
SearchResult ldapUser = lookupUser(username);
if (ldapUser != null) {
チェックは lookupUser より前に実行されるため、空のパスワードはディレクトリに届きません。空でないパスワードは通常の単純バインド経路を通ります。ディレクトリが資格情報の正しさを判断し、Traccar はその資格情報に対してディレクトリが返したコンテキストだけを受け入れます。
修正はこの経路について完全です。Traccar はサービスアカウントの検索にも同じ auth() を使い、それらの呼び出しは設定されたサービスパスワードを渡します。サービスパスワードを空に設定した展開では、依然として非認証のサービスバインドが行われるため、その設定も空にしないでください。
侵害されたかどうかを確認するには?
この CVE に公開された指標はありません。ディレクトリと Traccar のアクセスログで次のパターンを確認してください。
- Traccar サービスホストからの、長さゼロのパスワードによる単純バインド。
- 運用者の通常の場所と一致しないアドレスからの、管理者アカウントの成功セッション。
- リバースプロキシのアクセスログにある、信頼済みの範囲外のクライアントアドレスからの
POST /api/session要求。アクセスログに残るのはパスとクライアントアドレスで、要求本文は残らないため、パスワードフィールド自体は確認できません。
非認証バインドを受け入れるディレクトリは、設定によって匿名または通常のバインドとして記録することがあります。失敗した試行は何も残さないことがあります。予期しない管理者セッションは侵害として扱い、そのアカウントのパスワードと到達できる API トークンをローテーションしてください。
年表
- 2026-10-31:修正コミット
552c31f2が空パスワードのチェックを追加します。 - 2026-11-01:修正を含む Traccar 6.17.0 が公開されます。
- 2026-11-11:VulnCheck が 18:41 UTC に CVE-2026-126777 を公開します。
修正は CVE レコードより11日前にコミットされました。コミットからリリースまでが1日、リリースから公開までが10日です。
よくある質問
すべての Traccar 展開が影響を受けますか?
いいえ。LDAP 認証を使い、ディレクトリがアカウント名に対する非認証バインドを受け入れる必要があります。ローカルアカウントだけの Traccar は影響を受けません。
ディレクトリを安全にテストできますか?
はい。テストアカウントと管理されたクライアントを使います。有効な識別名と長さゼロのパスワードで単純バインドを送り、ディレクトリが成功を返すか確認してください。本番の管理者アカウントでは試さないでください。
なぜ空のパスワードがログインになるのですか?
LDAP は、名前と長さゼロのパスワードを伴うバインドを非認証バインドと定義します。一部のディレクトリは匿名アクセスを支えるためにこれを受け入れます。Traccar はその結果をパスワード認証済みのバインドと区別していませんでした。
Web インターフェースは必要ですか?
いいえ。同じログインサービスが Web インターフェース、POST /api/session、HTTP Basic 認証を処理します。ログインエンドポイントに到達できるクライアントはこの脆弱性を使えます。
ldap.force 設定は露出を変えますか?
いいえ。この設定はどのアカウントが LDAP を使うかを変えるだけで、空パスワードのバインドが受け入れられるかは変わりません。ディレクトリに存在するアカウントは、ローカルログインも有効な場合でも LDAP 経路で使えます。
6.17.0 は他に何を変えますか?
6.17.0 には空パスワードのチェックと通常の機能・修正が含まれます。セキュリティに関係する変更は LdapProvider.login() の3行のガードです。
修正は通常の LDAP ログインを壊しますか?
いいえ。空でないパスワードは同じ単純バインドをディレクトリに対して続けます。修正はバインド前に null または空のパスワードを拒否するだけなので、パスワードを入力する利用者に変化はありません。
パスワードをローテーションすべきですか?
はい。パスワードなしで管理者セッションが作成された可能性がある場合です。影響を受けたアカウントのパスワードをローテーションし、最近の操作を確認してください。非認証バインドを受け入れたディレクトリは攻撃者を検証していないため、パスワード自体は露出していませんが、セッションは露出しています。
参考資料
- CVE-2026-126777 の VulnCheck アドバイザリ、https://www.vulncheck.com/advisories/traccar-3.15-before-6.17.0-authentication-bypass-via-empty-ldap-password(2026年11月12日確認)。
- CVE-2026-126777 レコード、https://www.cve.org/CVERecord?id=CVE-2026-126777(2026年11月12日確認)。
- Traccar 修正コミット 552c31f2、https://github.com/traccar/traccar/commit/552c31f2097dbed9edef7cfe174c50b16febdc21(2026年11月12日確認)。
- Traccar 6.17.0 リリース、https://github.com/traccar/traccar/releases/tag/v6.17.0(2026年11月12日確認)。
- Traccar v6.16.0 の
LdapProvider.java、https://github.com/traccar/traccar/blob/v6.16.0/src/main/java/org/traccar/database/LdapProvider.java(2026年11月12日確認)。 - Traccar v6.17.0 の
LdapProvider.java、https://github.com/traccar/traccar/blob/v6.17.0/src/main/java/org/traccar/database/LdapProvider.java(2026年11月12日確認)。 - RFC 4513 第5.1.2節、Unauthenticated Bind Operation、https://www.rfc-editor.org/rfc/rfc4513#section-5.1.2(2026年11月12日確認)。
- Traccar リポジトリ、https://github.com/traccar/traccar(2026年11月12日確認)。
- CISA の悪用済み脆弱性カタログ、https://www.cisa.gov/known-exploited-vulnerabilities-catalog(2026年11月12日確認)。