Skip to content

security(npu-worker): the Windows worker's /pair and /unpair accept any caller #16658

Description

@mrveiss

Problem

The Windows NPU worker's pairing routes accept any caller, so anyone who can reach the worker's port can take it over.

  • No authentication anywhere. autobot-npu-worker/resources/windows-npu-worker/app/worker_pairing.py registers POST /pair, GET /pairing-status and POST /unpair (:34-50) without caller authentication. The worker app has no auth middleware or auth dependency anywhere under app/.
  • /unpair works for anyone. _handle_unpair (:122-148) deletes the worker-ID and pairing-status files on any request.
  • /pair accepts any host. On an unpaired worker, _handle_pair (:52-109) saves the caller's worker_id and main_host. It then applies the request's optional config through _apply_main_host_config (:150-193): the Redis settings, the NPU optimisation settings, and a model preload.

So a caller can unpair the worker and re-pair it to a host of their choosing. That points its Redis at an endpoint they control and triggers model preloads.

The legitimate pairing push is also unencrypted. It carries the Redis credential in that config (autobot-backend/api/npu_workers.py, _build_pairing_config and _send_pairing_request), and it goes to the worker URL as given. The worker reports that URL as http:// (app/utils/config_bootstrap.py:120), so the credential crosses the network in the clear.

Acceptance criteria

  • /pair, /unpair and every other state-changing worker route authenticate the calling main host. Tests show that an unauthenticated unpair or re-pair is refused.
  • Credentials pushed to the worker travel over an encrypted, authenticated channel.

Refs #16657, #16627

Activity

  1. mrveiss commented on Sep 13, 2026

    @mrveiss
    OwnerAuthor

    Owner decision, 2026-09-13, from #16627 (P1b): the Windows worker currently ignores a Redis config pushed at pairing. _apply_main_host_config stores it on self._bootstrap_config, but initialize_redis reads the bootstrap module's cache through get_redis_config(). Wiring that up while /pair accepts any caller would let anyone who can reach a worker redirect its Redis. So this issue now also covers making the worker apply a pushed Redis config, after /pair authenticates the calling host. P1b only adds the default username to the admin pair/repair payloads. This issue now blocks P2 (#16628).

  2. added this to the v0.11.0 milestone on Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions