VYPR
Moderate severityNVD Advisory· Published Feb 19, 2026· Updated Feb 19, 2026

Skill Scanner Unsecured Network Binding Vulnerability

CVE-2026-26057

Description

Skill Scanner is a security scanner for AI Agent Skills that detects prompt injection, data exfiltration, and malicious code patterns. A vulnerability in the API Server of Skill Scanner could allow a unauthenticated, remote attacker to interact with the server API and either trigger a denial of service (DoS) condition or upload arbitrary files. This vulnerability is due to an erroneous binding to multiple interfaces. An attacker could exploit this vulnerability by sending API requests to a device exposing the affected API Server. A successful exploit could allow the attacker to consume an excessive amount of resources (memory starvation) or to upload files to arbitrary folders on the affected device. This vulnerability affects Skill-scanner 1.0.1 and earlier releases when the API Server is enabled. The API Server is not enabled by default. Skill-scanner software releases 1.0.2 and later contain the fix for this vulnerability.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

CVE-2026-26057: Unauthenticated remote attacker can trigger DoS or upload arbitrary files in Skill Scanner API Server due to erroneous interface binding.

Vulnerability

Overview

CVE-2026-26057 is a vulnerability in the API Server component of Skill Scanner, a security scanner for AI tool for detecting prompt injection and malicious code. The flaw originates from an erroneous binding to multiple interfaces, causing the server to listen on all network interfaces (0.0.0.0) instead of localhost only [1][2][3]. This misconfiguration exposes the unauthenticated API to remote attackers, bypassing the intended localhost-only protection.

Exploitation and

Attack Surface

An unauthenticated, remote attacker can exploit this by sending crafted HTTP requests to the exposed API endpoints exposed via the misbound server. The attack surface includes the /upload and other endpoints that accept file uploads and scanning requests. No authentication or prior access is required, making any device with the API server accessible on the network a potential target [1][2][3][4]. The API Server is not enabled by default, but when enabled, the erroneous binding opens the service to remote interaction.

Impact

Successful exploitation allows two types of impact: first, a denial of service (DoS) condition via memory starvation, likely achieved by uploading zipbombs that consume excessive memory resources; second, the ability to upload arbitrary files to arbitrary folders on the host device [1][2][3][4]. This can lead to data modification, information disclosure, or further system compromise.

Mitigation

Status

The vulnerability affects Skill Scanner versions 1.0.1 and earlier. The fix was introduced in version 1.0.2, which changes the default binding from 0.0.0.0 to 127.0.0.1 (localhost) and adds warnings about the unauthenticated nature of the server [2][4]. Users are advised to update to 1.0.2 or later. If updating is not immediately possible, ensure the API Server is disabled or configured to listen only on localhost and avoid exposing it on untrusted networks.

AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
cisco-ai-skill-scannerPyPI
< 1.0.21.0.2

Affected products

1
  • cisco-ai-defense/skill-scannerv5
    Range: < 1.0.2

Patches

1
1e35e57f3051

