Back to skill

Security audit

Kimai Time Tracking

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Kimai integration, but it overstates its capabilities and handles a powerful API token with safeguards users should review.

Install only if you are comfortable granting a Kimai API token to this CLI. Use a dedicated least-privilege token, set KIMAI_BASE_URL only to a trusted HTTPS Kimai host, avoid administrator tokens, and be careful with delete commands, especially --force. Expect some documented commands and safety features to be missing unless the skill is updated.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/kimai_cli.py:25
Finding
Bearer Token Exposure Through Unvalidated Transport and Cross-Origin Redirects<![CDATA[ ## Vulnerability Details **File Location**: `scripts/kimai_cli.py`, lines 25–47 **Vulnerability Type**: Bearer credential exposure through insecure transport and unrestricted redirects **Risk Level**: Medium ### Vulnerable Code ```python class KimaiClient: def __init__(self, base_url: str, token: str): self.base_url = base_url.rstrip('/') self.token = token self.headers = { 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json', 'Accept': 'application/json' } def _request(self, method: str, endpoint: str, data: Optional[Dict] = None, params: Optional[Dict] = None) -> Any: """Make HTTP request to Kimai API""" url = f"{self.base_url}/api/{endpoint}" if params: query = '&'.join(f"{k}={v}" for k, v in params.items() if v is not None) if query: url += f"?{query}" try: req = urllib.request.Request( url, data=json.dumps(data).encode() if data else None, headers=self.headers, method=method ) with urllib.request.urlopen(req) as response: ``` The related configuration is documented at `SKILL.md`, lines 29–33: ```markdown **Required Environment Variables:** - `KIMAI_BASE_URL` - Full URL to Kimai instance (e.g., `https://kimai.example.com`) - `KIMAI_API_TOKEN` - Bearer token for authentication ``` ### Technical Analysis The client obtains `KIMAI_BASE_URL` from the environment and uses it directly without validating its URL scheme or destination. Every API request includes the Kimai token in the `Authorization` header. Although the documentation gives an HTTPS example, the implementation does not require HTTPS. If the configured URL uses `http://`, the bearer token, timesheet details, customer information, and other request data are transmitted without transport encryption. An attacker a ...[truncated 2933 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Require HTTPS by default** - Parse `KIMAI_BASE_URL` with `urllib.parse.urlparse()`. - Reject every scheme other than `https`. - If local HTTP development is necessary, require an explicit opt-in flag and restrict it to loopback destinations such as `localhost`, `127.0.0.1`, or `::1`. 2. **Enforce a redirect origin boundary** - Disable redirects for authenticated API requests, or implement a custom `HTTPRedirectHandler`. - Reject redirects that change the scheme, hostname, or effective port. - Never forward `Authorization` to a different origin. - Reject HTTPS-to-HTTP downgrade redirects in all cases. 3. **Validate endpoint configuration** - Reject URLs containing embedded credentials. - Require a valid hostname and disallow ambiguous or unsupported URL forms. - Consider an explicit hostname allowlist for managed deployments. 4. **Limit credential exposure** - Use a dedicated Kimai API token with only the permissions needed for the requested operations. - Avoid using an administrator token for ordinary time-tracking commands. - Separate read-only, write, and administrative workflows when practical. 5. **Harden request behavior** - Add finite connection and read timeouts to avoid indefinitely blocked operations. - Return generic network errors where possible and avoid exposing sensitive server response content. - Document certificate verification requirements and do not add options that disable TLS verification. 6. **Update the Skill documentation** - State that HTTPS is mandatory except for explicitly enabled loopback development. - Warn users that `KIMAI_BASE_URL` controls where the token and Kimai records are transmitted. - Recommend token rotation immediately after suspected endpoint or network compromise. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (21)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The code is clearly related to Kimai time-tracking and does implement substantial matching functionality: timesheets, customers, projects, activities, timer workflows, and basic administrative/system queries. However, the declared description materially overstates coverage by calling it a 'Complete Kimai time-tracking API integration' and explicitly listing management of teams, invoices, and exports plus reporting support. None of those areas appear in the supplied code chunk. This is not an undeclared malicious or unrelated capability; instead, it is a description-to-behavior overclaim significant enough to be a mismatch because the primary stated scope includes multiple major API domains absent from the implementation.

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
./scripts/kimai_cli.py timesheets recent
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill explicitly relies on environment variables and internet access to call a remote API, but it does not declare a corresponding tool scope such as allowed-tools or permissions. That creates an authorization and transparency gap: an agent may be able to access secrets and perform network operations without an explicit, reviewable capability boundary.

Session Persistence

Medium
Category
Rogue Agent
Content
- Start/stop/restart time tracking (timers)
- List, filter, or export timesheets
- Manage customers, projects, or activities
- Create invoices or export data
- Administrative tasks (users, teams, rates)
- Query system status (version, plugins, config)
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.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
ts_del = ts_sub.add_parser('delete', help='Delete timesheet')
    ts_del.add_argument('id', type=int)
    ts_del.add_argument('--force', action='store_true', help='Skip confirmation')

    # Customers
    cust_parser = subparsers.add_parser('customers', help='Customer management')
Confidence
85% 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.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
ts_del = ts_sub.add_parser('delete', help='Delete timesheet')
    ts_del.add_argument('id', type=int)
    ts_del.add_argument('--force', action='store_true', help='Skip confirmation')

    # Customers
    cust_parser = subparsers.add_parser('customers', help='Customer management')
Confidence
85% 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.

Static analysis

No suspicious patterns detected.