performing-scada-hmi-security-assessment
Perform security assessments of SCADA Human-Machine Interface (HMI) systems to identify vulnerabilities in web-based HMIs, thin-client configurations, authentication mechanisms, and communication channels between HMI and PLCs, aligned with IEC 62443 and NIST SP 800-82 guidelines.
Best use case
performing-scada-hmi-security-assessment is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Perform security assessments of SCADA Human-Machine Interface (HMI) systems to identify vulnerabilities in web-based HMIs, thin-client configurations, authentication mechanisms, and communication channels between HMI and PLCs, aligned with IEC 62443 and NIST SP 800-82 guidelines.
Teams using performing-scada-hmi-security-assessment should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/performing-scada-hmi-security-assessment/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How performing-scada-hmi-security-assessment Compares
| Feature / Agent | performing-scada-hmi-security-assessment | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Perform security assessments of SCADA Human-Machine Interface (HMI) systems to identify vulnerabilities in web-based HMIs, thin-client configurations, authentication mechanisms, and communication channels between HMI and PLCs, aligned with IEC 62443 and NIST SP 800-82 guidelines.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Performing SCADA HMI Security Assessment
## When to Use
- When assessing the security posture of HMI systems in SCADA/DCS environments
- When evaluating web-based HMI interfaces for common web vulnerabilities
- When auditing HMI authentication, authorization, and session management
- When testing communication security between HMIs and PLCs/RTUs
- When preparing for IEC 62443 or NERC CIP compliance assessments
**Do not use** for testing HMIs in active production without a maintenance window and rollback plan, for PLC-level protocol analysis (see performing-s7comm-protocol-security-analysis), or for general web application testing on non-OT systems.
## Prerequisites
- HMI system inventory with vendor, version, and network configuration details
- Lab or test environment mirroring production HMI setup (preferred for active testing)
- Authorization from plant operations for testing during maintenance windows
- NIST SP 800-82 and IEC 62443 security requirements documentation
- Network capture capability on HMI-to-PLC communication segment
## Workflow
### Step 1: Assess HMI Attack Surface
```python
#!/usr/bin/env python3
"""SCADA HMI Security Assessment Tool.
Evaluates HMI security across authentication, communication,
configuration, and web interface categories aligned with
IEC 62443 and NIST SP 800-82 requirements.
"""
import json
import sys
from datetime import datetime
from typing import Dict, List
try:
import requests
except ImportError:
print("Install requests: pip install requests")
sys.exit(1)
class HMISecurityAssessment:
"""Performs security assessment of SCADA HMI systems."""
def __init__(self, hmi_info: dict):
self.hmi_info = hmi_info
self.findings = []
self.checks_run = 0
self.checks_passed = 0
def check_authentication(self):
"""Assess HMI authentication mechanisms."""
checks = [
{
"id": "AUTH-01",
"name": "Password complexity enforcement",
"iec62443_ref": "ISA-62443-3-3 SR 1.7",
"description": "HMI must enforce minimum password complexity requirements",
"test": "Verify minimum length >= 8, complexity rules, history >= 5",
},
{
"id": "AUTH-02",
"name": "Account lockout policy",
"iec62443_ref": "ISA-62443-3-3 SR 1.11",
"description": "HMI must lock accounts after failed login attempts",
"test": "Verify lockout after 5 failed attempts, lockout duration >= 15 min",
},
{
"id": "AUTH-03",
"name": "Default credentials changed",
"iec62443_ref": "ISA-62443-3-3 SR 1.5",
"description": "All default vendor credentials must be changed",
"test": "Attempt login with known vendor defaults (admin/admin, operator/operator)",
},
{
"id": "AUTH-04",
"name": "Role-based access control",
"iec62443_ref": "ISA-62443-3-3 SR 2.1",
"description": "HMI must separate operator, engineer, and admin roles",
"test": "Verify operator role cannot access engineering functions",
},
{
"id": "AUTH-05",
"name": "Session timeout enforcement",
"iec62443_ref": "ISA-62443-3-3 SR 1.12",
"description": "HMI sessions must time out after inactivity",
"test": "Verify session timeout <= 15 minutes for operator, <= 5 for admin",
},
{
"id": "AUTH-06",
"name": "Multi-factor authentication for remote access",
"iec62443_ref": "ISA-62443-3-3 SR 1.13",
"description": "Remote HMI access requires MFA",
"test": "Verify MFA is enforced for all non-local HMI connections",
},
]
print(f"\n--- AUTHENTICATION ASSESSMENT ---")
for check in checks:
self.checks_run += 1
print(f" [{check['id']}] {check['name']}")
print(f" Ref: {check['iec62443_ref']}")
print(f" Test: {check['test']}")
def check_communication_security(self):
"""Assess HMI-to-PLC communication security."""
checks = [
{
"id": "COMM-01",
"name": "Encrypted HMI-PLC communication",
"description": "Traffic between HMI and PLCs should use encrypted protocols (OPC UA with TLS)",
"test": "Capture HMI-PLC traffic and verify encryption (Wireshark TLS handshake)",
},
{
"id": "COMM-02",
"name": "HMI write command authentication",
"description": "Write commands from HMI to PLC should be authenticated",
"test": "Verify that write operations require operator confirmation/authentication",
},
{
"id": "COMM-03",
"name": "Web HMI uses HTTPS",
"description": "Web-based HMI interfaces must use TLS 1.2+ with valid certificates",
"test": "Check TLS version, cipher suites, certificate validity",
},
{
"id": "COMM-04",
"name": "No cleartext protocols in use",
"description": "Telnet, FTP, HTTP must not be used for HMI access or management",
"test": "Port scan HMI for cleartext protocol services",
},
]
print(f"\n--- COMMUNICATION SECURITY ASSESSMENT ---")
for check in checks:
self.checks_run += 1
print(f" [{check['id']}] {check['name']}")
print(f" Test: {check['test']}")
def check_web_hmi_security(self):
"""Assess web-based HMI for common web vulnerabilities."""
hmi_url = self.hmi_info.get("url", "")
if not hmi_url:
print(f"\n [SKIP] No web HMI URL provided")
return
checks = [
{
"id": "WEB-01",
"name": "Cross-Site Scripting (XSS)",
"owasp": "A7:2017",
"test": "Test input fields with XSS payloads in tag names, alarm messages",
},
{
"id": "WEB-02",
"name": "Cross-Site Request Forgery (CSRF)",
"owasp": "A8:2013",
"test": "Verify CSRF tokens on state-changing operations (setpoint changes)",
},
{
"id": "WEB-03",
"name": "Insecure Direct Object References",
"owasp": "A4:2013",
"test": "Manipulate URL parameters to access other users HMI views",
},
{
"id": "WEB-04",
"name": "Security Headers",
"test": "Verify X-Frame-Options, CSP, X-Content-Type-Options headers",
},
{
"id": "WEB-05",
"name": "Privileged file system access (CVE-2025-0921)",
"test": "Check Ignition SCADA for privileged file system vulnerability via project files",
},
]
print(f"\n--- WEB HMI SECURITY ASSESSMENT ---")
print(f" Target: {hmi_url}")
for check in checks:
self.checks_run += 1
print(f" [{check['id']}] {check['name']}")
print(f" Test: {check['test']}")
def check_hardening(self):
"""Assess HMI operating system and application hardening."""
checks = [
{
"id": "HARD-01",
"name": "OS patch level",
"test": "Verify HMI OS is patched within SLA (typically 90 days for OT)",
},
{
"id": "HARD-02",
"name": "Unnecessary services disabled",
"test": "Verify no unnecessary network services running (RDP if not needed, SMB, etc)",
},
{
"id": "HARD-03",
"name": "USB port restrictions",
"test": "Verify USB mass storage is blocked on HMI terminals",
},
{
"id": "HARD-04",
"name": "Application whitelisting",
"test": "Verify only authorized HMI applications can execute",
},
{
"id": "HARD-05",
"name": "Audit logging enabled",
"test": "Verify operator actions, login events, and setpoint changes are logged",
},
]
print(f"\n--- HMI HARDENING ASSESSMENT ---")
for check in checks:
self.checks_run += 1
print(f" [{check['id']}] {check['name']}")
print(f" Test: {check['test']}")
def generate_report(self):
"""Generate assessment report."""
self.check_authentication()
self.check_communication_security()
self.check_web_hmi_security()
self.check_hardening()
print(f"\n{'='*70}")
print("SCADA HMI SECURITY ASSESSMENT SUMMARY")
print(f"{'='*70}")
print(f"Date: {datetime.now().isoformat()}")
print(f"HMI: {self.hmi_info.get('name', 'Unknown')}")
print(f"Vendor: {self.hmi_info.get('vendor', 'Unknown')}")
print(f"Version: {self.hmi_info.get('version', 'Unknown')}")
print(f"Total Checks: {self.checks_run}")
print(f"Findings: {len(self.findings)}")
if __name__ == "__main__":
assessment = HMISecurityAssessment(hmi_info={
"name": "Plant-HMI-01",
"vendor": "Siemens WinCC",
"version": "7.5 SP2",
"ip": "10.10.2.10",
"url": "https://10.10.2.10:8080",
"os": "Windows 10 LTSC 2021",
})
assessment.generate_report()
```
## Key Concepts
| Term | Definition |
|------|------------|
| HMI | Human-Machine Interface providing operators visual representation and control of industrial processes |
| Web HMI | Browser-based HMI interface accessible via HTTP/HTTPS, subject to standard web vulnerabilities |
| Setpoint | Target value for a process variable that operators can change through the HMI; unauthorized changes can cause process upset |
| Alarm Suppression | Attacker technique of disabling or hiding HMI alarms to mask malicious process manipulation |
| WinCC | Siemens SCADA/HMI software widely deployed in manufacturing and process industries |
| CVE-2025-0921 | Ignition SCADA privileged file system vulnerability exploitable through malicious project uploads |
## Output Format
```
HMI SECURITY ASSESSMENT REPORT
=================================
Date: YYYY-MM-DD
HMI: [name] | Vendor: [vendor] | Version: [version]
FINDINGS BY CATEGORY:
Authentication: [pass/fail count]
Communication: [pass/fail count]
Web Security: [pass/fail count]
Hardening: [pass/fail count]
CRITICAL FINDINGS:
1. [finding with remediation]
COMPLIANCE STATUS:
IEC 62443 SL-T: [target level]
IEC 62443 SL-A: [achieved level]
```Related Skills
triaging-security-incident
Performs initial triage of security incidents to determine severity, scope, and required response actions using the NIST SP 800-61r3 and SANS PICERL frameworks. Classifies incidents by type, assigns priority based on business impact, and routes to appropriate response teams. Activates for requests involving incident triage, security alert classification, severity assessment, incident prioritization, or initial incident analysis.
triaging-security-incident-with-ir-playbook
Classify and prioritize security incidents using structured IR playbooks to determine severity, assign response teams, and initiate appropriate response procedures.
triaging-security-alerts-in-splunk
Triages security alerts in Splunk Enterprise Security by classifying severity, investigating notable events, correlating related telemetry, and making escalation or closure decisions using SPL queries and the Incident Review dashboard. Use when SOC analysts face queued alerts from correlation searches, need to prioritize investigation order, or must document triage decisions for handoff to Tier 2/3 analysts.
tizen-security-compliance
Maps security requirements to implementation. Coordinates compliance against FIPS 140-3, OCF, CommonCriteria, and Tizen specification.
testing-websocket-api-security
Tests WebSocket API implementations for security vulnerabilities including missing authentication on WebSocket upgrade, Cross-Site WebSocket Hijacking (CSWSH), injection attacks through WebSocket messages, insufficient input validation, denial-of-service via message flooding, and information leakage through WebSocket frames. The tester intercepts WebSocket handshakes and messages using Burp Suite, crafts malicious payloads, and tests for authorization bypass on WebSocket channels. Activates for requests involving WebSocket security testing, WS penetration testing, CSWSH attack, or real-time API security assessment.
testing-jwt-token-security
Assessing JSON Web Token implementations for cryptographic weaknesses, algorithm confusion attacks, and authorization bypass vulnerabilities during security engagements.
testing-api-security-with-owasp-top-10
Systematically assessing REST and GraphQL API endpoints against the OWASP API Security Top 10 risks using automated and manual testing techniques.
static-security-analyzer
Wrapper around Tizen Studio static analyzer. Detects memory leaks, buffer overflows, and coding vulnerabilities in C/C++/JavaScript.
security-requirement-extraction
Derive security requirements from threat models and business context. Use when translating threats into actionable requirements, creating security user stories, or building security test cases.
performing-yara-rule-development-for-detection
Develop precise YARA rules for malware detection by identifying unique byte patterns, strings, and behavioral indicators in executable files while minimizing false positives.
performing-wireless-security-assessment-with-kismet
Conduct wireless network security assessments using Kismet to detect rogue access points, hidden SSIDs, weak encryption, and unauthorized clients through passive RF monitoring.
performing-wireless-network-penetration-test
Execute a wireless network penetration test to assess WiFi security by capturing handshakes, cracking WPA2/WPA3 keys, detecting rogue access points, and testing wireless segmentation using Aircrack-ng and related tools.