T09 · Insecure Skill Coding Practices
- Location
mcp_connector/api_client.py:190- Finding
API Credential and Quote Data Can Be Sent to an Arbitrary or Plaintext Endpoint
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The connector is mostly purpose-aligned, but its privacy and network boundaries are under-disclosed for a tool that handles API keys, customer identifiers, and ERP inventory data.
Review this before installing in any real procurement or customer-data workflow. Use only a trusted HTTPS quote endpoint, scope and rotate the API key, avoid sending real customer identifiers, and treat remote advisory text as untrusted market data rather than instructions for the agent. Run it with access only to the intended inventory file.
mcp_connector/api_client.py:190API Credential and Quote Data Can Be Sent to an Arbitrary or Plaintext Endpoint
mcp_connector/api_client.py:155Undisclosed Customer Identifier Is Transmitted to the Remote Service
mcp_connector/merger.py:217Remote Advisory Content Is Inserted into MCP Agent Context Without Trust Controls
README.md:43Runtime Dependencies Are Installed Without Version or Integrity Pinning
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
cp .env.example .env
# Edit .env:
# QUOTE_ENGINE_URL = https://api.ic-navigator.com (or your self-hosted URL)
# QUOTE_ENGINE_API_KEY = JAY-IC-xxxxxxxxxxxxxxxxxxxx
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# Output as JSON (for ERP integration)
python -m mcp_connector.client quote STM32L412CBU6 --json
ENVIRONMENT VARIABLES (set in .env or shell)
─────────────────────────────────────────────
QUOTE_ENGINE_URL — https://your-engine.example.com
QUOTE_ENGINE_API_KEY — your X-API-Key credential
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# Output as JSON (for ERP integration)
python -m mcp_connector.client quote STM32L412CBU6 --json
ENVIRONMENT VARIABLES (set in .env or shell)
─────────────────────────────────────────────
QUOTE_ENGINE_URL — https://your-engine.example.com
QUOTE_ENGINE_API_KEY — your X-API-Key credential
The docstring promises that pricing columns are NEVER read, regardless of presence. But _build_index skips columns only when their actual header text matches price keywords; if a user maps stock_qty, package, or date_code to a non-keyword pricing header name, the code will index and extract that column, contradicting the stated guarantee.
The description explicitly labels the connector as 'Taiwan-neutral', which is a locale/political framing applied by default rather than presented as an optional mode. The file does not clearly state that users can opt into or disable this locale-specific filtering, so it may violate language/locale policy expectations.
The architecture section lists 'Taiwan-neutral filtering' as an inherent server-side function, suggesting the skill applies a specific locale/policy lens automatically. Although advisory output languages are selectable elsewhere, this policy-sensitive filtering itself is not presented as user-selectable or justified as mandatory for a narrowly regional tool.
The module-level documentation states that only part_number, qty, and lang are sent to the remote engine, but fetch_quote also includes customer_id when provided. This mismatch can cause callers to transmit identifying or sensitive data off-host under a false assumption, creating a real privacy and data-governance risk in a connector explicitly framed around minimizing outbound data.
The documentation promises that only part number, quantity, and language are transmitted, but the implementation also forwards customer_id to the remote service. This creates a privacy and trust boundary mismatch: operators may supply customer identifiers believing they are local-only or may rely on the stated guarantee for compliance decisions, causing unintended disclosure of potentially sensitive metadata.
The design narrative emphasizes minimal single-record extraction, but read_all and the batch helpers iterate and return all inventory rows from the local ERP file. In this skill context, that broadens access from targeted lookup to bulk exfiltration of inventory metadata, increasing confidentiality risk if the skill is invoked by an untrusted workflow or exposed agent.
The module’s privacy contract states that only part number and quantity are eligible for extraction, but the implementation also returns supply status, package, and date code. This is a real data-minimization/privacy-boundary violation because downstream callers may rely on the documented contract and unintentionally expose additional ERP metadata.
This code hard-codes user-visible recommendation strings in Traditional Chinese, and the formatter later also emits fixed Traditional Chinese labels. The applicable policy rule flags language/locale constraints when a specific language is forced without offering user choice or documenting a justified locale limitation.
The docstring explicitly states that labels are in Traditional Chinese, and the generated table headers and action/risk labels are all fixed in that locale. Under the policy, this is a natural-language locale restriction unless the skill provides opt-in language selection or clearly documents a justified region-specific scope.
The public API sets lang: str = "en" and documents English as the default advisory language. Under the policy, forcing a specific language without explicit user choice or opt-in is a natural-language locale policy issue unless clearly justified.
pip install without ==version installs the latest release, which could include malicious changes.
pip install without ==version installs the latest release, which could include malicious changes.
No suspicious patterns detected.