T09 · Insecure Skill Coding Practices
- Location
scripts/match_faces.py:35- Finding
Biometric API Requests Are Retained by Default
- Content
View full analysis
Vulnerability Details
File Location:
scripts/match_faces.py:35-49
Related Documentation:SKILL.md:65
Vulnerability Type: Biometric data retention enabled through an omitted privacy parameter
Risk Level: MediumVulnerable Code
python headers = {"x-api-key": api_key} data = { "face_match_score_decline_threshold": str(threshold), "rotate_image": str(rotate).lower(), } if vendor_data: data["vendor_data"] = vendor_data with open(user_image, "rb") as uf, open(ref_image, "rb") as rf: files = { "user_image": (os.path.basename(user_image), uf), "ref_image": (os.path.basename(ref_image), rf), } response = requests.post(API_URL, headers=headers, files=files, data=data, timeout=60)The Skill documentation states that the omitted option defaults to retention:
markdown | `save_api_request` | boolean | No | `true` | — | Save in Business Console Manual Checks |Technical Analysis
The face-matching operation necessarily transmits two facial images to the declared Didit HTTPS endpoint. However, the request does not set
save_api_requesttofalse. According to the bundled API documentation, this parameter defaults totrue, causing the request to be saved in the Business Console Manual Checks area.Persistent server-side retention is not necessary to obtain a standalone face-match result. The behavior therefore exceeds the minimum data privileges required for the declared functionality and conflicts with the Skill's own recommendation to minimize biometric image storage.
Facial images are persistent biometric identifiers that cannot be safely rotated in the same manner as passwords or API keys. Retaining them unnecessarily increases the consequences of account compromise, excessive console access, insider misuse, or a service-side data breach.
Attack Path
- A user supplies a selfie and ...[truncated 1314 chars]
- Remediation
View remediation
Remediation Suggestions
Add the privacy control explicitly to every request:
python data = { "face_match_score_decline_threshold": str(threshold), "rotate_image": str(rotate).lower(), "save_api_request": "false", }If request retention is required for a specific workflow:
- Keep retention disabled by default.
- Introduce an explicit option such as
--save-api-request. - Display a clear notice that enabling the option may persist facial images and associated metadata in the Business Console.
- Obtain informed user authorization before uploading with retention enabled.
- Document the retention duration, access controls, deletion process, and applicable data-processing terms.
- Restrict Business Console access using least privilege and periodically remove records that are no longer required.
