Back to skill

Security audit

opensearch-vector-search

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent OpenSearch guidance, but its live cluster analyzer handles real cluster passwords in an unsafe way and disables TLS certificate verification by default.

Review before installing if you plan to use live cluster analysis. Use a dedicated least-privilege read-only OpenSearch account, avoid sending passwords in chat or command-line arguments, require HTTPS with certificate verification, and pin installer and benchmark dependency versions. Documentation examples that create, modify, or delete indices should be treated as manual examples only, never run against production without backups and explicit confirmation.

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

Error
Location
scripts/analyze_cluster.py:37
Finding

TLS Certificate Verification Is Disabled by Default for Authenticated Cluster Connections

Content
View full analysis
OpenSearch: """Create an OpenSearch client connection.""" parsed = url.rstrip("/") use_ssl = parsed.startswith("https") kwargs = { "hosts": [parsed], "use_ssl": use_ssl, "verify_certs": verify_ssl, "ssl_show_warn": False, "connection_class": RequestsHttpConnection, "timeout": 30, } if not no_auth and username and password: kwargs["http_auth"] = (username, password) return OpenSearch(**kwargs) ``` ```python parser.add_argument("--url", required=True, help="OpenSearch cluster URL (e.g., https://host:9200)") parser.add_argument("--username", "-u", help="Username for basic auth") parser.add_argument("--password", "-p", help="Password for basic auth") parser.add_argument("--no-auth", action="store_true", help="Connect without authentication") parser.add_argument("--verify-ssl", action="store_true", help="Verify SSL certificates (default: false)") ``` ### Technical Analysis The analyzer sends HTTP Basic Authentication credentials to a user-selected OpenSearch endpoint, but TLS certificate validation is disabled unless the user explicitly supplies `--verify-ssl`. Consequently, an HTTPS connection encrypts traffic without reliably authenticating the destination s ...[truncated 2040 chars]
Remediation
View remediation
OpenSearch: ``` 2. Replace `--verify-ssl` with an explicitly dangerous `--insecure` option. Require deliberate opt-in and print a prominent warning when it is used. 3. Reject non-HTTPS URLs whenever authentication is enabled: ```python if not no_auth and not parsed.startswith("https://"): raise ValueError("HTTPS is required when credentials are used") ``` 4. Remove `warnings.filterwarnings("ignore")` and set `ssl_show_warn=True`. 5. Support private certificate authorities through a `--ca-certs` option rather than advising users to disable verification. 6. Validate that the URL scheme is exactly `https` or `http`, reject embedded URL credentials, and document the expected endpoint. 7. Use a dedicated read-only OpenSearch principal with only the cluster-monitoring and index-metadata permissions required by the selected analysis action. 8. Add automated tests confirming that authenticated HTTP is rejected and that certificate verification is enabled unless an explicit insecure override is supplied. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:123
Finding

OpenSearch Passwords Are Requested Through Chat and Exposed in Command-Line Arguments

Content
View full analysis
-u -p --action cluster-overview -f pretty ``` ``` The script implements the plaintext command-line password option: ```python parser.add_argument("--url", required=True, help="OpenSearch cluster URL (e.g., https://host:9200)") parser.add_argument("--username", "-u", help="Username for basic auth") parser.add_argument("--password", "-p", help="Password for basic auth") ``` The README also demonstrates literal command-line passwords: ```bash python3 scripts/analyze_cluster.py \ --url https://my-cluster.us-east-1.es.amazonaws.com \ -u admin -p MyPassword \ --action all -f pretty ``` ### Technical Analysis Requesting a password in an agent conversation places the secret in chat history and potentially in service-side logs, model telemetry, audit records, or exported transcripts. Passing the password with `-p` places it in the process argument vector. Depending on the exec ...[truncated 1757 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
opensearch-vector-benchmark/SKILL.md:46
Finding

Mutable and Unpinned Third-Party Packages Are Installed and Executed

Content
View full analysis
Remediation
View remediation
' ``` 2. Maintain a lock or constraints file covering transitive dependencies. 3. Generate and enforce cryptographic hashes with `pip --require-hashes` where practical. 4. Replace `npx clawhub@latest` with a reviewed, pinned package version. 5. Verify package provenance, signatures, registry ownership, and release checksums before the first execution. 6. Perform installation in a disposable, least-privileged environment without production credentials. 7. Do not expose the AWS credential chain or OpenSearch secrets during package installation or initial import validation. 8. Scan the resolved dependency set for known vulnerabilities and record the lock file with the benchmark manifest. 9. Promote dependency versions only through a review and testing process rather than automatically consuming new releases. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (29)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · .gitignore (reported line 4)May include surrounding context.

