Security Model: Claude Code on Android

July 27, 2026 ยท View on GitHub

This document describes what Termux:API permissions and ADB wireless debugging expose when used with Claude Code on Android. It is written for anyone considering granting these capabilities, developer or not. Read this before enabling Termux:API permissions or ADB wireless debugging.

Terms used here:

  • Termux is a terminal app that runs a Linux command-line environment on Android.
  • Termux:API is a companion app that lets Termux command-line tools reach Android features such as SMS, GPS, and the camera.
  • ADB (Android Debug Bridge) is Android's developer tool for sending commands to a device. Wireless debugging lets it connect over WiFi instead of over a USB cable.
  • MCP (Model Context Protocol) is a standard that lets external servers provide extra tools and data to Claude Code.
  • SSRF (server-side request forgery) is an attack that tricks a tool into making network requests to internal addresses it should not reach.
  • Hook is a script Claude Code runs automatically at a set point, such as a PreToolUse hook that runs before a tool call.
  • Headless means running Claude Code from a script or a single command (claude -p) rather than in a live interactive session.

The three install methods are called Path A, Path B, and Path C. See the README for what each one is.


What Termux:API Permissions Expose

When you grant a permission to the Termux:API companion app, every process running inside Termux can access that data type. There is no per-session or per-tool scoping. Once a permission is granted, it stays granted for all Termux processes until you revoke it in Android Settings.

Data TypeCommandPermission GateWhat This Means
SMS (read and send)termux-sms-list, termux-sms-sendSMS permissionAny Termux process can read your text messages and send new ones
Contactstermux-contact-listContacts permissionFull contact list accessible from Termux
Call logtermux-call-logCall log permissionIncoming and outgoing call history readable
GPS locationtermux-locationLocation permissionReal-time device coordinates available
Cameratermux-camera-photoCamera permissionCan take photos without the camera app open
Microphonetermux-microphone-recordMicrophone permissionCan record audio in the background
Clipboardtermux-clipboard-get, termux-clipboard-setNone (pre-Android 13)Clipboard contents readable and writable without a permission prompt on Android versions before 13. On Android 13 and later, the system limits background clipboard access and notifies you when the clipboard is read
Notificationstermux-notification-listNotification accessCan read notification content from all apps
Sensorstermux-sensorNoneAccelerometer, gyroscope, barometer, magnetometer, and other hardware sensors accessible
Fingerprinttermux-fingerprintBiometricsTriggers the biometric prompt (does not read fingerprint data)
Phone dialingtermux-telephony-callPhone permissionCan initiate outgoing calls
Text-to-speechtermux-tts-speakNoneCan speak text aloud through the device speaker

What ADB Adds

ADB wireless debugging runs commands as Android's shell user, a system-level debug identity that is more privileged than any app. These capabilities do not require any Termux:API permissions.

CapabilityCommandImpact
Screenshot any appadb shell screencapCaptures whatever is on screen, including banking apps, password managers, and private conversations
Screen recordingadb shell screenrecordContinuous video capture of the display
Touch and key injectionadb shell input tap/swipe/textCan tap buttons, type text, and navigate any app autonomously
Launch or stop any appadb shell am start/force-stopCan open banking apps, authenticators, email, or any installed application
SMS via content provideradb shell content query --uri content://smsReads SMS messages through a different access path than Termux:API
Contacts via content provideradb shell content query --uri content://com.android.contacts/contactsReads contacts through a different access path than Termux:API
System settingsadb shell settings get/putCan read and modify device configuration (brightness, DND, etc.)
Full process listadb shell ps -ALists every running process on the device
System logsadb logcatMay contain authentication tokens, URLs, and debug data from other apps
Installed appsadb shell pm list packagesComplete list of every app installed on the device
Hardware sensorsadb shell dumpsys sensorserviceFull hardware sensor inventory
Device propertiesadb shell getpropHardware identifiers, build info, carrier info

ADB Bypasses Termux:API Permission Denials

This is the critical point most users miss. If you deny SMS permission to the Termux:API companion app, termux-sms-list correctly fails. But adb shell content query --uri content://sms still works, because ADB operates as the shell user, not as the Termux app. Android's per-app permission model does not apply to ADB commands. Denying a permission in Android Settings blocks the app-level path but leaves the ADB path open. These are two completely different access levels using two different privilege models.


Threat Scenarios

