FlawOpen

flawopen.com/AI Security/ghostjacking-ai-agent-poisoned-observability-logs-august-2026

● FlawOpen mapping: CWE-1427 · Editorial severity: Medium
FlawOpen Security Research

GhostJacking: Poisoned Logs and AI Agents

Research shows how attacker-controlled telemetry can steer an integrated AI agent. No CVE or confirmed victim breach.[1], [2]

💡 Plain English Explainer (ELI5)

Imagine a receptionist blocks a suspicious delivery but copies the sender’s note into the incident log. Later, a dispatcher verifies a real ticket number and a genuine gap in the demo’s DNS policy, then trusts the attacker-chosen address in the same note and changes the public address book that tells browsers and email where the company’s services live. The log was evidence, not authority to make that change; a separate policy check and approval should control it.[1]

Core Concepts & Subsystem Terms

GhostJacking
Tenet Security’s name for demonstrations in which attacker-controlled content in observability events influences an AI agent connected to those tools. It is a research label, not a CVE.[1], [2]
Indirect prompt injection
Instructions embedded in data the model is asked to inspect, rather than supplied as a direct instruction by the user.[1], [2], [4]
Observability event
A log, alert, trace, or error record describing system activity. Some fields can contain text supplied by an external requester.[1], [2]
Independent authorization
A non-model policy check that evaluates the actor, target, requested change, and approval before a tool performs a consequential action.[2], [5]
CWE-1427
MITRE’s weakness class for improper neutralization of input used in LLM prompting. This is FlawOpen’s conceptual mapping; Tenet, ngCERT, and a CVE record did not assign it to GhostJacking.[4], [1], [2]
Editorial severity
ngCERT labels the advisory risk and damage High. FlawOpen rates this evidence summary Medium because the demonstrations require an agent with relevant integrations and mutation permissions; no victim breach is confirmed. This is an editorial rating, not a vendor score.[2], [1]

Framework mappings

Step-by-Step Attack Flow

Step 1

An agent receives authority to investigate

Tenet’s research describes coding or operations agents connected to tools such as Cloudflare, Datadog, and Sentry. The relevant precondition is an agent that can both read external event content and take consequential actions with its existing permissions.[1]

Step 2

A request is recorded as evidence

In Tenet’s Cloudflare demonstration, a request is blocked by a WAF while attacker-controlled text in a request field is retained in an event record. A blocked request can still leave untrusted text for a later agent to read.[1], [2]

Step 3

Plausible telemetry bypasses obvious-instruction defenses

Tenet reports that obvious commands were rejected in its testing. Its successful Cloudflare demonstration instead used structured scanner-like telemetry with a ticket reference, compliance citation, and metric; the agent verified some claims, then trusted unverified attacker-controlled DNS values. This is a researcher-reported demonstration of indirect prompt injection, not evidence of a real-world victim breach.[1], [2]

Step 4

Existing permissions turn influence into impact

Tenet reports that its controlled demonstration caused an agent to modify DNS through an integrated Cloudflare tool. That outcome depends on the connected agent’s permissions and configuration; it is not evidence that Cloudflare itself was compromised or that customer systems were attacked.[1]

Step 5

A separate policy boundary can stop the change

The application should treat the model’s proposal as untrusted. A server-side authorization service must independently check the exact resource and change, require approval from an authorized human where appropriate, and record the decision before calling the provider API.[2], [5]

Source Code: Flaw vs. Secure Implementation

These are illustrative application snippets, not the vulnerable or fixed source of any named product. The unsafe shape gives an agent that reads untrusted event text a direct mutation tool. The hardened shape separates proposal from execution: an independent service consumes a one-time approval bound to the exact actor and change, then applies policy before calling the provider. The actor identity comes from authenticated server context, not a caller-controlled field; the model cannot choose it. A prompt instruction alone is not an authorization control. Production code must also validate schemas, tenant and resource ownership, approval expiry, replay resistance, audit durability, and provider error handling.[1], [2], [5]

UNPATCHED FLAW
// Illustrative unsafe integration; not source code from Cloudflare, Datadog, Sentry, or Tenet.
async function investigate(event: EventRecord) {
  return agent.run({
    context: event.message,
    tools: [cloudflare.updateDnsRecord]
  });
}
HARDENED SECURE PATCH
// Illustrative control boundary; the model can propose, but cannot authorize or apply.
type DnsProposal = { zoneId: string; name: string; value: string };

async function proposeDnsChange(event: EventRecord): Promise<DnsProposal> {
  return agent.propose({ evidence: markUntrusted(event.message) });
}

async function applyDnsChange(
  proposal: DnsProposal,
  approvalId: string
) {
  const actorId = auth.requireAuthenticatedActorId();
  const validatedProposal = DnsProposalSchema.parse(proposal);
  const approval = await approvals.consumeOnce(approvalId, { actorId });
  if (!approval || approval.actorId !== actorId ||
      approval.zoneId !== validatedProposal.zoneId ||
      approval.name !== validatedProposal.name ||
      approval.value !== validatedProposal.value ||
      !policy.canChangeDns(actorId, validatedProposal.zoneId, validatedProposal.name)) {
    throw new Error('DNS change is not independently authorized');
  }
  // Fail closed if the authorization decision cannot be recorded before mutation.
  await audit.record({ actorId, approvalId, action: 'dns-change', decision: 'authorized' });
  try {
    await cloudflare.updateDnsRecord(validatedProposal);
  } catch (error) {
    await audit.record({ actorId, approvalId, action: 'dns-change', outcome: 'provider-failed' });
    throw error;
  }
  await audit.record({ actorId, approvalId, action: 'dns-change', outcome: 'succeeded' });
}

Engineering & System Hardening Checklist

Sources

← AI Security Hub Directory →