Back to skill

Security audit

beach-safety

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent beach-conditions MCP server, but it sends beach names and coordinates to third-party weather and geocoding services.

Install only if you are comfortable sending beach names and coordinates to public third-party APIs. Treat the safety score as advisory, verify local lifeguard and official beach warnings before entering the water, and consider pinning dependencies before operational use.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding

The documented purpose says the skill provides beach conditions via an mcporter MCP call, but the finding indicates behavior beyond that description, including CLI-based geocoding workflow and lack of evidence for the declared MCP-only architecture. Mismatches like this are dangerous because reviewers and users may approve the skill under false assumptions, while hidden or undocumented behavior can expand data access, execution paths, or external communications.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README encourages use from very broad natural-language prompts like asking generally about surf or beach safety at any beach worldwide, which can cause the skill to be invoked in loosely related contexts without strong user intent confirmation. For a skill that returns safety guidance, over-broad activation increases the chance of unnecessary external calls, incorrect context selection, or overreliance on automated safety advice when the user may have intended a general discussion rather than live conditions.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill declares no explicit tool scope or permissions even though its documented behavior relies on network access to external services. That makes the trust boundary unclear for users and hosting agents, and can permit broader-than-expected capability use if the runtime infers or grants network access implicitly.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The description says to use the skill when asked about "surf, waves, swim conditions, rip currents, or beach safety at any beach worldwide," which is a wide natural-language trigger set rather than a narrow invocation condition. It does not provide exclusion conditions or negative examples, so routine beach/travel conversation could unintentionally invoke the skill.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This code sends latitude/longitude derived from user input to api.weather.gov. External transmission of location data can expose user interests or whereabouts to third parties, which is a real privacy concern in an MCP/agent context where tool calls may be implicit.

Content

Scanner excerpt · src/server.py (reported line 223)May include surrounding context.

python
try:
        async with httpx.AsyncClient(timeout=15.0) as client:
            # Step 1: Get grid point metadata
            points_url = f"https://api.weather.gov/points/{lat},{lon}"
            resp = await client.get(points_url, headers={"User-Agent": "BeachSafetyMCP/1.0"})
            if resp.status_code != 200:
                return {}

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The tool transmits user-related coordinates to Open-Meteo for forecast data. While expected for functionality, it is still an external data flow that can leak location information without clear user awareness.

Content

Scanner excerpt · src/server.py (reported line 346)May include surrounding context.

python
"""Get Open-Meteo Weather data — completely free, no API key."""
    try:
        async with httpx.AsyncClient(timeout=15.0) as client:
            url = "https://api.open-meteo.com/v1/forecast"
            params = {
                "latitude": lat,
                "longitude": lon,

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

UV forecast retrieval also sends user-associated coordinates to Open-Meteo. Repeated external calls increase privacy exposure and should be treated as a genuine data-sharing risk, even though no direct code execution or credential leakage is present.

Content

Scanner excerpt · src/server.py (reported line 397)May include surrounding context.

python
try:
        async with httpx.AsyncClient(timeout=15.0) as client:
            resp = await client.get(
                "https://api.open-meteo.com/v1/forecast",
                params={
                    "latitude": lat, "longitude": lon,
                    "current": "uv_index",

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This request sends coordinates to NOAA again when checking surf zone alerts. The security issue is not the HTTPS call itself but the undisclosed transmission of user-linked location data to an external service in an agent workflow.

Content

Scanner excerpt · src/server.py (reported line 467)May include surrounding context.

python
try:
        async with httpx.AsyncClient(timeout=15.0) as client:
            # Get the forecast zone from the points endpoint
            points_url = f"https://api.weather.gov/points/{lat},{lon}"
            resp = await client.get(points_url, headers={"User-Agent": "BeachSafetyMCP/1.0"})
            if resp.status_code != 200:
                return "Unknown"

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · src/server.py (reported line 482)May include surrounding context.

python
zone_id = forecast_zone.split("/")[-1]

            # Fetch active alerts for this zone
            alerts_url = f"https://api.weather.gov/alerts/active/zone/{zone_id}"
            resp = await client.get(alerts_url, headers={"User-Agent": "BeachSafetyMCP/1.0"})
            if resp.status_code == 200:
                alerts_data = resp.json()

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The comment at L0521 states the code determines rip current risk using 'NOAA > alerts > heuristic fallback', and L0516 gathers surf-zone alerts. However, the unpacking at L0519 drops the fifth gathered result and the subsequent logic uses only NOAA forecast data or a heuristic, never the alert result. This is an active contradiction between the documented intent and the implemented behavior.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency is specified as httpx>=0.27.0, which allows future versions to be installed without review and does not guarantee reproducible builds. This can introduce vulnerable or breaking releases into the skill supply chain, especially in an external-networking skill that likely relies on HTTP client behavior.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
httpx>=0.27.0

Unverifiable Dependency: httpx has 2 known advisory(ies) (CVE-2021-41945 (Improper Input Validation in httpx); CVE-2021-41945 (Encode OSS httpx <=1.0.0.beta0 is affected by improper input validation in `http)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding

Because the manifest does not pin httpx to a specific version, it is impossible to verify whether the installed package is affected by known advisories. In a skill that likely makes outbound MCP/HTTP requests for beach and surf data, uncertainty around the HTTP client's security posture increases supply-chain and request-handling risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

User-supplied beach names are transmitted to third-party geocoding services, and coordinates are later sent to multiple external weather providers, but the tool descriptions do not clearly disclose that this user input leaves the local environment. In an agent setting, users may reasonably assume queries are processed locally, so this creates a privacy/transparency risk, especially for sensitive location queries.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The docstring at L0385 says the function will 'Find and fetch nearest NOAA NDBC buoy data', but the implementation immediately returns an empty dictionary and explicitly notes the feature is unimplemented. That is a direct contradiction between the function documentation and actual behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The docstring at L0425 says the function gets tide predictions from NOAA CO-OPS, but the implementation only contains a comment saying it is approximate for MVP and then returns an empty dictionary. This is a straightforward mismatch between stated behavior and code behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.