Back to skill

Security audit

Qirabot

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed GUI automation skill with real control and privacy risks, but the inspected artifacts are coherent with that purpose and do not show hidden or malicious behavior.

Install and run this only for UI automation tasks where you are comfortable letting Qirabot view and act on the target screen. Use a virtual environment, consider pinning package versions yourself, avoid exposing privileged accounts, keep persistent browser profiles per site/task, and require explicit approval before purchases, posts, deletes, account changes, or other irreversible actions.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:31
Finding

Unpinned Third-Party Dependencies Create a Supply-Chain Execution Risk

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description centers on GUI automation, but the skill content also performs local environment validation, dependency inspection, executable discovery, API key checks, and device enumeration. That hidden operational surface matters because users or reviewers may approve it expecting UI automation only, while it also probes the host system and connected devices.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill explicitly instructs the agent to run shell commands and rely on environment variables, but it declares no tool/permission scope. That mismatch can cause an orchestrator to invoke a skill with broader execution capability than reviewers or policy expect, increasing the risk of unintended command execution and environment inspection.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger text is very broad (automate, scrape, click, verify what's on screen, desktop application, etc.), making accidental invocation more likely in contexts where users did not intend to authorize a high-capability automation skill. For a skill that can drive browsers, apps, and shell-assisted setup, overbroad routing increases the chance of misuse or surprise execution.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
78% confidence
Finding

The skill encourages high-level goal delegation to bot.ai and later documents reuse of authenticated persistent profiles across runs. In combination, this can let an autonomous agent act inside an existing logged-in session and perform consequential user actions if confirmation boundaries are missed or bypassed.

Content

Scanner excerpt · SKILL.md (reported line 86)May include surrounding context.

md
**Keep the task string a concise goal, not a step-by-step script.** `bot.ai` is
smart enough to plan its own clicks — over-specifying ("click Search, then type
X, then click the first result, then…") fights the model, locks in a brittle
path, and burns extra steps. Write what success looks like, not how to get
there. Good: `"Add the cheapest in-stock item to the cart and check out"`.
Bad: a 6-step click-by-click recipe.

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · references/REFERENCE.md (reported line 80)May include surrounding context.

AI-located actions (one model call each)

python
bot.click(target, locate, *, timeout=0.0, interval=2.0, wait="", model_alias="", language="")
bot.type_text(target, locate, text, *, press_enter=False, clear_before_typing=False, timeout=0.0, ...)
bot.double_click(target, locate, ...)
bot.long_press(target, locate, *, duration=2.0, timeout=0.0, ...)  # Appium/Airtest mobile only

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · references/REFERENCE.md (reported line 81)May include surrounding context.

AI-located actions (one model call each)

python
bot.click(target, locate, *, timeout=0.0, interval=2.0, wait="", model_alias="", language="")
bot.type_text(target, locate, text, *, press_enter=False, clear_before_typing=False, timeout=0.0, ...)
bot.double_click(target, locate, ...)
bot.long_press(target, locate, *, duration=2.0, timeout=0.0, ...)  # Appium/Airtest mobile only

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · references/REFERENCE.md (reported line 83)May include surrounding context.

AI-located actions (one model call each)

python
bot.click(target, locate, *, timeout=0.0, interval=2.0, wait="", model_alias="", language="")
bot.type_text(target, locate, text, *, press_enter=False, clear_before_typing=False, timeout=0.0, ...)
bot.double_click(target, locate, ...)
bot.long_press(target, locate, *, duration=2.0, timeout=0.0, ...)  # Appium/Airtest mobile only

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

The documentation explicitly recommends persistent Chromium profiles to retain cookies and login state across runs. In the context of a GUI automation skill, that increases the chance of long-lived sensitive session material being stored on disk where other local users, malware, or later automations could reuse it, especially if the profile path is shared, weakly permissioned, or used for high-privilege accounts.

Content

Scanner excerpt · references/REFERENCE.md (reported line 149)May include surrounding context.

md
import os
# Pass an ABSOLUTE path: qirabot forwards user_data_dir straight to Playwright's
# launch_persistent_context, and neither expands "~". A literal "~/..." would
# create a "./~/" dir in the CWD — always wrap with os.path.expanduser.
page = bot.open(url, user_data_dir=os.path.expanduser("~/.qira-profiles/<site>"))
if not bot.verify(page, "the user is logged in (avatar shown, no Login button)"):
    ...  # first run only: do the login (e.g. QR scan), then it sticks

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/preflight.py (reported line 126)May include surrounding context.

python
hard_ok = hard_ok and bool(adb)
        if adb:
            try:
                out = subprocess.run([adb, "devices"], capture_output=True,
                                     text=True, timeout=10).stdout
                devs = [ln for ln in out.splitlines()[1:] if ln.strip() and "\tdevice" in ln]
                line(OK if devs else NO, f"Android device connected ({len(devs)})",

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The reference states language defaults to "en", which establishes a specific language/locale behavior by default. Under the policy, forcing a language without explicit user choice or opt-in can be a natural-language policy concern unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

This code template includes direct handling of a sensitive credential via the QIRA_API_KEY environment variable, but provides no user-facing warning or guidance about protecting the key. Under the code-file criteria, access to sensitive environment variables should have some disclosure through comments, prompts, or documentation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.