T09 · Insecure Skill Coding Practices
- Location
attio_client.py:214- Finding
Broken Pagination Causes Unbounded API Requests and Memory Consumption
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a real Attio CRM client, but it gives an agent broad read/write/delete access with weak scoping and no delete safeguard.
Install only if you are comfortable giving this skill a dedicated, least-privilege Attio API key. Treat it as capable of broad Attio reads and writes, verify record IDs before any update or delete, avoid autonomous use of deletion, and avoid --all on large objects until pagination is fixed.
attio_client.py:214Broken Pagination Causes Unbounded API Requests and Memory Consumption
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
request.data = json.dumps(data).encode("utf-8")
try:
with urlopen(request, timeout=timeout) as response:
body = response.read().decode("utf-8")
if body:
return json.loads(body)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Copy the env template:
cp .env.example .env
Add your API key:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# Edit .env and replace with your key
ATTIO_API_KEY="your-key-here"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
3. **Add your API key:**
```bash
# Edit .env and replace with your key
ATTIO_API_KEY="your-key-here"
```
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
3. **Add your API key:**
```bash
# Edit .env and replace with your key
ATTIO_API_KEY="your-key-here"
```
The declared behavior limits the skill to companies, people, and notes, but the implementation reportedly supports broader Attio resources and arbitrary raw endpoint access. This mismatch is dangerous because users may authorize the skill believing it has narrow CRM functionality while it can access or modify additional data types and endpoints.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
## Setup
1. Get API key from https://app.attio.com/settings/api
2. Copy `.env.example` to `.env` and add your key
## Quick Commands
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
API_KEY = os.environ.get("ATTIO_API_KEY", "")
if not API_KEY:
# Fallback: read from .env file
env_path = os.path.join(os.path.dirname(__file__), ".env")
if os.path.exists(env_path):
with open(env_path) as f:
for line in f:
This markdown file describes a --delete option for removing records, but it does not include any user warning about deletion risk, reversibility, or need for confirmation. For markdown files, omission of warnings about behaviors that could affect user data or system integrity should be flagged.
The skill declares access to environment credentials and uses networked API access, but it does not specify any tool/permission scope. In an agent setting, missing explicit scope increases the chance the skill can be invoked with broader capabilities than users expect, especially because it uses a direct API key and remote CRUD operations.
The setup instructions tell users to place an API key directly into a local environment file without emphasizing its sensitivity or handling requirements. This can lead to insecure storage, accidental commits, or overbroad distribution of a credential that enables direct CRM access.
The skill advertises delete operations without any warning, confirmation guidance, or mention of irreversible consequences. In an agent-driven workflow, this raises the risk of accidental or prompt-induced destructive actions against production CRM records.
The module documentation emphasizes direct querying and fresh reads, but the code also performs create, update, delete, and note creation actions. In security-sensitive agent workflows, inaccurate documentation can mislead operators into granting or invoking mutating behavior they did not expect.
The skill description claims CRUD for companies, people, and notes, but the implementation also exposes broader Attio access such as deals, tasks, pipelines, object enumeration, and generic object queries. This mismatch increases the risk that users or calling agents invoke capabilities they did not knowingly authorize, expanding data exposure and modification scope.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
if not API_KEY:
print(json.dumps({"error": "No API key found. Set ATTIO_API_KEY env var or create .env file"}))
sys.exit(1)
BASE_URL = "https://api.attio.com/v2"
def make_request(endpoint: str, method: str = "GET", data: dict = None, timeout: int = 60) -> dict:
"""Make request to Attio API with proper headers and timeout."""
The delete operation executes immediately when given an object type and record ID, with no confirmation, dry-run option, or safeguard. In an agent-operated environment, this raises the likelihood of accidental or prompt-induced destructive actions against production CRM data.
The CLI supports arbitrary endpoint access via --raw and also falls back to generic object querying for unrecognized endpoints, effectively turning the skill into a broad Attio API proxy. In an agent context, this can bypass the narrower business purpose described in metadata and enable unexpected reads or writes across the tenant.
The script reads an API credential from the ATTIO_API_KEY environment variable and falls back to a local .env file, but there is no user-facing notice that sensitive credentials are being accessed. For code files, access to sensitive environment variables or credentials should have some visible disclosure unless already clearly warned elsewhere.