text
__pycache__/
*.pyc
*.pyo
.env
.venv

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill description promises broad analysis and live cluster review, including handling cluster URLs and credentials, while the declared capabilities and implemented behavior are not clearly aligned and the permission model is absent. This mismatch is dangerous because users or orchestrators may trust the skill with sensitive credentials or operational decisions under false assumptions about what is implemented, reviewed, or safely constrained, which can expose secrets or trigger risky analysis flows without adequate safeguards.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **Cluster analyzer** (`scripts/analyze_cluster.py`): Connects to a user-provided OpenSearch cluster and performs **read-only** analysis. It NEVER creates, mod

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **Cluster analyzer** (`scripts/analyze_cluster.py`): Connects to a user-provided OpenSearch cluster and performs **read-only** analysis. It NEVER creates, mod

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **Cluster analyzer** (`scripts/analyze_cluster.py`): Connects to a user-provided OpenSearch cluster and performs **read-only** analysis. It NEVER creates, mod

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **Cluster analyzer** (`scripts/analyze_cluster.py`): Connects to a user-provided OpenSearch cluster and performs **read-only** analysis. It NEVER creates, mod

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **Cluster analyzer** (`scripts/analyze_cluster.py`): Connects to a user-provided OpenSearch cluster and performs **read-only** analysis. It NEVER creates, mod

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **Cluster analyzer** (`scripts/analyze_cluster.py`): Connects to a user-provided OpenSearch cluster and performs **read-only** analysis. It NEVER creates, mod

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **Cluster analyzer** (`scripts/analyze_cluster.py`): Connects to a user-provided OpenSearch cluster and performs **read-only** analysis. It NEVER creates, mod

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| Cost optimization, instance sizing, memory calc | `references/cost-optimization.md` | cost, pricing, instance, memory calculation, cluster sizing, budget |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| Cost optimization, instance sizing, memory calc | `references/cost-optimization.md` | cost, pricing, instance, memory calculation, cluster sizing, budget |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
89% confidence
Finding

The documented DELETE /my_index_v1 command is a destructive administrative operation that could be copied and executed against a live OpenSearch cluster, causing immediate permanent loss of the old index. This skill’s context increases risk because it is operational guidance for OpenSearch administration, and users may provide real cluster endpoints and follow examples verbatim.

Content

Scanner excerpt · references/indexing-strategies.md (reported line 240)May include surrounding context.

  1. Delete the old index:
bash
DELETE /my_index_v1

Best Practices:

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 49)May include surrounding context.

git clone https://github.com/norrishuang/opensearch-vector-search-skill.git cd opensearch-vector-search-skill

mkdir -p ~/.kiro/steering cp SKILL.md ~/.kiro/steering/opensearch-vector-search.md cp -r references ~/.kiro/steering/opensearch-references

text

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 81)May include surrounding context.

bash
# Copy skill into the .kiro/skills directory of your project
mkdir -p <your-project>/.kiro/skills/opensearch-vector-search
cp SKILL.md <your-project>/.kiro/skills/opensearch-vector-search/SKILL.md
cp -r references <your-project>/.kiro/skills/opensearch-vector-search/references
cp -r scripts <your-project>/.kiro/skills/opensearch-vector-search/scripts

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 95)May include surrounding context.

bash
# Copy skill into the .kiro/skills directory of your project
mkdir -p <your-project>/.kiro/skills/opensearch-vector-search
cp SKILL.md <your-project>/.kiro/skills/opensearch-vector-search/SKILL.md
cp -r references <your-project>/.kiro/skills/opensearch-vector-search/references
cp -r scripts <your-project>/.kiro/skills/opensearch-vector-search/scripts

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill advertises and documents shell execution and outbound network activity, including scripts that call the AWS Pricing API and connect to user-provided OpenSearch clusters, but it does not declare any explicit tool scope or permissions boundary. That increases the risk of overbroad execution in a host agent, makes operator review harder, and can lead to unintended credential use or network access if the skill is invoked in environments with ambient tools and secrets.

Content

No source excerpt is available for this finding.

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · references/cost-optimization.md (reported line 1510)May include surrounding context.

md
def monitor_quantized_index():
    # 1. Check cluster health
    health = requests.get("http://localhost:9200/_cluster/health").json()
    if health["status"] != "green":
        alert("Cluster status abnormal")

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · references/cost-optimization.md (reported line 1515)May include surrounding context.

md
def monitor_quantized_index():
    # 1. Check cluster health
    health = requests.get("http://localhost:9200/_cluster/health").json()
    if health["status"] != "green":
        alert("Cluster status abnormal")

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The document explicitly instructs readers to delete an index but does not prominently warn that this action is irreversible and will permanently remove data. In a knowledge-base skill that may be used to guide operational actions, omission of a destructive-action warning can lead to accidental data loss, especially if users copy commands directly into production workflows.

Content

No source excerpt is available for this finding.

Behavior Manipulation

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Subtle instructions detected that may alter agent decision-making or introduce hidden biases.

Content

Scanner excerpt · references/indexing-strategies.md (reported line 244)May include surrounding context.

text

**Best Practices**:
- Always use aliases instead of directly using index names
- Use version numbers in index naming (e.g., my_index_v1)
- Use the `_reindex` API when rebuilding indexes
- Verify data integrity in the new index before switching the alias

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · references/quantization-techniques.md (reported line 273)May include surrounding context.

md
"id": i
        }
        
        response = requests.post(
            f"http://localhost:9200/{index_name}/_doc/{i}",
            headers={"Content-Type": "application/json"},
            data=json.dumps(doc)

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · references/quantization-techniques.md (reported line 569)May include surrounding context.

md
"id": i
        }
        
        response = requests.post(
            f"http://localhost:9200/{index_name}/_doc/{i}",
            headers={"Content-Type": "application/json"},
            data=json.dumps(doc)

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · references/quantization-techniques.md (reported line 569)May include surrounding context.

md
for vector in test_vectors:
        # Get quantized results via API
        response = requests.post(
            f"http://localhost:9200/_plugins/_knn/models/{model_id}/_search",
            json={"vector": vector.tolist(), "k": 1}
        )

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The client disables TLS certificate verification by default via verify_ssl=False and passes verify_certs=verify_ssl, while also suppressing SSL warnings. This allows a man-in-the-middle attacker to intercept or modify traffic to the OpenSearch cluster, including credentials and cluster metadata, especially because this skill explicitly supports connecting to user-provided cluster URLs and credentials.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
tests/test_generate_benchmark_plan.py:24