Back to skill

Security audit

Rag based on Google drive

Security checks for vulnerabilities and agentic risk

Overview

This skill is purpose-aligned for a Google Drive RAG tool, but it handles personal document access tokens and document queries with weak scoping and unsafe credential handling.

Review before installing. Only use this with an API_URL you fully trust, preferably HTTPS on a known service domain, and treat the JWT as a secret that can access your indexed personal documents. Avoid putting highly sensitive documents in the index unless you are comfortable with the RAG API processing them. Pin dependencies, restrict .env permissions, and require confirmation before token renewal or sync operations.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
cli.py:8
Finding

Unrestricted API endpoint can receive bearer credentials and sensitive document queries

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
cli.py:211
Finding

JWT credentials are stored in plaintext and renewed tokens are exposed through standard output

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Runtime installation uses unpinned and unhashed dependencies

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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (24)

Tainted flow: 'base_url' from os.getenv (line 11, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · cli.py (reported line 50)May include surrounding context.

python
def cmd_service_account(base_url, token):
    print("Fetching service account information...")
    try:
        response = requests.get(f"{base_url}/service-account", headers=get_headers(token))
        response.raise_for_status()
        data = response.json()
        print(f"\\n✅ Service Account Email: {data.get('service_account_email')}")

Tainted flow: 'payload' from os.getenv (line 24, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · cli.py (reported line 64)May include surrounding context.

python
print(f"Adding folder '{folder_name}' to tracked RAG indexes...")
    try:
        payload = {"folder_name": folder_name}
        response = requests.post(f"{base_url}/add-folder", headers=get_headers(token), json=payload)
        response.raise_for_status()
        data = response.json()
        print("\\n✅ Success!")

Tainted flow: 'payload' from os.getenv (line 24, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · cli.py (reported line 83)May include surrounding context.

python
try:
        payload = {"force": force}
        response = requests.post(f"{base_url}/sync", headers=get_headers(token), json=payload)
        response.raise_for_status()
        data = response.json()
        print("\\n✅ Success!")

Tainted flow: 'payload' from os.getenv (line 24, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · cli.py (reported line 104)May include surrounding context.

python
if folder_names:
            payload["folder_names"] = folder_names
            
        response = requests.post(f"{base_url}/search", headers=get_headers(token), json=payload)
        response.raise_for_status()
        data = response.json()

Tainted flow: 'base_url' from os.getenv (line 11, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · cli.py (reported line 141)May include surrounding context.

python
def cmd_status(base_url, token):
    print("Fetching ingestion status for your account...")
    try:
        response = requests.get(f"{base_url}/status", headers=get_headers(token))
        response.raise_for_status()
        data = response.json()

Tainted flow: 'base_url' from os.getenv (line 11, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · cli.py (reported line 171)May include surrounding context.

python
def cmd_list_files(base_url, token):
    print("Fetching tracked files from database...")
    try:
        response = requests.get(f"{base_url}/list-files", headers=get_headers(token))
        response.raise_for_status()
        data = response.json()

Tainted flow: 'payload' from os.getenv (line 24, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · cli.py (reported line 206)May include surrounding context.

python
print("Requesting a new token from the server...")
    try:
        payload = {"expires_in_days": int(days)}
        response = requests.post(f"{base_url}/renew-token", headers=get_headers(token), json=payload)
        response.raise_for_status()
        data = response.json()
        print("\n✅ Success! New token generated.")

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · cli.py (reported line 13)May include surrounding context.

python
base_url = os.getenv("API_URL")
    if not base_url:
        print("Error: API_URL not found in .env file.")
        sys.exit(1)
        
    token = token_override if token_override else os.getenv("JWT_TOKEN")

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · cli.py (reported line 40)May include surrounding context.

python
base_url = os.getenv("API_URL")
    if not base_url:
        print("Error: API_URL not found in .env file.")
        sys.exit(1)
        
    token = token_override if token_override else os.getenv("JWT_TOKEN")

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The code outputs the full newly issued token to the terminal, which is direct credential exposure. In this skill context, the token protects access to personal Google Drive RAG data and management actions, so leakage could let another party search documents, inspect tracked files, or trigger account operations.

Content

Scanner excerpt · cli.py (reported line 214)May include surrounding context.

python
print(f"Expires at: {data.get('expires_at')}")
        print("\nNEW_TOKEN:")
        print(data.get('token'))
        print("\nPlease update your .env file with this new token.")
    except requests.exceptions.RequestException as e:
        print(f"\n❌ Error renewing token: {e}")
        if e.response is not None:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · cli.py (reported line 222)May include surrounding context.

python
def main():
    parser = argparse.ArgumentParser(description="Google Drive RAG CLI")
    parser.add_argument("-t", "--token", help="Override JWT token from .env")
    
    subparsers = parser.add_subparsers(dest="command", help="Available commands", required=True)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill invokes local environment access, package installation, and network-backed CLI operations but declares no explicit tool scope or permission boundary. That makes the operational surface larger and less auditable, increasing the chance an agent executes sensitive actions without clear user understanding or policy enforcement.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill description frames the feature as searching synced personal documents but does not clearly disclose that sync and search send document-derived data to an external RAG API. Users may unknowingly authorize processing of sensitive personal files by a third-party service without informed consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs the agent to collect API_URL and JWT_TOKEN and persist them to a local .env file without warning about credential sensitivity, file permissions, or persistence risks. This can expose bearer tokens to other local processes, backups, logs, or future sessions if the file is not protected.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

The skill directs persistent storage of API configuration and JWT credentials in ~/.agents/skills/driverag/.env, creating session persistence for sensitive authentication material. Persisted secrets broaden the attack window because they remain available across sessions and may be accessible to other tools, users, or backups on the host.

Content

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

md
Before running any commands, you MUST verify the environment is set up:
1. Check if `~/.agents/skills/driverag/.env` exists. 
   - If it DOES NOT exist, you MUST ask the user to provide their `API_URL` and `JWT_TOKEN`.
   - Once they provide them, create the `.env` file in the skill directory (`~/.agents/skills/driverag/.env`) with those values.
2. Check if the virtual environment exists (`~/.agents/skills/driverag/venv`). 
   - If it DOES NOT exist, create it: `cd ~/.agents/skills/driverag && python3 -m venv venv`
   - Then install the requirements: `source venv/bin/activate && pip install -r requirements.txt`

Ssd 3

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs the agent to return exact search results and citations from personal documents without any redaction, sensitivity checks, or least-disclosure controls. This increases the risk of exposing highly sensitive information such as IDs, insurance details, financial data, or private document names in the conversation output.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
88% confidence
Finding

The instruction to automatically run renew-token after a 401 or expiry warning authorizes a state-changing credential-management action without obtaining fresh user approval. Autonomous token renewal can surprise users, modify stored credentials, and normalize background handling of secrets beyond the original request.

Content

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

md
## Important notes
- Do NOT hallucinate answers. ALWAYS run the `cli.py search` command to get the exact answer from the RAG system and output the exact response it gives you.
- CRITICAL: If the user asks "What files do you have", "List my files", or "What documents are in the database", DO NOT use the search command! You MUST use the `list-files` command instead, because RAG semantic search cannot generate file lists.
- If the CLI returns a 401 Unauthorized or warns that the token is about to expire, inform the user and automatically run the `renew-token` command to update their `.env` file.
- When outputting the RAG search results to the user, ensure you include the citations/source documents exactly as the CLI returns them so the user knows where the information came from.

## Examples

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 · cli.py (reported line 23)May include surrounding context.

python
try:
            import jwt
            from datetime import datetime, timezone
            # Decode without verification just to read the expiration claim
            payload = jwt.decode(token, options={"verify_signature": False})
            exp = payload.get("exp")
            if exp:

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The CLI implements materially broader capabilities than the stated skill description, including sync, status, file listing, and token renewal. Capability drift is dangerous because users and reviewers may grant trust based on the manifest while the code can perform additional sensitive operations against personal document infrastructure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The renew-token command prints a freshly issued authentication token directly to stdout, where it can be captured by terminal logging, shell history tools, CI logs, screen recording, or shoulder-surfing. Because the token grants API access to personal document operations, disclosure can enable unauthorized access until expiry.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
96% confidence
Finding

The dependency requests is unpinned, which makes builds non-reproducible and can cause the environment to resolve to an unexpectedly vulnerable or breaking release. In a skill that interacts with Google Drive and personal documents, a networking library upgrade or downgrade could expose the agent to known client-side issues or operational instability without any code change in the skill itself.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests
python-dotenv

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
83% confidence
Finding

requests has multiple known advisories, and because no version is pinned, there is no way to verify that the installed release is not affected. This is more concerning in this skill's context because requests is a network-facing library and the skill accesses personal document infrastructure, so client-side request handling flaws could contribute to credential leakage, SSRF-like behavior, or insecure transport validation depending on the resolved version and usage.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency python-dotenv is also unpinned, so installation may pull different versions over time, including versions with security defects or incompatible behavior. Because this skill likely loads credentials or configuration from environment files, variation in python-dotenv behavior can directly affect secret handling and local file safety.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
requests
python-dotenv

Unverifiable Dependency: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
80% confidence
Finding

python-dotenv has known advisories and the unpinned requirement prevents verification that a safe version will be installed. Given this skill's use of service accounts and local configuration, flaws in .env parsing or file-handling behavior could affect secrets exposure or unsafe file writes if a vulnerable release is resolved.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.