Back to skill

Security audit

jf-open-pro-ptz-control

Security checks across malware telemetry and agentic risk

Overview

This skill is a disclosed PTZ camera-control tool, but it gives high-impact camera movement and patrol authority with broad trigger phrasing and an unvalidated endpoint override.

Install only for authorized operators of the target JF PTZ devices. Keep JF_ENDPOINT set to one of the documented vendor regional hosts, protect JF_APP_SECRET and JF_DEVICE_TOKEN, and require explicit confirmation before movement, preset deletion, tour start, or tour clearing actions.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (9)

Tainted flow: 'url' from os.getenv (line 271, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
}
    }
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:
Confidence
83% confidence
Finding
response = requests.post(url, headers=headers, json=body, timeout=30)

Tainted flow: 'url' from os.getenv (line 271, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
}
    }
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:
Confidence
83% confidence
Finding
response = requests.post(url, headers=headers, json=body, timeout=30)

Tainted flow: 'url' from os.getenv (line 271, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
if command in ["set", "set-name"] and preset_name:
        body["OPPTZControl"]["Parameter"]["PresetName"] = preset_name
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:
Confidence
83% confidence
Finding
response = requests.post(url, headers=headers, json=body, timeout=30)

Tainted flow: 'url' from os.getenv (line 271, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
body["OPPTZControl"]["Parameter"]["Preset"] = preset
        body["OPPTZControl"]["Parameter"]["Step"] = step
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:
Confidence
83% confidence
Finding
response = requests.post(url, headers=headers, json=body, timeout=30)

Tainted flow: 'url' from os.getenv (line 271, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
body = {"Name": "Uart.PTZPreset"}
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:
Confidence
80% confidence
Finding
response = requests.post(url, headers=headers, json=body, timeout=30)

Tainted flow: 'url' from os.getenv (line 271, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
body = {"Name": "Uart.PTZTour"}
    
    response = requests.post(url, headers=headers, json=body, timeout=30)
    result = response.json()
    
    if result.get("code") != 2000:
Confidence
80% confidence
Finding
response = requests.post(url, headers=headers, json=body, timeout=30)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill documentation clearly instructs use of environment variables containing sensitive credentials and device tokens, and describes outbound API access, but no explicit permission declaration is present. That creates a real trust and review gap: operators may invoke a skill with network and secret access without an upfront, machine-readable declaration of those capabilities.

Vague Triggers

Medium
Confidence
84% confidence
Finding
The trigger phrases are broad and overlap with common natural language such as direction, zoom, preset, and patrol-related words. In a PTZ control skill, accidental invocation can directly move cameras, change surveillance coverage, or start automated patrol behavior, making misfires operationally and privacy-relevant rather than merely inconvenient.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This skill controls live camera orientation, zoom, presets, and tours, but the description lacks a clear warning that activating it can alter monitoring coverage and affect privacy or physical-site awareness. Users may not realize that a simple command can redirect a surveillance device away from intended areas or expose other areas, increasing the chance of unsafe or privacy-invasive use.

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

No suspicious patterns detected.