Back to skill

Security audit

API Tester Pro

Security checks for vulnerabilities and agentic risk

Overview

This API-testing skill matches its stated purpose, but it can send requests from the agent host to any URL and saves full tested URLs locally by default.

Install only if you are comfortable letting the skill make user-directed HTTP requests from the agent environment. Avoid putting secrets in URLs, use it only with trusted endpoints, be careful with internal or cloud-metadata addresses, and manually remove or protect api_tests.json if sensitive endpoints were tested.

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
SKILL.md:40
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery

Content
View full analysis
urllib.request.Request: """Convert to a urllib request object.""" data = None if self.body and self.method in ("POST", "PUT", "PATCH"): data = self.body.encode("utf-8") if isinstance(self.body, str) else self.body if "Content-Type" not in self.headers: self.headers["Content-Type"] = self.content_type req = urllib.request.Request( self.url, data=data, headers=self.headers, method=self.method ) return req ``` ```python def send(self, request: APIRequest) -> APIResponse: """Send a single API request.""" resp = APIResponse() start = time.time() try: req = request.to_urllib_request() with urllib.request.urlopen(req, timeout=request.timeout) as conn: ``` The same unrestricted request primitive is exposed through the benchmark and GraphQL functions: ```python def benchmark(self, url: str, count: int = 5, method: str = "GET") -> dict: latencies = [] errors = 0 for i in range(count): req = APIRequest(method=method, url=url) resp = self.send(req) ``` ```python def graphql(self, endpoint: str, query: str, variables: dict = None) -> APIResponse: body = json.dumps({"query": query, "variables": variables or {}}) req = APIRequest( method="POST", url=endpoint, body=body, content_type="application/json" ) return self.send(req) ``` ### Technical Analysis The request URL is passed directly to `urllib.request.Request` and `urllib.request.urlopen` without validating its scheme, hostname, resolved IP address, port, or redirect destination. No restrictions prevent access to loopback, private, link-local, reserved, or cloud me ...[truncated 1828 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:100
Finding

Sensitive URL Data Is Persisted in Plaintext History

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (5)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill description advertises test-result persistence but does not clearly warn users that API interaction data will be retained locally. This lack of transparency increases the chance that users unknowingly store sensitive endpoint information or test artifacts on disk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill initializes a persistent history file and creates directories to store API test records locally. For an API testing utility, persistence can be legitimate, but storing request metadata by default creates unnecessary data retention risk because tested URLs may contain secrets, internal hostnames, or other sensitive operational details.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill sends arbitrary outbound HTTP and GraphQL requests based on user-provided inputs without an explicit warning that supplied data will be transmitted to remote services. In practice, users may include tokens, personal data, or internal URLs, making this a data-exposure and SSRF-style capability if used in sensitive environments.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code appends detailed test history to disk on every request, including URL, status, timing, errors, and timestamp, extending beyond transient execution. This creates a local audit trail that could expose internal endpoints, credentials embedded in URLs, or sensitive failure details if the file is later accessed by another user or process.

Content

No source excerpt is available for this finding.

External Transmission

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

md
# GraphQL查询
gql_resp = tester.graphql(
    "https://api.github.com/graphql",
    "{ viewer { login } }"
)
print(f"GraphQL -> {gql_resp.status}")

Static analysis

No suspicious patterns detected.