Back to skill

Security audit

Didit Face Search

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it handles highly sensitive face images and identity results in ways that deserve review before installation.

Install only if you have a lawful basis and user consent to send face images to Didit. Treat outputs as sensitive identity data, avoid logging full responses, use pseudonymous vendor_data, protect DIDIT_API_KEY, and prefer changing the script or API call to disable saved API requests unless retention is explicitly required.

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

Warning
Location
scripts/search_faces.py:33
Finding

Biometric Images Are Retained Remotely by Default

Content
View full analysis
dict: api_key = get_api_key() with open(image_path, "rb") as f: files = {"user_image": (os.path.basename(image_path), f, "image/jpeg")} data = {} if rotate: data["rotate_image"] = "true" if vendor_data: data["vendor_data"] = vendor_data r = requests.post(ENDPOINT, headers={"x-api-key": api_key}, files=files, data=data, timeout=60) ``` The API documentation states: ```markdown | `user_image` | file | **Yes** | — | Face image to search (JPEG/PNG/WebP/TIFF, max 5MB) | | `rotate_image` | boolean | No | `false` | Try 0/90/180/270 rotations for non-upright faces | | `save_api_request` | boolean | No | `true` | Save in Business Console | | `vendor_data` | string | No | — | Your identifier for session tracking | ``` ### Technical Analysis Uploading a face image and the `DIDIT_API_KEY` to the documented Didit HTTPS endpoint is disclosed and required for the Skill's remote face-search functionality. The destination is hardcoded as `https://verification.didit.me/v3/face-search/`, and no covert secondary recipient was identified. However, the API defaults `save_api_request` to `true`, while the script does not override that behavior. Consequently, every submitted biometric image may be retained in the Didit Business Console even when the operator only needs an immediate search result. Remote retention is not necessary for the core one-time comparison operation and therefore exceeds minimum data handling requirements. Face images are sensitive biometric data. Unlike ordinary credentials, biometric traits cannot readily be changed after compromi ...[truncated 1326 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/search_faces.py:61
Finding

Complete Face-Search Response Is Written to Standard Output

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:243
Finding

Third-Party Dependency Is Installed Without Version or Integrity Pinning

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (7)

Tainted flow: 'api_key' from os.environ.get (line 26, 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 · scripts/search_faces.py (reported line 42)May include surrounding context.

python
data["rotate_image"] = "true"
        if vendor_data:
            data["vendor_data"] = vendor_data
        r = requests.post(ENDPOINT, headers={"x-api-key": api_key},
                          files=files, data=data, timeout=60)
    if r.status_code not in (200, 201):
        print(f"Error {r.status_code}: {r.text}", file=sys.stderr)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill requires environment access and makes network calls but does not declare an explicit tool/permission scope. That can cause agents or reviewers to underestimate its capabilities, weakening least-privilege controls and informed consent around a workflow that handles biometric data. In this context, the omission is more concerning because the skill transmits face images and API credentials to an external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill description does not clearly warn that biometric face images and related personal data are transmitted to a third-party API for 1:N face search. Users or integrators may invoke it without understanding that highly sensitive biometric information and associated identifiers may leave their environment, creating privacy, consent, and regulatory risk. Because this skill is specifically designed for facial deduplication, the context makes the omission more dangerous than a generic external API call.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

This example performs an external POST request sending a face image and API key to a remote service. While expected for the feature, it is still a real data-exfiltration boundary involving sensitive biometric data; if used without clear consent, validation, or governance, it can expose users' personal information to a third party. The surrounding skill context makes this transmission legitimate in purpose but sensitive in impact.

Content

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

python
import requests

response = requests.post(
    "https://verification.didit.me/v3/face-search/",
    headers={"x-api-key": "YOUR_API_KEY"},
    files={"user_image": ("photo.jpg", open("photo.jpg", "rb"), "image/jpeg")},

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

This browser/TypeScript example also sends a face image and API key to an external endpoint. The behavior is not inherently malicious, but it crosses a sensitive trust boundary with biometric data and could lead to privacy violations or unauthorized disclosure if embedded into larger agent workflows without adequate notice and controls. Given the facial search use case, the sensitivity of the transmitted data raises the risk level.

Content

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

md
const formData = new FormData();
formData.append("user_image", photoFile);

const response = await fetch("https://verification.didit.me/v3/face-search/", {
  method: "POST",
  headers: { "x-api-key": "YOUR_API_KEY" },
  body: formData,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script uploads a face image and optional vendor tracking data to a third-party remote service, but it provides no explicit user notice, confirmation, or consent checkpoint at runtime. Because facial images are highly sensitive biometric data, silent transmission can create privacy, compliance, and unauthorized-disclosure risks, especially if operators invoke the tool on user data without clear disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The code reads DIDIT_API_KEY from the environment, which is a sensitive credential access pattern covered by the warning rule for code files. While the docstring notes that the variable is required, it does not explain that the credential will be used to authenticate requests to an external service or provide any user-facing handling notice beyond failure output.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.