Back to skill

Security audit

QuickBooks Direct

Security checks for vulnerabilities and agentic risk

Overview

This QuickBooks skill is purpose-built, but it needs Review because it can affect real accounting data while storing powerful OAuth secrets in plaintext.

Review this carefully before installing, especially for production QuickBooks companies. Use a sandbox first, do not commit config.json, restrict its permissions, consider replacing plaintext storage with an OS keychain or secret manager, and avoid autoStart until you have reviewed the code and confirmed every state-changing action before it runs.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
run.js:153
Finding

OAuth Login CSRF Due to Fixed and Unvalidated State Parameter

Content
View full analysis
{ const app = express(); const server = app.listen(3001); app.get('/callback', async (req, res) => { try { const code = req.query.code; const realmId = req.query.realmId; ``` ### Technical Analysis OAuth 2.0 authorization-code flows require a cryptographically unpredictable, session-bound `state` value. The application must compare the state returned to the callback with the value generated for the active authorization request. This implementation always sends the fixed value `randomstate`. More importantly, the callback does not read or validate `req.query.state` at all. It accepts any authorization code and realm ID delivered to the local callback endpoint. Consequently, the callback is not bound to the authentication operation initiated by the victim. An attacker who can cause the victim's browser or another locally accessible process to request the callback may inject an authorization response associated with a different QuickBooks account or company. The implementation also fails to validate that `code` and `realmId` are present and correctly formed before exchanging and persisting them. ### Attack Path 1. The attacker learns the application's OAuth client ID and redirect URI. 2. The attacker initiates an Intuit OAuth authorization flow and authorizes access to an attacker-controlled QuickBooks company. 3. The attacker obtains an authorization response intended for `http://localhost:3001/callback`. 4. While the victim's Skill callback server is listening, the ...[truncated 1277 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
run.js:61
Finding

QuickBooks Client Secret and OAuth Tokens Stored in Plaintext Without Enforced File Permissions

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
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (26)

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 · API_REFERENCE.md (reported line 452)May include surrounding context.

md
- **Client ID**: Your QuickBooks app identifier (semi-public)
- **Client Secret**: Your QuickBooks app secret key (SENSITIVE)
- **Access Token**: Short-lived API access token (SENSITIVE)
- **Refresh Token**: Long-lived token for obtaining new access tokens (VERY SENSITIVE)
- **Realm ID**: QuickBooks company identifier (semi-public)

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 · SECURITY.md (reported line 13)May include surrounding context.

md
- **Client ID**: Your QuickBooks app identifier (semi-public)
- **Client Secret**: Your QuickBooks app secret key (SENSITIVE)
- **Access Token**: Short-lived API access token (SENSITIVE)
- **Refresh Token**: Long-lived token for obtaining new access tokens (VERY SENSITIVE)
- **Realm ID**: QuickBooks company identifier (semi-public)

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 · API_REFERENCE.md (reported line 516)May include surrounding context.

md
- **Client ID**: Your QuickBooks app identifier (semi-public)
- **Client Secret**: Your QuickBooks app secret key (SENSITIVE)
- **Access Token**: Short-lived API access token (SENSITIVE)
- **Refresh Token**: Long-lived token for obtaining new access tokens (VERY SENSITIVE)
- **Realm ID**: QuickBooks company identifier (semi-public)

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 · SECURITY.md (reported line 13)May include surrounding context.

md
- **Client ID**: Your QuickBooks app identifier (semi-public)
- **Client Secret**: Your QuickBooks app secret key (SENSITIVE)
- **Access Token**: Short-lived API access token (SENSITIVE)
- **Refresh Token**: Long-lived token for obtaining new access tokens (VERY SENSITIVE)
- **Realm ID**: QuickBooks company identifier (semi-public)

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 · SECURITY.md (reported line 14)May include surrounding context.

md
- **Client ID**: Your QuickBooks app identifier (semi-public)
- **Client Secret**: Your QuickBooks app secret key (SENSITIVE)
- **Access Token**: Short-lived API access token (SENSITIVE)
- **Refresh Token**: Long-lived token for obtaining new access tokens (VERY SENSITIVE)
- **Realm ID**: QuickBooks company identifier (semi-public)

## Risk Assessment

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 · SECURITY.md (reported line 71)May include surrounding context.

md
### 4. Token Management

- **Refresh tokens expire after 100 days of inactivity** - Use regularly or re-authenticate
- **Access tokens expire after 1 hour** - Automatically refreshed by the skill
- If you suspect token compromise, immediately:
  1. Revoke tokens in QuickBooks Developer Portal
  2. Delete `config.json`

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · SECURITY.md (reported line 141)May include surrounding context.

md
3. **Recovery:**
   - Generate new app credentials
   - Update skill with new credentials
   - Re-authenticate
   - Monitor for 30 days

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

Scanner excerpt · SECURITY.md (reported line 167)May include surrounding context.

export QB_CLIENT_ID="your_id" export QB_CLIENT_SECRET="your_secret"

text
Modify skill to read from environment instead of config file

### Option 4: External Secret Management
For enterprise use:

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

The documentation confirms that access and refresh tokens are stored and automatically refreshed, and elsewhere states they are kept in plaintext in config.json along with the client secret. Persistent plaintext credential material for a financial platform creates a strong credential-exposure risk: compromise of the local filesystem or workspace could allow unauthorized API access to accounting data and business operations.

Content

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

md
### Token Management

- **Access tokens** expire after 1 hour (refreshed automatically)
- **Refresh tokens** last 100 days (renewed on refresh)
- The skill automatically refreshes tokens before they expire
- Re-authenticate if you see "Not authenticated" errors

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 · TROUBLESHOOTING.md (reported line 11)May include surrounding context.

md
- [ ] QuickBooks Developer app created
- [ ] Redirect URI matches in app and config
- [ ] Successfully completed OAuth flow
- [ ] Access token not expired

## Common Issues & Solutions

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The changelog makes conflicting security claims: version 1.0.0 states 'secure credential storage' and 'token encryption and storage,' while 1.0.1 explicitly adds warnings about plaintext credential storage in config.json. This inconsistency can mislead operators into believing secrets are protected when they may actually be stored unencrypted, increasing the risk of credential exposure through local compromise, backups, logs, or accidental sharing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The authentication example instructs users to provide a client secret directly in the tool call and states that tokens are saved to a local config.json file, but it gives no guidance on secure secret handling, encryption, file permissions, or avoiding committing credentials to source control. In an API integration skill for financial systems, this can lead to credential leakage, token theft, and unauthorized access to QuickBooks data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

These examples create invoices and send customer emails without clearly warning that the actions are state-changing and may affect real accounting records or contact external recipients. In a QuickBooks integration context, users may run examples verbatim against production data, causing accidental financial entries, customer confusion, and audit/compliance issues.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The later examples include payments, bills, sales receipts, and especially batch operations that can create multiple financial transactions, yet they provide no warning about live side effects or bulk impact. Because this skill operates on accounting systems, accidental execution could rapidly create fraudulent-looking or incorrect ledger entries at scale, making reconciliation and recovery difficult.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
- Search customers with SQL-like queries

### 🧾 Invoice Operations
- Create and manage invoices
- Send invoices via email
- Query invoice history
- Track invoice status

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

md
1. **File Permissions** - Restrict `config.json` to owner read/write only:
   - Windows: Right-click → Properties → Security → Advanced
   - Linux/Mac: `chmod 600 config.json`

2. **Never Commit Credentials** - Ensure `config.json` is in `.gitignore`

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SECURITY.md (reported line 44)May include surrounding context.

Linux/Mac:

bash
# Set to owner read/write only
chmod 600 config.json

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SECURITY.md (reported line 45)May include surrounding context.

Linux/Mac:

bash
# Set to owner read/write only
chmod 600 config.json

2. Storage Location

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
## Overview

This skill enables OpenClaw to interact with QuickBooks Online for:
- **Customer & Vendor Management**: Create and manage business relationships
- **Invoicing**: Generate, send, and track invoices
- **Payments**: Record and reconcile payments
- **Inventory**: Manage products, services, and stock levels

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill exposes authentication and high-impact financial operations with examples that encourage users to provide client credentials and perform live accounting actions, but it does not consistently present prominent warnings, confirmation requirements, or safe-by-default guidance at the point of use. In an agent context, this increases the risk of accidental disclosure of secrets or unintended business transactions because the skill is designed to automate sensitive actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The troubleshooting guide instructs users to delete config.json as part of token recovery without warning that this file likely contains OAuth credentials, refresh tokens, and other configuration needed to reconnect. While not malicious, this is unsafe operational guidance because it can cause credential loss, unnecessary re-authentication, and accidental disruption if users delete the wrong file or have unsaved changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The guide recommends forcefully terminating whatever process is bound to port 3000 using Stop-Process/taskkill without telling users to verify that the PID belongs to this skill. That can disrupt unrelated applications or local services, especially on shared developer machines, and encourages broad destructive action as a quick fix.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The 'Reset Everything' section instructs users to delete node_modules and config.json without warning about loss of saved credentials, tokens, or local configuration. In a troubleshooting document, this kind of blanket destructive reset is risky because users may follow it under pressure and erase recoverable state unnecessarily.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill persists highly sensitive material including the QuickBooks client secret, access token, and refresh token to a local config.json file in plaintext. If the host is multi-user, the workspace is synced/backed up, or another process can read the file, an attacker could reuse those credentials to access or maintain access to the QuickBooks tenant, with the refresh token enabling long-lived compromise.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The authentication handler sends the QuickBooks client ID, client secret, and authorization code to Intuit's token endpoint, which is a sensitive network operation involving credentials. This file contains no user-facing notice, prompt, or warning explaining that supplied secrets will be transmitted to external services.

Content

No source excerpt is available for this finding.