Can the agent read my text messages? Yes, if you granted SMS permission to Termux:API (termux-sms-list) or if ADB is connected (adb shell content query --uri content://sms). This includes 2FA codes delivered via SMS.

Can it screenshot my banking app? Only with ADB connected. adb shell screencap captures whatever is currently on screen. If a banking app is in the foreground, the screenshot includes it.

Can it operate my phone autonomously? With ADB connected, yes. adb shell am start opens any app, and adb shell input tap/swipe/text navigates it. Combined, these can open an app, tap buttons, enter text, and interact with the UI without the user touching the screen.

Can it send data to an external server? By default, Claude Code has access to curl, wget, and other network tools through the Bash tool. The SSRF guard (the optional PreToolUse hook documented in docs/ssrf-guard.md, which blocks WebFetch and WebSearch requests to internal IPs) does not intercept Bash-level network commands. There is no outbound data boundary by default.

Can a malicious MCP server access my data? MCP servers receive tool responses from Claude Code. If Claude Code has access to contacts, SMS, or location data, that data can appear in tool responses sent to any connected MCP server. The SSRF guard does not intercept MCP data flow.

Can a malicious file trick the agent into exfiltrating data? Prompt injection (where a file contains instructions that redirect the agent's behavior) is a known risk with all LLM-based tools. The risk is non-zero. A file could attempt to instruct the agent to send data to an external URL.


Existing Mitigations

MitigationWhat It CoversWhat It Does Not Cover
SSRF guard (docs)Blocks WebFetch and WebSearch requests to private/reserved IP ranges and non-HTTP schemesDoes not block Bash-level curl/wget, does not intercept MCP data flow, does not prevent DNS rebinding
Fingerprint gate (docs)Requires biometric approval before sensitive operations (git push, destructive commands by default)Only gates operations you configure it for. Does not block Termux:API or ADB commands by default
CLAUDE.md constitution (template)Defines behavioral rules the model follows: scope boundaries, forbidden actions, confirmation requirementsModel-enforced, not technically enforced. The model can be instructed to ignore it via prompt injection
Claude's safety trainingAnthropic's safety training makes the model resist harmful instructionsNot a technical control. Effective in most cases but not absolute
Agent permissions matrix (docs)Documents the principle that no agent should hold both web access and write access, and configures per-agent tools/disallowedTools restrictions that Claude Code enforces at runtimeThe split-by-role principle is a design choice you have to apply; once configured, the per-agent tool restrictions are runtime-enforced, but nothing forces you to design the roles that way in the first place

What's Not Covered

These gaps exist by default in the current setup:

  • No Termux:API command restriction. Once a permission is granted, every Termux process can use it. There is no way to allow Claude Code to use the camera but deny it SMS access at the Termux level. This must be done in Android's permission settings for the Termux:API app.
  • No ADB command restriction. Once ADB is connected, the full set of adb shell commands is available. There is no built-in way to allow screencap but deny input injection.
  • No outbound data exfiltration boundary. Claude Code can run curl, wget, or any network command via the Bash tool. There is no default firewall or egress filter preventing data from being sent to external servers.
  • No MCP data boundary. Data flowing to MCP servers is not filtered or restricted. Any data Claude Code can access may appear in MCP tool responses.
  • No session-level tool scoping for interactive use. The --tools and --disallowedTools flags work for headless (claude -p) sessions, but interactive sessions have no runtime tool restriction beyond hooks.

Path A Forces Google DNS for Claude Code's Own Lookups

On Path A (native Termux), the launcher writes a small preload at ~/.local/share/claude/setdns.js and loads it on every launch via BUN_OPTIONS --preload. It calls dns.setServers(["8.8.8.8", "8.8.4.4"]), pointing Claude Code's own DNS lookups at Google's public resolvers. This works around a startup hang where Claude Code's bundled resolver falls back to a dead loopback address and times out (see Troubleshooting).

What this means for you: while Claude Code is running, its name lookups go to 8.8.8.8 / 8.8.4.4 rather than to a VPN, split-tunnel, or Pi-hole resolver you may have configured. For Claude Code's own queries, this overrides that resolver. The rest of your phone keeps using its normal DNS; only Claude Code's lookups are affected, and only on Path A. Paths B and C do not use this preload.

To send Claude Code's lookups to your own nameserver instead, edit the setServers([...]) list in ~/.local/share/claude/setdns.js.


  1. Start without ADB. Path A, Path B, and Path C all work fully without ADB wireless debugging. Only enable ADB when you specifically need screenshot, input injection, or system query capabilities.
  2. Deny unnecessary Termux:API permissions. Go to Android Settings and deny SMS, Contacts, Call Log, Camera, Microphone, and Location for the Termux:API app unless your workflow requires them. Claude Code works normally without any of these.
  3. Install the SSRF guard. It blocks the most common SSRF vector (WebFetch and WebSearch to internal IPs). See SSRF Guard.
  4. Install the fingerprint gate. Configure it to require biometric approval for operations you consider sensitive. See Fingerprint Gate.
  5. Extend the fingerprint gate to cover Termux:API commands (termux-sms-*, termux-contact-*, termux-location, termux-camera-*) and ADB commands (adb shell) if you use them.
  6. Write a CLAUDE.md constitution. Define explicit rules for what the agent may and may not do. See the Constitution Template.
  7. Sandbox headless sessions. If you run claude -p from cron or scripts, use --tools and --disallowedTools to restrict available capabilities. See the install guide cron section.
  8. Do not install untrusted MCP servers. MCP servers receive data from Claude Code's tool responses. Only connect servers you trust.
  9. Disconnect ADB when not using it. Toggle off Wireless Debugging in Developer Options.
  10. Never use ADB wireless debugging on public WiFi. The debugging daemon listens on a network-accessible port. Any device on the same network can attempt to pair.

Last updated: 2026-07-01.