fix: restrict api access to localhost by default, and warn of the issues if exposed publically (#8)

https://github.com/cisco-ai-defense/skill-scannerRichard TweedJan 30, 2026via ghsa
6 files changed · +44 34
  • docs/api-server.md+39 28 modified
    @@ -5,6 +5,7 @@
     The Skill Scanner API Server provides a REST interface for uploading and scanning Agent Skills packages, enabling integration with web applications, CI/CD pipelines, and other services.
     
     **Key Points**:
    +
     - **Skills are local packages**: Skills are local file packages that users install on their machines, not remote services
     - **API enables uploads**: The API allows uploading skill ZIP files for scanning via HTTP
     - **For integration workflows**: Useful for CI/CD, web interfaces, and service integrations
    @@ -15,12 +16,16 @@ The Skill Scanner API Server provides a REST interface for uploading and scannin
     **Documentation**: Auto-generated Swagger/ReDoc
     **Status**: Production ready
     
    +## Warnings
    +
    +This server is for development use, and is unauthenticated. We recommend you do not expose it on any interface except localhost, since these APIs can be used for a denial of wallet attack on your API keys, or denial of service on the hosting machine through uploaded zipbombs.
    +
     ## Starting the Server
     
     ### Command Line
     
     ```bash
    -# Start server (default: 0.0.0.0:8000)
    +# Start server (default: localhost:8000)
     skill-scanner-api
     
     # Custom port
    @@ -38,7 +43,7 @@ skill-scanner-api --host 127.0.0.1 --port 9000
     ```python
     from skill_scanner.api_server import run_server
     
    -run_server(host="0.0.0.0", port=8000, reload=False)
    +run_server(host="127.0.0.1", port=8000, reload=False)
     ```
     
     ## Endpoints
    @@ -52,6 +57,7 @@ GET /health
     Returns server status and available analyzers.
     
     **Response:**
    +
     ```json
     {
       "status": "healthy",
    @@ -83,16 +89,17 @@ Content-Type: application/json
     
     **Request Parameters:**
     
    -| Parameter | Type | Default | Description |
    -|-----------|------|---------|-------------|
    -| `skill_directory` | string | required | Path to skill directory |
    -| `use_behavioral` | boolean | false | Enable behavioral dataflow analyzer |
    -| `use_llm` | boolean | false | Enable LLM semantic analyzer |
    -| `llm_provider` | string | "anthropic" | LLM provider (anthropic, openai, azure, bedrock, gemini) |
    -| `use_aidefense` | boolean | false | Enable Cisco AI Defense analyzer |
    -| `aidefense_api_key` | string | null | AI Defense API key (or set `AI_DEFENSE_API_KEY` env var) |
    +| Parameter           | Type    | Default     | Description                                              |
    +| ------------------- | ------- | ----------- | -------------------------------------------------------- |
    +| `skill_directory`   | string  | required    | Path to skill directory                                  |
    +| `use_behavioral`    | boolean | false       | Enable behavioral dataflow analyzer                      |
    +| `use_llm`           | boolean | false       | Enable LLM semantic analyzer                             |
    +| `llm_provider`      | string  | "anthropic" | LLM provider (anthropic, openai, azure, bedrock, gemini) |
    +| `use_aidefense`     | boolean | false       | Enable Cisco AI Defense analyzer                         |
    +| `aidefense_api_key` | string  | null        | AI Defense API key (or set `AI_DEFENSE_API_KEY` env var) |
     
     **Response:**
    +
     ```json
     {
       "scan_id": "uuid",
    @@ -141,6 +148,7 @@ Content-Type: application/json
     ```
     
     **Response:**
    +
     ```json
     {
       "scan_id": "uuid",
    @@ -156,6 +164,7 @@ GET /scan-batch/{scan_id}
     ```
     
     **Response (Processing):**
    +
     ```json
     {
       "scan_id": "uuid",
    @@ -165,6 +174,7 @@ GET /scan-batch/{scan_id}
     ```
     
     **Response (Completed):**
    +
     ```json
     {
       "scan_id": "uuid",
    @@ -185,6 +195,7 @@ GET /analyzers
     ```
     
     **Response:**
    +
     ```json
     {
       "analyzers": [
    @@ -329,13 +340,13 @@ while True:
     
     ```javascript
     // Scan skill
    -const response = await fetch('http://localhost:8000/scan', {
    -  method: 'POST',
    -  headers: { 'Content-Type': 'application/json' },
    +const response = await fetch("http://localhost:8000/scan", {
    +  method: "POST",
    +  headers: { "Content-Type": "application/json" },
       body: JSON.stringify({
    -    skill_directory: '/path/to/skill',
    -    use_llm: false
    -  })
    +    skill_directory: "/path/to/skill",
    +    use_llm: false,
    +  }),
     });
     
     const result = await response.json();
    @@ -344,12 +355,12 @@ console.log(`Findings: ${result.findings_count}`);
     
     // Upload ZIP
     const formData = new FormData();
    -formData.append('file', skillZipFile);
    -formData.append('use_llm', 'false');
    +formData.append("file", skillZipFile);
    +formData.append("use_llm", "false");
     
    -const uploadResponse = await fetch('http://localhost:8000/scan-upload', {
    -  method: 'POST',
    -  body: formData
    +const uploadResponse = await fetch("http://localhost:8000/scan-upload", {
    +  method: "POST",
    +  body: formData,
     });
     ```
     
    @@ -373,7 +384,7 @@ export ANTHROPIC_API_BASE=https://your-endpoint.com/anthropic
     export AI_DEFENSE_API_KEY=your_key
     
     # Server settings (optional)
    -export API_HOST=0.0.0.0
    +export API_HOST=localhost
     export API_PORT=8000
     ```
     
    @@ -472,12 +483,12 @@ docker run -p 8000:8000 \
     
     ### Common Errors
     
    -| Status Code | Error | Solution |
    -|-------------|-------|----------|
    -| 400 | Invalid request | Check JSON format and required fields |
    -| 404 | Skill not found | Verify directory path exists |
    -| 500 | Scan failed | Check logs for detailed error |
    -| 503 | Service unavailable | Server may be overloaded or starting up |
    +| Status Code | Error               | Solution                                |
    +| ----------- | ------------------- | --------------------------------------- |
    +| 400         | Invalid request     | Check JSON format and required fields   |
    +| 404         | Skill not found     | Verify directory path exists            |
    +| 500         | Scan failed         | Check logs for detailed error           |
    +| 503         | Service unavailable | Server may be overloaded or starting up |
     
     ### Error Response Format
     
    
  • skill_scanner/api/api_cli.py+2 2 modified
    @@ -39,11 +39,11 @@ def main():
       skill-scanner-api --reload
     
       # Custom host and port
    -  skill-scanner-api --host 0.0.0.0 --port 9000
    +  skill-scanner-api --host localhost --port 9000
             """,
         )
     
    -    parser.add_argument("--host", default="0.0.0.0", help="Host to bind to (default: 0.0.0.0)")
    +    parser.add_argument("--host", default="localhost", help="Host to bind to (default: localhost)")
     
         parser.add_argument("--port", type=int, default=8000, help="Port to bind to (default: 8000)")
     
    
  • skill_scanner/api/api_server.py+1 1 modified
    @@ -616,7 +616,7 @@ async def list_analyzers():
     
     
     # Entry point for running the server
    -def run_server(host: str = "0.0.0.0", port: int = 8000, reload: bool = False):
    +def run_server(host: str = "localhost", port: int = 8000, reload: bool = False):
         """
         Run the API server.
     
    
  • skill_scanner/core/analyzers/static.py+1 1 modified
    @@ -553,7 +553,7 @@ def _skill_uses_network(self, skill: Skill) -> bool:
             ]
     
             socket_external_indicators = ["socket.connect", "socket.create_connection"]
    -        socket_localhost_indicators = ["localhost", "127.0.0.1", "0.0.0.0"]
    +        socket_localhost_indicators = ["localhost", "127.0.0.1", "::1"]
     
             for skill_file in skill.get_scripts():
                 content = skill_file.read_content()
    
  • skill_scanner/core/static_analysis/context_extractor.py+0 1 modified
    @@ -172,7 +172,6 @@ class ContextExtractor:
             # Localhost and development
             "localhost",
             "127.0.0.1",
    -        "0.0.0.0",
         ]
     
         def extract_context(self, file_path: Path, source_code: str) -> SkillScriptContext:
    
  • tests/test_api_server_config.py+1 1 modified
    @@ -225,7 +225,7 @@ def test_run_server_default_values(self):
             sig = inspect.signature(run_server)
     
             # Check default values
    -        assert sig.parameters["host"].default == "0.0.0.0"
    +        assert sig.parameters["host"].default == "localhost"
             assert sig.parameters["port"].default == 8000
             assert sig.parameters["reload"].default is False
     
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.