T01 · Skill Instruction Hijacking
- Location
scripts/analyze.py:143- Finding
Untrusted Android Source Code Is Embedded Directly into the LLM Prompt
- Content
View full analysis
Vulnerability Details
File Location:
scripts/analyze.py, lines 143–149 and 202–204; prompt output occurs at line 249
Vulnerability Type: Prompt injection through untrusted source-code content
Risk Level: HighVulnerable Code
python source_text = '\n\n'.join( f'// === {name} ===\n{code}' for name, code in source_code.items() ) prompt = f"""你是一个资深 Android 测试专家。请仔细阅读以下 Android 应用源码(包名:{app_package}),输出一份供 AI 自动化测试 Agent 直接使用的**测试先验知识**。 # ... prompt instructions omitted ... ## 源码 {source_text}""" return promptThe resulting prompt is subsequently emitted for processing by the agent:
python print("--- LLM_PROMPT ---") print(prompt)Technical Analysis
The analyzer treats Kotlin and Java source files as trusted prompt content.
source_textis interpolated verbatim into the same instruction message that defines the LLM's role, analysis goals, and required output format.There is no security boundary distinguishing trusted analyzer instructions from untrusted project content. The prompt also does not instruct the model to treat source-file text exclusively as evidence or to ignore instructions appearing inside it.
Although
read_source_files()removes certain empty and comment-only lines, this does not prevent prompt injection. An attacker can place natural-language instructions in string literals, annotations, multiline strings, identifiers, or ordinary code lines that survive filtering.This permits indirect prompt injection: a malicious Android project can attempt to override the analysis instructions, suppress or fabricate findings, violate the required JSON format, or insert attacker-selected content into the generated static profile.
Attack Path
- An attacker creates or modifies a Kotlin or Java file in the Android project.
- The attacker embeds an instruction such as a request to ignore the analyzer's prior requirements and emit attacker-controlled profile content.
find_kotlin_files()di ...[truncated 1506 chars]
- Remediation
View remediation
Remediation Suggestions
-
Separate trusted instructions from source data
- Submit analyzer policy in a trusted system or developer message.
- Place source code in a distinct structured input field or user-data attachment rather than interpolating it into the instruction body.
-
Explicitly classify project content as untrusted
- Tell the model that all source text is evidence only.
- State that instructions, requests, role declarations, or output directives found in source files must never be followed.
-
Use strong content boundaries
- Wrap each source file in clearly identified data blocks.
- Use dynamically generated delimiters and ensure project content cannot terminate or imitate the boundary.
- Include the canonical relative path and a content hash for provenance.
-
Validate generated output
- Parse the response strictly as JSON.
- Validate it against an authoritative JSON Schema.
- Reject extra fields, non-JSON prefixes or suffixes, invalid priority values, and instruction-like content in fields intended to hold factual data.
-
Constrain downstream use
- Treat generated summaries and profiles as untrusted data when consumed by another agent.
- Do not place generated free text into privileged instruction messages.
- Require user review before generated artifacts influence actions with side effects.
-
Use deterministic analysis where possible
- Extract manifests, navigation edges, identifiers, permissions, and hardcoded constants using parsers.
- Reserve LLM processing for semantic interpretation and require claims to reference source locations.
-
Add adversarial tests
- Test payloads in Kotlin strings, Java annotations, multiline literals, identifiers, and code statements.
- Confirm that embedded instructions cannot alter the output format, role, or analysis policy.
-
