Back to skill

Security audit

Batch Processing (DataLoader)

Security checks for vulnerabilities and agentic risk

Overview

This is a self-contained JavaScript DataLoader utility with some quality caveats, but no hidden persistence, credential access, or deceptive data movement.

Before using this in production, validate DataLoader options such as maxBatchSize and treat the benchmark examples as illustrative rather than authoritative. Only batch APIs or databases you intentionally provide through your own batchLoadFn, and avoid sharing loader instances across unrelated requests if cached data is sensitive.

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
dataloader.js:33
Finding

Unvalidated maxBatchSize Allows Infinite Dispatch Rescheduling and Denial of Service

Content
View full analysis
0; if (this._queue.length > 0) { setImmediate(() => this._dispatchBatch()); } ``` ### Technical Analysis The constructor does not verify that `maxBatchSize` is a finite positive integer. Because negative numbers are truthy in JavaScript, a value such as `-1` is accepted instead of falling back to the default. When `_dispatchBatch()` runs with `maxBatchSize: -1`, `this._queue.slice(0, -1)` excludes the final queued item, while `this._queue.slice(-1)` retains that item. The queue therefore never becomes empty. The implementation continuously schedules another dispatch through `setImmediate()`, and the retained load promise never resolves. The same underlying problem applies to other negative values, which can leave one or more entries permanently queued. Non-integer, infinite, or otherwise invalid values also lack explicit validation and can produce unexpected batching behavior. ### Attack Path 1. An attacker or untrusted caller gains influence over the options passed to the `DataLoader` constructor. 2. The caller creates a loader with a negative batch size: ```javascript const loader = new DataLoader(async keys => keys, { maxBatchSize: -1 }); ``` 3. The caller queues at least one load: ```javascript await loader.load('attacker-controlled-key'); ``` 4. `_dispatchBatch()` retains the queued item because of the negative `slice()` index. 5. Since the queue remains non-empty, the implementation repeatedly invokes `setImmediate()` and dispatches again. 6. The load p ...[truncated 615 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 106)May include surrounding context.

md
console.log('\n=== Example 2: API Batching ===');
  
  const urls = [
    'https://api.example.com/users/1',
    'https://api.example.com/users/2',
    'https://api.example.com/users/3',
  ];

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 107)May include surrounding context.

md
console.log('\n=== Example 2: API Batching ===');
  
  const urls = [
    'https://api.example.com/users/1',
    'https://api.example.com/users/2',
    'https://api.example.com/users/3',
  ];

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · examples.js (reported line 77)May include surrounding context.

js
console.log('\n=== Example 2: API Batching ===');
  
  const urls = [
    'https://api.example.com/users/1',
    'https://api.example.com/users/2',
    'https://api.example.com/users/3',
  ];

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · examples.js (reported line 78)May include surrounding context.

js
console.log('\n=== Example 2: API Batching ===');
  
  const urls = [
    'https://api.example.com/users/1',
    'https://api.example.com/users/2',
    'https://api.example.com/users/3',
  ];

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · examples.js (reported line 79)May include surrounding context.

js
console.log('\n=== Example 2: API Batching ===');
  
  const urls = [
    'https://api.example.com/users/1',
    'https://api.example.com/users/2',
    'https://api.example.com/users/3',
  ];

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The comments and output framing present Example 5 as a DataLoader-based improvement over N+1 behavior, but the postLoader batch function loops over userIds and executes mockDB.query once per ID. This contradicts the documented intent that the example demonstrates reducing N+1 queries through batching, because the implementation still issues N per-user post queries inside the batch.

Content

No source excerpt is available for this finding.