Back to skill

Security audit

xero quickbooks invoicing payments uk b2b accounting freelance

Security checks for vulnerabilities and agentic risk

Overview

This invoice-chasing skill has a coherent business purpose, but it asks the agent to handle accounting, email, and customer financial data with broad permissions and weakly defined storage controls.

Review carefully before installing. Use a dedicated accounting app/account and sender mailbox, avoid pasting real secrets into chat unless the host provides an encrypted credential vault, keep approval required for all sends, verify recipient data before enabling automation, and define retention/deletion rules for customer and payment history.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
CONFIG.md:18
Finding

Secrets Are Collected Through Agent Conversations and Persisted in Generic Memory

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:768
Finding

Sensitive Customer and Financial Records Are Retained Indefinitely in Agent Memory

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
CONFIG.md:123
Finding

Default Integration Setup Requests Permissions Beyond the Core Monitoring Workflow

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (24)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · CONFIG.md (reported line 159)May include surrounding context.

md
## Troubleshooting

**"Xero 401 Unauthorized"**
→ Access token expired. The skill auto-refreshes — if this persists, your
refresh token may have expired (60 days of inactivity). Re-authenticate:
send your bot "reconnect Xero" and follow the OAuth flow again.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
## Troubleshooting

**"Xero 401 Unauthorized"**
→ Access token expired. The skill auto-refreshes — if this persists, your
refresh token may have expired (60 days of inactivity). Re-authenticate:
send your bot "reconnect Xero" and follow the OAuth flow again.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
## Troubleshooting

**"Xero 401 Unauthorized"**
→ Access token expired. The skill auto-refreshes — if this persists, your
refresh token may have expired (60 days of inactivity). Re-authenticate:
send your bot "reconnect Xero" and follow the OAuth flow again.

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The skill instructs storage of Xero client secrets and OAuth tokens in memory, which creates a concentrated credential target if memory is exposed, logged, or accessible to other skills/components. Compromise of these values grants access to financial records and potentially write capabilities in the accounting platform.

Content

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

md
ACCOUNTING_PLATFORM      # xero | quickbooks | both
XERO_CLIENT_ID           # From your Xero app — developer.xero.com/app/manage
XERO_CLIENT_SECRET       # From your Xero app — keep secret, never expose
XERO_ACCESS_TOKEN        # OAuth access token — fetched automatically, auto-refreshed
XERO_REFRESH_TOKEN       # OAuth refresh token — stored securely, never shown
XERO_TENANT_ID           # Xero organisation ID — fetched automatically after auth
QB_CLIENT_ID             # From your QuickBooks app — developer.intuit.com

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The same risk applies to QuickBooks credentials and tokens: storing them in ordinary memory exposes high-value authentication material beyond the minimum necessary boundary. An attacker or unrelated component with memory access could impersonate the business and access or alter accounting data.

Content

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

md
XERO_TENANT_ID           # Xero organisation ID — fetched automatically after auth
QB_CLIENT_ID             # From your QuickBooks app — developer.intuit.com
QB_CLIENT_SECRET         # From your QuickBooks app — keep secret, never expose
QB_ACCESS_TOKEN          # QuickBooks OAuth access token — auto-refreshed
QB_REFRESH_TOKEN         # QuickBooks OAuth refresh token — stored securely
QB_REALM_ID              # QuickBooks company ID — fetched automatically after auth

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

STRIPE_PAYMENT_LINK # Your Stripe payment link URL (if PAYMENT_LINK_ENABLED = true)

text

Never log or repeat access tokens or refresh tokens back to the user.

### Token refresh
Both Xero and QuickBooks OAuth tokens expire after 30 minutes (access token) and

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Automatically refreshing access tokens using a stored refresh token before each API call implies persistent handling of sensitive bearer credentials inside the skill runtime. If the refresh token is exposed, an attacker can mint new access tokens repeatedly and maintain unauthorized accounting access.

Content

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

md
Never log or repeat access tokens or refresh tokens back to the user.

### Token refresh
Both Xero and QuickBooks OAuth tokens expire after 30 minutes (access token) and
60 days (refresh token). The skill automatically refreshes access tokens using the
stored refresh token before each API call. If the refresh token has expired (after
60 days of inactivity), prompt the user to re-authenticate via CONFIG.md.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The design relies on long-lived refresh tokens retained across runs, creating durable credential persistence risk. A stolen refresh token provides ongoing access well beyond a single session, making compromise materially more severe than transient access-token exposure.

Content

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

md
### Token refresh
Both Xero and QuickBooks OAuth tokens expire after 30 minutes (access token) and
60 days (refresh token). The skill automatically refreshes access tokens using the
stored refresh token before each API call. If the refresh token has expired (after
60 days of inactivity), prompt the user to re-authenticate via CONFIG.md.

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The token refresh flow includes submitting client secret and refresh token material as part of OAuth exchange operations. While normal protocol behavior, in the context of this skill it confirms active handling of raw high-value secrets, which is dangerous if implemented through prompt-visible memory or logs.

Content

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

Step 1 — Fetch invoices from Xero

Refresh access token if needed:

text
POST https://identity.xero.com/connect/token
Content-Type: application/x-www-form-urlencoded

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The QuickBooks refresh flow similarly requires raw credential material, including a Basic authorization value derived from client ID and secret plus the refresh token. Exposure of any of these values can enable unauthorized token minting and access to the company's accounting environment.

Content

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

Step 2 — Fetch invoices from QuickBooks (if configured)

Refresh QBO access token:

text
POST https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer
Authorization: Basic {base64(QB_CLIENT_ID:QB_CLIENT_SECRET)}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The guide instructs users to paste OAuth client secrets directly into the bot chat, creating an unnecessary credential exposure path. Even if the document claims secrets are stored 'securely in memory,' there is no warning about chat logging, retention, access controls, or safer alternatives, so compromise of the bot, logs, or operator environment could expose accounting platform credentials.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · CONFIG.md (reported line 33)May include surrounding context.

After authentication, the skill fetches your Xero organisation ID automatically:

text
GET https://api.xero.com/connections

If you have multiple Xero organisations, it will ask which to use.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

After authentication, the skill fetches your Xero organisation ID automatically:

text
GET https://api.xero.com/connections

If you have multiple Xero organisations, it will ask which to use.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

After authentication, the skill fetches your Xero organisation ID automatically:

text
GET https://api.xero.com/connections

If you have multiple Xero organisations, it will ask which to use.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

After authentication, the skill fetches your Xero organisation ID automatically:

text
GET https://api.xero.com/connections

If you have multiple Xero organisations, it will ask which to use.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The email setup section asks the user to send an email app password to the bot and encourages credential reuse if already configured. This grants access to a mailbox and outbound email capability, which could enable account compromise, data exposure, phishing, or unauthorized sending if the bot or its logs are accessed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README promotes automated email and WhatsApp chasing tied to accounting data, but does not explicitly warn that customer contact details, invoice status, balances, and message content may be transmitted to third-party communication providers. In a debt-collection context, automated outreach to real customers raises privacy, consent, and misdelivery risks, and can cause unauthorized or inappropriate contact if configuration or recipient selection is wrong.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The document states that all correspondence will be in UK English, which imposes a language/locale choice unconditionally. This is a natural-language policy issue unless the skill offers the user a language choice or clearly documents a justified region-specific constraint with opt-in.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
95% confidence
Finding

The skill defaults CHASE_ENABLED to true, allowing the system to send debt-collection communications on schedule automatically. Autonomous external messaging based on invoice state can misfire on stale data, disputes, or wrong recipients, causing harassment, privacy incidents, and legal/commercial harm.

Content

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

md
PAYMENT_TERMS_DAYS       # Default: 30 (days after invoice date payment is due)
CURRENCY                 # Default: GBP

CHASE_ENABLED            # Default: true — automatically send chase emails on schedule
APPROVAL_REQUIRED        # Default: true — owner approves each chase before sending
WHATSAPP_CHASE_THRESHOLD # Default: £500 — chase via WhatsApp for invoices above this
STOP_CHASE_ON_DISPUTE    # Default: true — pause chasing if dispute flag is set

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill enables automated outbound email and WhatsApp contact to third-party customer details by default, but does not require an explicit upfront consent/confirmation flow before external communications begin. Because these messages can affect customer relationships, send legal/payment demands, and disclose billing context, unintended or misconfigured sends create privacy, compliance, and reputational risk.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
88% confidence
Finding

Persisting detailed chase logs in memory creates a durable record of customer names, invoice numbers, payment amounts, communication timing, and collection activity. If memory is accessible to other skills, operators, or logs, this becomes a privacy and business-sensitivity exposure with long retention value to an attacker.

Content

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

After sending each chase:

  • Update chase_stage and last_chased in invoice_chase_queue
  • Add entry to chase_log:
json
{
  "invoice_id": "{id}",

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
- 💰 invoice summary · 📧 chase email · ✅ paid · ⏸️ paused · 🔴 final demand · 📊 report · ⚠️ alert
- Always show amount in £ — never raw numbers without currency
- For Stage 4 (final demand), always flag as needing owner attention — never auto-send
  without approval regardless of APPROVAL_REQUIRED setting
- When a payment comes in: celebrate it briefly — "✅ £2,100 received from Metro Retail!"
- When reporting aged debtors: be matter-of-fact, not alarming — state the facts and
  suggest next action

Scope Creep

Low
Category
Excessive Agency
Confidence
70% confidence
Finding

Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Content

Scanner excerpt · README.md (reported line 43)May include surrounding context.

md
UK-focused: Late Payment of Commercial Debts Act 1998 awareness built in. Statutory
interest calculation included. All correspondence in UK English.

Not limited to product sellers — works for any UK business that invoices clients:
freelancers, agencies, consultants, tradespeople, and service businesses.

---

Scope Creep

Low
Category
Excessive Agency
Confidence
70% confidence
Finding

Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Content

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

md
UK-focused: Late Payment of Commercial Debts Act 1998 awareness built in. Statutory
interest calculation included. All correspondence in UK English.

Not limited to product sellers — works for any UK business that invoices clients:
freelancers, agencies, consultants, tradespeople, and service businesses.

---

Static analysis

No suspicious patterns detected.