Tool Hijacking

Tool hijacking — злоупотребление избыточными правами агента (Excessive Agency): через инъекцию агента заставляют вызвать его собственный инструмент с аргументами атакующего. Нарушаются права и действия агента — он «своими руками» сливает данные, деньги или выполняет вредный код. Это то, во что превращается Prompt Injection, когда у модели есть «руки».

Суть

Корневая причина — агенту дали слишком много прав и не ограничили последствия. Сам по себе вызов инструмента легитимен (read_file, http_request), но управляемый инъекцией он становится каналом атаки. Для внешнего мира это выглядит как «обычный HTTP-запрос от агента» — без алертов.

Зачем это нужно

Это самая «дорогая» категория: в отличие от jailbreak (вытащить текст), здесь происходит действие с необратимыми последствиями (деньги, письма, БД). Защита — не только фильтры на вход, но и ограничение самих прав (Agent Governance) и изоляция исполнения (Agent Sandboxing).

Как работает (подтипы)

  • Token / data exfiltration — агент получает команду прочитать .env и отправить содержимое на внешний URL. Инструменты read_file + http_request выполняют её без вопросов → утекают ключи от всей инфраструктуры. Никаких алертов — обычный HTTP-запрос.
  • Malicious skills / plugins — атакующий публикует инструмент с легитимным названием (pdf-reader, web-search-pro). Варианты:
    • rug pull — вредонос добавляют после обновления плагина;
    • typosquatting — openai-mcp-tools vs openai_mcp_tools;
    • скомпрометированная зависимость внутри легитимного плагина. Итог — выполнение произвольного кода внутри агента, backdoor; агент вызывает плагин автоматически.
  • Runaway API-billing — агент застрял в цикле (не может выполнить задачу → повторяет), либо команда «повтори запрос 1000 раз» → счёт за API (см. также Agent CostControl).

Защита

  • Allowlist инструментов и доменов — детерминированная проверка ДО вызова: что агент может запускать, на какие хосты ходить (проверять именно хост, а не подстроку: ловушка wildberries.ru.attacker.net):
from urllib.parse import urlparse
ALLOWED_DOMAINS = {"wildberries.ru"}                 # домен + поддомены (www., m. …)

def is_allowed_url(url) -> tuple[bool, str]:
    try:
        parsed = urlparse(str(url))
    except Exception:
        return False, "<unparsable>"
    if parsed.scheme not in ("http", "https"):       # режем не-http (ftp://…)
        return False, f"scheme:{parsed.scheme}"
    host = (parsed.hostname or "").lower().rstrip(".")
    for dom in ALLOWED_DOMAINS:                       # сравниваем ХОСТ, не подстроку
        if host == dom or host.endswith("." + dom):   # ловушка wildberries.ru.attacker.net -> block
            return True, host
    return False, host or "<empty-host>"

Узел-привратник scrape_one_safe() / n_domain_guard() вызывает is_allowed_url() ДО Firecrawl — экономит биллинг и режет чужие домены.

  • HITL на опасных действиях (Human in the Loop) — деньги/auth/bash требуют апрува.
  • Ограничение последствий — Agent Sandboxing: даже захваченный агент не вырывается за microVM.
  • Принцип наименьших прав — каждому агенту/инструменту только необходимый минимум доступа (Agent Governance, ролевая модель из ФСТЭК №21).
  • Для MCP-инструментов — проверять источник/издателя, фиксировать версии зависимостей.

Связано с

  • Prompt Injection — механизм, через который запускается hijacking
  • Agent Sandboxing — изоляция, ограничивающая ущерб
  • Agent Governance — уровни автономии и пропорциональные права
  • Agent CostControl — runaway-billing как форма Token DoS
  • MCP — инструментальный слой, чьи плагины могут быть скомпрометированы

Открытые вопросы

  • Как практично верифицировать издателя MCP-инструмента до подключения?