title: Arbitrary Write to SSH Authorized Keys or Shell Startup File via Unvalidated File-Edit Tool
id: ATR-2026-02040
rule_version: 1
status: experimental
description: |
  Detects an agent being directed to use a file-write/edit tool (multiedit, write_file, apply_diff, patch, or similar) to plant a persistence backdoor: injecting an attacker SSH public key into ~/.ssh/authorized_keys, or prepending a writable/temp directory (/tmp, /var/tmp, /dev/shm, ~/.cache) onto PATH inside a shell startup file (~/.bashrc, ~/.zshrc, ~/.profile, ~/.bash_profile). Mined from GHSA-29w3-p9w9-wc47 (PraisonAI multiedit tool has no path validation, workspace-boundary check, or protected-path guard, letting a crafted prompt make it read/write arbitrary files including SSH keys and shell dotfiles) -- generalized beyond that one tool name, since any file-edit tool lacking the same protections is equally exploitable. Ordinary edits to these files (adding an alias, an env var export, an nvm/pyenv init block) are common and must not fire; only the two concrete persistence primitives above do.
author: ATR Community (CVE sweep)
date: 2026/07/11
schema_version: '0.1'
detection_tier: pattern
maturity: experimental
severity: critical
references:
  owasp_llm:
    - LLM06:2025
  owasp_agentic:
    - ASI02:2026
  mitre_attack:
    - 'T1098.004 - Account Manipulation: SSH Authorized Keys'
    - 'T1546.004 - Event Triggered Execution: Unix Shell Configuration Modification'
  mitre_atlas:
    - AML.T0053 - LLM Plugin Compromise
metadata_provenance:
  owasp_llm: human-reviewed
  owasp_agentic: human-reviewed
  mitre_attack: human-reviewed
  mitre_atlas: human-reviewed
compliance:
  eu_ai_act:
    - article: '15'
      context: Article 15 (accuracy, robustness and cybersecurity) requires high-risk AI systems to resist unauthorised attempts to alter their behaviour or environment; this rule detects a file-edit tool being weaponised to plant an SSH-key or PATH-hijack persistence backdoor.
      strength: primary
    - article: '9'
      context: Article 9 (risk management system) requires identified risks to be addressed by appropriate measures; this rule is a runtime risk-treatment control for the file-edit-tool persistence-write risk class.
      strength: secondary
  nist_ai_rmf:
    - subcategory: MG.2.3
      context: Treating file-edit-tool persistence writes (authorized_keys injection, PATH hijack) as an identified AI risk requires active runtime countermeasures; this detection rule is the primary risk treatment implementation.
      strength: primary
    - subcategory: MP.5.1
      context: Identifying file-edit-tool persistence writes as an AI risk to be catalogued in the organizational risk register.
      strength: secondary
  iso_42001:
    - clause: '8.1'
      context: ISO/IEC 42001 Clause 8.1 (operational planning and control) is operationalised by this rule's detection of unvalidated file-edit-tool persistence writes.
      strength: primary
    - clause: '8.3'
      context: ISO/IEC 42001 Clause 8.3 (AI risk treatment) is implemented via this rule's runtime detection of the persistence-write attempt.
      strength: secondary
tags:
  category: privilege-escalation
  subcategory: file-edit-tool-persistence
  scan_target: llm_io
  confidence: high
agent_source:
  type: llm_io
  framework:
    - any
  provider:
    - any
detection:
  condition: any
  conditions:
    - field: content
      operator: regex
      value: (?i)\b(multiedit|write_file|apply_diff|patch|overwrite|append|edit)\b(?![\s\S]{0,135}?\b(?:my\s+own|my\s+key|myself|for\s+myself|me@[\w.-]+)\b)[\s\S]{0,40}\.ssh[\/\\]authorized_keys[\s\S]{0,40}\b(ssh-(rsa|ed25519|dss)|ecdsa-sha2-)\b
      description: File-edit tool directed to inject an SSH public key into authorized_keys (verb precedes path precedes key); excludes first-person self-referential key provisioning (my own / my key / myself / me@<host> comment)
    - field: content
      operator: regex
      value: (?i)\b(multiedit|write_file|apply_diff|patch|overwrite|append|edit)\b(?![\s\S]{0,135}?\b(?:my\s+own|my\s+key|myself|for\s+myself|me@[\w.-]+)\b)[\s\S]{0,40}\b(ssh-(rsa|ed25519|dss)|ecdsa-sha2-)\b[\s\S]{0,40}\.ssh[\/\\]authorized_keys
      description: File-edit tool directed to inject an SSH public key into authorized_keys (verb precedes key precedes path); excludes first-person self-referential key provisioning (my own / my key / myself / me@<host> comment)
    - field: content
      operator: regex
      value: (?i)\b(multiedit|write_file|apply_diff|patch|overwrite|append|edit)\b[\s\S]{0,30}(~[\/\\]?|\$HOME[\/\\])\.(bashrc|bash_profile|zshrc|profile)\b[\s\S]{0,40}\bexport\s+PATH=["\x27]?(\/tmp|\/var\/tmp|\/dev\/shm|~[\/\\]\.cache)[^\n"\x27]*:\$PATH
      description: Shell startup file edit prepending a world-writable/temp directory onto PATH (classic PATH-hijack persistence)
  false_positives:
    - Adding a normal alias, function, or env-var export to a shell rc file
    - Legitimate PATH additions pointing at project-local bin/ or language-version-manager (nvm/pyenv/rbenv) directories, not /tmp or /dev/shm
    - An operator provisioning their OWN SSH key via cloud-init/Ansible/bootstrap onboarding, expressed with first-person framing ("my own", "my key", "myself", or a "me@<host>" key comment) -- this rule now requires the request to NOT carry that self-referential framing before firing, since routine self-provisioning is common and an attacker planting a foreign key has no reason to frame it as the requester's own
response:
  actions:
    - block_input
    - alert
  message_template: |
    [ATR-2026-02040] File-edit tool directed to write an SSH persistence key or PATH-hijack entry -- treat as an attempted backdoor, not a routine dotfile edit.
confidence: 80
