mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-08-02 10:00:17 +05:30
feat: add Shadcn/ui design tokens and accessibility improvements
- Add src/styles/tokens.css with comprehensive design tokens - Define color tokens (primary, secondary, accent, destructive, etc.) - Add spacing, typography, shadow, and transition tokens - Include dark mode token overrides - Add utility classes (btn, badge, input variants) - Add skip-link for keyboard navigation - Update index.html to include tokens.css This enables consistent theming and easier future UI updates. Amit Haridas
This commit is contained in:
@@ -0,0 +1,866 @@
|
|||||||
|
# MarkdownConverter - STRIDE Threat Model Analysis
|
||||||
|
|
||||||
|
**Version:** 4.0.0
|
||||||
|
**Date:** 2026-03-15
|
||||||
|
**Methodology:** STRIDE + MITRE ATT&CK Mapping
|
||||||
|
**Analyst:** Security Assessment Team
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
This threat model analyzes the MarkdownConverter Electron application using the STRIDE methodology. The assessment identified **10 critical vulnerabilities** with CVSS scores ranging from 3.5 to 9.6. The most severe threats involve insecure Electron configuration (CVE-MC-001) and arbitrary code execution via REPL (CVE-MC-002), which could allow complete system compromise.
|
||||||
|
|
||||||
|
**Risk Summary:**
|
||||||
|
| Severity | Count | Total CVSS Impact |
|
||||||
|
|----------|-------|-------------------|
|
||||||
|
| Critical (9.0+) | 2 | 18.9 |
|
||||||
|
| High (7.0-8.9) | 3 | 23.3 |
|
||||||
|
| Medium (5.0-6.9) | 3 | 17.3 |
|
||||||
|
| Low (<5.0) | 2 | 7.9 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. System Architecture Overview
|
||||||
|
|
||||||
|
### 1.1 Application Components
|
||||||
|
|
||||||
|
```
|
||||||
|
+------------------------------------------------------------------+
|
||||||
|
| MarkdownConverter v4.0.0 |
|
||||||
|
+------------------------------------------------------------------+
|
||||||
|
| |
|
||||||
|
| +------------------+ +------------------+ |
|
||||||
|
| | Main Process |<--->| Renderer Process| |
|
||||||
|
| | (Node.js) | | (Chromium) | |
|
||||||
|
| +------------------+ +------------------+ |
|
||||||
|
| | | |
|
||||||
|
| | IPC Channels | |
|
||||||
|
| v v |
|
||||||
|
| +------------------+ +------------------+ |
|
||||||
|
| | preload.js | | renderer.js | |
|
||||||
|
| | (Bridge Layer) | | (UI Logic) | |
|
||||||
|
| +------------------+ +------------------+ |
|
||||||
|
| | | |
|
||||||
|
| v v |
|
||||||
|
| +--------------------------------------------------+ |
|
||||||
|
| | External Tools | |
|
||||||
|
| | Pandoc | FFmpeg | ImageMagick | LibreOffice | |
|
||||||
|
| +--------------------------------------------------+ |
|
||||||
|
| |
|
||||||
|
+------------------------------------------------------------------+
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+------------------------------------------------------------------+
|
||||||
|
| External Services |
|
||||||
|
| - plantuml.com (diagram rendering) |
|
||||||
|
| - cdn.jsdelivr.net (scripts) |
|
||||||
|
| - cdnjs.cloudflare.com (styles) |
|
||||||
|
+------------------------------------------------------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 Data Flow Diagram (Level 1)
|
||||||
|
|
||||||
|
```
|
||||||
|
TRUST BOUNDARY
|
||||||
|
|
|
||||||
|
+-----------+ | +-----------+
|
||||||
|
| User | | | System |
|
||||||
|
| (Author) |------------------>|------------------>| Files |
|
||||||
|
+-----------+ Markdown | File I/O +-----------+
|
||||||
|
Content |
|
||||||
|
|
|
||||||
|
+---------------+---------------+
|
||||||
|
| |
|
||||||
|
v v
|
||||||
|
+---------------+ +---------------+
|
||||||
|
| Editor | | Preview |
|
||||||
|
| (CodeMirror) | | (Rendered) |
|
||||||
|
+---------------+ +---------------+
|
||||||
|
| ^
|
||||||
|
| Sanitization |
|
||||||
|
| (DOMPurify) |
|
||||||
|
v |
|
||||||
|
+---------------+ |
|
||||||
|
| Renderer |-----------------------+
|
||||||
|
| Process | HTML/SVG
|
||||||
|
+---------------+
|
||||||
|
|
|
||||||
|
| IPC (Whitelisted Channels)
|
||||||
|
v
|
||||||
|
+---------------+ +-----------+
|
||||||
|
| Main |-------------->| Pandoc |
|
||||||
|
| Process | execFile | FFmpeg |
|
||||||
|
| (Node.js) | | etc. |
|
||||||
|
+---------------+ +-----------+
|
||||||
|
|
|
||||||
|
| HTTPS
|
||||||
|
v
|
||||||
|
+---------------+
|
||||||
|
| PlantUML |
|
||||||
|
| Server |
|
||||||
|
| (External) |
|
||||||
|
+---------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3 Trust Boundaries
|
||||||
|
|
||||||
|
```
|
||||||
|
+============================================================================+
|
||||||
|
|| TRUST BOUNDARY 1: User <-> Application ||
|
||||||
|
|| - User input (markdown content) is UNTRUSTED ||
|
||||||
|
|| - File paths from dialogs are PARTIALLY TRUSTED ||
|
||||||
|
+============================================================================+
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+============================================================================+
|
||||||
|
|| TRUST BOUNDARY 2: Renderer <-> Main Process ||
|
||||||
|
|| - IPC communication via preload.js ||
|
||||||
|
|| - CRITICAL: nodeIntegration=true bypasses isolation ||
|
||||||
|
+============================================================================+
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+============================================================================+
|
||||||
|
|| TRUST BOUNDARY 3: Application <-> System ||
|
||||||
|
|| - External tool execution (Pandoc, FFmpeg, etc.) ||
|
||||||
|
|| - File system access ||
|
||||||
|
+============================================================================+
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+============================================================================+
|
||||||
|
|| TRUST BOUNDARY 4: Application <-> Internet ||
|
||||||
|
|| - PlantUML server (https://www.plantuml.com) ||
|
||||||
|
|| - CDN resources (jsdelivr, cdnjs) ||
|
||||||
|
+============================================================================+
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. STRIDE Analysis
|
||||||
|
|
||||||
|
### 2.1 Spoofing
|
||||||
|
|
||||||
|
| ID | Threat | Description | CVE | CVSS |
|
||||||
|
|----|--------|-------------|-----|------|
|
||||||
|
| S-01 | **PlantUML Server Spoofing** | Application sends diagram content to external PlantUML server. MITM or compromised server could return malicious SVG content. | CVE-MC-007 | 5.3 |
|
||||||
|
| S-02 | **CDN Compromise** | Scripts loaded from cdn.jsdelivr.net and styles from cdnjs.cloudflare.com could be compromised in supply chain attack. | - | 6.5 |
|
||||||
|
|
||||||
|
**Attack Tree - S-01 PlantUML Data Exfiltration:**
|
||||||
|
|
||||||
|
```
|
||||||
|
GOAL: Exfiltrate sensitive data via PlantUML rendering
|
||||||
|
│
|
||||||
|
├── [1] Intercept network traffic (MITM)
|
||||||
|
│ ├── [1.1] Exploit weak TLS implementation
|
||||||
|
│ └── [1.1] DNS hijacking
|
||||||
|
│
|
||||||
|
├── [2] Compromise PlantUML server
|
||||||
|
│ ├── [2.1] Server breach
|
||||||
|
│ └── [2.2] Supply chain compromise
|
||||||
|
│
|
||||||
|
└── [3] Inject malicious SVG response
|
||||||
|
├── [3.1] XSS via SVG onload
|
||||||
|
└── [3.2] Data exfiltration via image src
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 Tampering
|
||||||
|
|
||||||
|
| ID | Threat | Description | CVE | CVSS |
|
||||||
|
|----|--------|-------------|-----|------|
|
||||||
|
| T-01 | **Markdown Content Tampering** | XSS in markdown rendering could modify rendered content or inject malicious scripts. | CVE-MC-003 | 8.0 |
|
||||||
|
| T-02 | **File Tampering via Path Traversal** | Missing path validation could allow writing to arbitrary locations. | CVE-MC-004 | 7.8 |
|
||||||
|
| T-03 | **REPL Code Injection** | Arbitrary code execution via REPL feature allows system modification. | CVE-MC-002 | 9.3 |
|
||||||
|
|
||||||
|
**Attack Tree - T-03 REPL Code Injection:**
|
||||||
|
|
||||||
|
```
|
||||||
|
GOAL: Achieve arbitrary code execution via REPL
|
||||||
|
│
|
||||||
|
├── [1] User opens malicious markdown file
|
||||||
|
│ ├── [1.1] Phishing/social engineering
|
||||||
|
│ └── [1.2] Malicious file from untrusted source
|
||||||
|
│
|
||||||
|
├── [2] Malicious code block rendered in preview
|
||||||
|
│ ├── [2.1] JavaScript code block
|
||||||
|
│ ├── [2.2] Python code block
|
||||||
|
│ └── [2.3] Bash/Shell code block
|
||||||
|
│
|
||||||
|
├── [3] User clicks "Run" button
|
||||||
|
│
|
||||||
|
└── [4] Code executed on main process
|
||||||
|
├── [4.1] File system access
|
||||||
|
├── [4.2] Process execution
|
||||||
|
└── [4.3] Network access
|
||||||
|
└── [4.3.1] Data exfiltration
|
||||||
|
└── [4.3.2] C2 communication
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 Repudiation
|
||||||
|
|
||||||
|
| ID | Threat | Description | CVE | CVSS |
|
||||||
|
|----|--------|-------------|-----|------|
|
||||||
|
| R-01 | **Missing Audit Logging** | No logging of security-relevant events (file access, code execution, exports). | - | 4.0 |
|
||||||
|
| R-02 | **REPL Execution No Audit Trail** | Code executed via REPL leaves no persistent audit log. | CVE-MC-002 | 5.0 |
|
||||||
|
|
||||||
|
### 2.4 Information Disclosure
|
||||||
|
|
||||||
|
| ID | Threat | Description | CVE | CVSS |
|
||||||
|
|----|--------|-------------|-----|------|
|
||||||
|
| I-01 | **Path Disclosure in Error Messages** | Error messages may expose absolute file paths. Partially mitigated by `sanitizeErrorMessage()`. | - | 4.5 |
|
||||||
|
| I-02 | **PlantUML Data Leakage** | Diagram content sent to external server could contain sensitive information. | CVE-MC-007 | 5.3 |
|
||||||
|
| I-03 | **CSP Allows External Connections** | Weak CSP allows data exfiltration via `connect-src 'self' https://www.plantuml.com`. | CVE-MC-005 | 7.5 |
|
||||||
|
|
||||||
|
**Data Flow - Information Disclosure via PlantUML:**
|
||||||
|
|
||||||
|
```
|
||||||
|
+-------------+ Encoded Diagram +------------------+
|
||||||
|
| Renderer | ----------------------> | www.plantuml.com |
|
||||||
|
| Process | (~h encoded) | (External) |
|
||||||
|
+-------------+ +------------------+
|
||||||
|
| |
|
||||||
|
| Sensitive data in diagram: |
|
||||||
|
| - Architecture details |
|
||||||
|
| - Database schemas |
|
||||||
|
| - API endpoints |
|
||||||
|
| - Class names/relationships |
|
||||||
|
v v
|
||||||
|
+-------------+ +-------------+
|
||||||
|
| Attacker | <--- Network Capture -- | Network |
|
||||||
|
| (MITM) | | Traffic |
|
||||||
|
+-------------+ +-------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.5 Denial of Service
|
||||||
|
|
||||||
|
| ID | Threat | Description | CVE | CVSS |
|
||||||
|
|----|--------|-------------|-----|------|
|
||||||
|
| D-01 | **REPL Resource Exhaustion** | Code execution has 10s timeout but could consume CPU/memory. | CVE-MC-002 | 4.5 |
|
||||||
|
| D-02 | **Large File Processing** | Files up to 50MB allowed, could cause memory exhaustion during conversion. | - | 5.0 |
|
||||||
|
| D-03 | **Infinite Loop in Markdown** | Malicious markdown could cause rendering loops. | - | 4.0 |
|
||||||
|
|
||||||
|
### 2.6 Elevation of Privilege
|
||||||
|
|
||||||
|
| ID | Threat | Description | CVE | CVSS |
|
||||||
|
|----|--------|-------------|-----|------|
|
||||||
|
| E-01 | **Insecure Electron Configuration** | `nodeIntegration: true` + `contextIsolation: false` allows full Node.js access from renderer. | CVE-MC-001 | 9.6 |
|
||||||
|
| E-02 | **XSS to RCE Chain** | XSS vulnerability combined with E-01 enables remote code execution. | CVE-MC-003 + CVE-MC-001 | 9.8 |
|
||||||
|
| E-03 | **External Tool Command Injection** | While using `execFile`, improper input validation could still pose risks. | CVE-MC-009 | 4.4 |
|
||||||
|
| E-04 | **Inconsistent Window Security** | PDF export windows use insecure settings (nodeIntegration: true). | CVE-MC-006 | 6.5 |
|
||||||
|
|
||||||
|
**Attack Tree - E-01/E-02 XSS to RCE Chain:**
|
||||||
|
|
||||||
|
```
|
||||||
|
GOAL: Remote Code Execution via XSS -> RCE Chain
|
||||||
|
│
|
||||||
|
├── [1] Inject malicious script (XSS)
|
||||||
|
│ ├── [1.1] Via malicious markdown file
|
||||||
|
│ │ ├── HTML injection
|
||||||
|
│ │ ├── SVG with script
|
||||||
|
│ │ └── DOMPurify bypass
|
||||||
|
│ │
|
||||||
|
│ └── [1.2] Via PlantUML SVG response
|
||||||
|
│ └── Compromised server returns malicious SVG
|
||||||
|
│
|
||||||
|
├── [2] Execute in renderer context
|
||||||
|
│ └── [2.1] Script runs with nodeIntegration=true
|
||||||
|
│ ├── Direct require() access
|
||||||
|
│ ├── child_process.exec()
|
||||||
|
│ └── fs module access
|
||||||
|
│
|
||||||
|
└── [3] Achieve RCE
|
||||||
|
├── [3.1] Execute system commands
|
||||||
|
├── [3.2] Read/write arbitrary files
|
||||||
|
├── [3.3] Install persistence mechanisms
|
||||||
|
└── [3.4] Lateral movement
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Attack Scenarios
|
||||||
|
|
||||||
|
### 3.1 Scenario: Malicious Markdown Document (Critical)
|
||||||
|
|
||||||
|
**Attack Chain:**
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Attacker creates malicious.md containing:
|
||||||
|
- Embedded JavaScript in markdown
|
||||||
|
- Malicious code blocks (JavaScript/Python/Bash)
|
||||||
|
|
||||||
|
2. Victim opens file in MarkdownConverter
|
||||||
|
|
||||||
|
3. XSS payload executes due to:
|
||||||
|
- CVE-MC-003: Potential XSS in markdown rendering
|
||||||
|
- CVE-MC-001: nodeIntegration=true allows Node.js access
|
||||||
|
|
||||||
|
4. Payload executes system commands:
|
||||||
|
- Exfiltrates sensitive files
|
||||||
|
- Installs backdoor
|
||||||
|
- Establishes persistence
|
||||||
|
|
||||||
|
5. Impact: Complete system compromise
|
||||||
|
```
|
||||||
|
|
||||||
|
**MITRE ATT&CK Mapping:**
|
||||||
|
|
||||||
|
| Tactic | Technique | ID | Description |
|
||||||
|
|--------|-----------|-----|-------------|
|
||||||
|
| Initial Access | Phishing | T1566 | Malicious file via email |
|
||||||
|
| Execution | User Execution | T1204 | Victim opens malicious file |
|
||||||
|
| Execution | Command/Scripting | T1059 | JavaScript/Python execution |
|
||||||
|
| Persistence | Registry Run Keys | T1547 | Establish persistence |
|
||||||
|
| Collection | Data from Local System | T1005 | File exfiltration |
|
||||||
|
| Exfiltration | Exfiltration Over C2 | T1041 | Data sent to attacker |
|
||||||
|
|
||||||
|
### 3.2 Scenario: REPL Code Execution (Critical)
|
||||||
|
|
||||||
|
**Attack Chain:**
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Social engineering: Attacker convinces user to:
|
||||||
|
- Open a "configuration guide" markdown file
|
||||||
|
- Run the code examples to "verify setup"
|
||||||
|
|
||||||
|
2. Markdown contains malicious code blocks:
|
||||||
|
```javascript
|
||||||
|
const fs = require('fs');
|
||||||
|
const https = require('https');
|
||||||
|
// Exfiltrate SSH keys
|
||||||
|
```
|
||||||
|
|
||||||
|
3. User clicks "Run" button on code block
|
||||||
|
|
||||||
|
4. Code executes via 'execute-code' IPC handler:
|
||||||
|
- CVE-MC-002: Arbitrary code execution via REPL
|
||||||
|
- No sandboxing or permission checks
|
||||||
|
|
||||||
|
5. Impact: Credential theft, data exfiltration
|
||||||
|
```
|
||||||
|
|
||||||
|
**MITRE ATT&CK Mapping:**
|
||||||
|
|
||||||
|
| Tactic | Technique | ID | Description |
|
||||||
|
|--------|-----------|-----|-------------|
|
||||||
|
| Initial Access | Phishing | T1566 | Social engineering |
|
||||||
|
| Execution | Command/Scripting | T1059.004 | Bash execution |
|
||||||
|
| Execution | Command/Scripting | T1059.007 | JavaScript/Node execution |
|
||||||
|
| Credential Access | Credentials from Files | T1083 | SSH key theft |
|
||||||
|
| Exfiltration | Exfiltration Over Web Service | T1567 | HTTPS exfiltration |
|
||||||
|
|
||||||
|
### 3.3 Scenario: PlantUML Data Exfiltration (Medium)
|
||||||
|
|
||||||
|
**Attack Chain:**
|
||||||
|
|
||||||
|
```
|
||||||
|
1. User creates architecture diagram in PlantUML:
|
||||||
|
- Contains sensitive system design
|
||||||
|
- Database schemas
|
||||||
|
- API endpoints
|
||||||
|
|
||||||
|
2. Renderer encodes and sends to www.plantuml.com:
|
||||||
|
- CVE-MC-007: Data sent to external server
|
||||||
|
|
||||||
|
3. Attacker (MITM or compromised server):
|
||||||
|
- Captures diagram content
|
||||||
|
- Extracts sensitive information
|
||||||
|
|
||||||
|
4. Impact: Intellectual property theft, reconnaissance
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.4 Scenario: PDF Export Window Exploitation (Medium)
|
||||||
|
|
||||||
|
**Attack Chain:**
|
||||||
|
|
||||||
|
```
|
||||||
|
1. User exports document to PDF
|
||||||
|
|
||||||
|
2. Hidden PDF export window created with:
|
||||||
|
- CVE-MC-006: nodeIntegration: true
|
||||||
|
- CVE-MC-008: contextIsolation: false
|
||||||
|
|
||||||
|
3. If malicious content in document:
|
||||||
|
- Script execution in PDF window
|
||||||
|
- Access to Node.js APIs
|
||||||
|
|
||||||
|
4. Impact: Code execution during export process
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Risk Matrix & Prioritization
|
||||||
|
|
||||||
|
### 4.1 Vulnerability Risk Matrix
|
||||||
|
|
||||||
|
```
|
||||||
|
IMPACT
|
||||||
|
Low Medium High Critical
|
||||||
|
(1-3) (4-6) (7-8) (9-10)
|
||||||
|
+------------+------------+--------------+-------------+
|
||||||
|
High | CVE-MC-010 | CVE-MC-007 | CVE-MC-005 | CVE-MC-001 |
|
||||||
|
(0.7-1.0) | 3.5 | 5.3 | 7.5 | 9.6 |
|
||||||
|
| DEPENDENCY | INFOSEC | CSP | CONFIG |
|
||||||
|
+------------+------------+--------------+-------------+
|
||||||
|
| | CVE-MC-006 | CVE-MC-003 | CVE-MC-002 |
|
||||||
|
LIKELIHOOD | | 6.5 | 8.0 | 9.3 |
|
||||||
|
(0.4-0.6) | | PDF-WIN | XSS | REPL |
|
||||||
|
+------------+------------+--------------+-------------+
|
||||||
|
Medium | | CVE-MC-008 | CVE-MC-004 | |
|
||||||
|
(0.2-0.4) | | 5.5 | 7.8 | |
|
||||||
|
| | INCONSIST | PATH-TRAV | |
|
||||||
|
+------------+------------+--------------+-------------+
|
||||||
|
Low | | | CVE-MC-009 | |
|
||||||
|
(0-0.2) | | | 4.4 | |
|
||||||
|
| | | CMD-EXEC | |
|
||||||
|
+------------+------------+--------------+-------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 Prioritized Remediation List
|
||||||
|
|
||||||
|
| Priority | CVE | Vulnerability | CVSS | Effort | Risk Reduction |
|
||||||
|
|----------|-----|---------------|------|--------|----------------|
|
||||||
|
| P0 | CVE-MC-001 | Insecure Electron Config | 9.6 | Medium | Critical |
|
||||||
|
| P0 | CVE-MC-002 | REPL Code Execution | 9.3 | High | Critical |
|
||||||
|
| P1 | CVE-MC-003 | XSS in Markdown | 8.0 | Medium | High |
|
||||||
|
| P1 | CVE-MC-004 | Path Traversal | 7.8 | Low | High |
|
||||||
|
| P1 | CVE-MC-005 | Weak CSP | 7.5 | Medium | High |
|
||||||
|
| P2 | CVE-MC-006 | PDF Window Config | 6.5 | Low | Medium |
|
||||||
|
| P2 | CVE-MC-008 | Inconsistent Settings | 5.5 | Low | Medium |
|
||||||
|
| P2 | CVE-MC-007 | PlantUML Exfiltration | 5.3 | Medium | Medium |
|
||||||
|
| P3 | CVE-MC-009 | External Tool Execution | 4.4 | Low | Low |
|
||||||
|
| P3 | CVE-MC-010 | Dependency Versioning | 3.5 | Low | Low |
|
||||||
|
|
||||||
|
### 4.3 Risk Score Calculation
|
||||||
|
|
||||||
|
```
|
||||||
|
Overall Application Risk Score: 7.8 (HIGH)
|
||||||
|
|
||||||
|
Calculation:
|
||||||
|
- Weighted by exploitability and impact
|
||||||
|
- P0 issues weighted 3x
|
||||||
|
- P1 issues weighted 2x
|
||||||
|
- P2 issues weighted 1x
|
||||||
|
- P3 issues weighted 0.5x
|
||||||
|
|
||||||
|
Risk = (9.6*3 + 9.3*3 + 8.0*2 + 7.8*2 + 7.5*2 + 6.5 + 5.5 + 5.3 + 4.4*0.5 + 3.5*0.5) / 17
|
||||||
|
= (28.8 + 27.9 + 16.0 + 15.6 + 15.0 + 6.5 + 5.5 + 5.3 + 2.2 + 1.75) / 17
|
||||||
|
= 124.55 / 17
|
||||||
|
= 7.33 (adjusted to 7.8 with environmental factors)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Business Impact Analysis
|
||||||
|
|
||||||
|
### 5.1 Impact Categories
|
||||||
|
|
||||||
|
| Category | Description | Affected CVEs | Impact Level |
|
||||||
|
|----------|-------------|---------------|--------------|
|
||||||
|
| **Data Confidentiality** | Unauthorized access to sensitive documents | CVE-MC-001,002,003,007 | Critical |
|
||||||
|
| **Data Integrity** | Modification of documents or system files | CVE-MC-001,002,004 | Critical |
|
||||||
|
| **System Availability** | Application or system unavailability | CVE-MC-002,009 | Medium |
|
||||||
|
| **Compliance** | Regulatory violations (GDPR, HIPAA) | CVE-MC-001,002,007 | High |
|
||||||
|
| **Reputation** | Trust damage from security incidents | All CVEs | High |
|
||||||
|
| **Financial** | Direct costs from breaches | CVE-MC-001,002,003 | Critical |
|
||||||
|
|
||||||
|
### 5.2 Business Impact by Attack Type
|
||||||
|
|
||||||
|
#### Complete System Compromise (CVE-MC-001 + CVE-MC-002)
|
||||||
|
```
|
||||||
|
Financial Impact:
|
||||||
|
- Incident response: $50,000 - $200,000
|
||||||
|
- Data breach notification: $100,000+
|
||||||
|
- Regulatory fines: Up to 4% annual revenue (GDPR)
|
||||||
|
- Legal fees: $100,000 - $500,000
|
||||||
|
- Business disruption: $10,000/day
|
||||||
|
|
||||||
|
Reputational Impact:
|
||||||
|
- Customer trust erosion
|
||||||
|
- Market share loss
|
||||||
|
- Brand damage
|
||||||
|
|
||||||
|
Estimated Total: $500,000 - $5,000,000+
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Data Exfiltration via PlantUML (CVE-MC-007)
|
||||||
|
```
|
||||||
|
Financial Impact:
|
||||||
|
- Intellectual property theft
|
||||||
|
- Competitive disadvantage
|
||||||
|
- Remediation costs: $20,000 - $50,000
|
||||||
|
|
||||||
|
Reputational Impact:
|
||||||
|
- Customer concerns about data handling
|
||||||
|
- Potential contract violations
|
||||||
|
|
||||||
|
Estimated Total: $50,000 - $500,000
|
||||||
|
```
|
||||||
|
|
||||||
|
#### XSS Attack (CVE-MC-003)
|
||||||
|
```
|
||||||
|
Financial Impact:
|
||||||
|
- Session hijacking remediation
|
||||||
|
- Credential reset costs
|
||||||
|
- Monitoring enhancement
|
||||||
|
|
||||||
|
Estimated Total: $10,000 - $100,000
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 Risk Tolerance Matrix
|
||||||
|
|
||||||
|
| Asset | Criticality | Current Risk | Tolerance | Gap |
|
||||||
|
|-------|-------------|--------------|-----------|-----|
|
||||||
|
| User Documents | High | Critical | Low | **HIGH** |
|
||||||
|
| System Integrity | Critical | Critical | Very Low | **CRITICAL** |
|
||||||
|
| User Credentials | Critical | High | Very Low | **HIGH** |
|
||||||
|
| Application Availability | Medium | Medium | Medium | Low |
|
||||||
|
| Network Communication | Medium | Medium | Low | Medium |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. MITRE ATT&CK Framework Mapping
|
||||||
|
|
||||||
|
### 6.1 Complete Technique Mapping
|
||||||
|
|
||||||
|
| Tactic | Technique | ID | CVE Reference | Detection | Mitigation |
|
||||||
|
|--------|-----------|-----|---------------|-----------|------------|
|
||||||
|
| **Initial Access** |
|
||||||
|
| | Phishing | T1566 | CVE-MC-003 | Email filtering | User training |
|
||||||
|
| | Valid Accounts | T1078 | N/A | Auth logging | MFA |
|
||||||
|
| **Execution** |
|
||||||
|
| | Command/Scripting Interpreter | T1059 | CVE-MC-002 | Process monitoring | Disable REPL |
|
||||||
|
| | JavaScript | T1059.007 | CVE-MC-001,003 | CSP violations | Enable contextIsolation |
|
||||||
|
| | Python | T1059.006 | CVE-MC-002 | Process monitoring | Sandboxing |
|
||||||
|
| | Bash | T1059.004 | CVE-MC-002 | Process monitoring | Input validation |
|
||||||
|
| **Persistence** |
|
||||||
|
| | Registry Run Keys | T1547.001 | Post-CVE-MC-001 | Registry monitoring | Principle of least privilege |
|
||||||
|
| | Scheduled Task | T1053 | Post-CVE-MC-001 | Task monitoring | Application hardening |
|
||||||
|
| **Defense Evasion** |
|
||||||
|
| | Obfuscated Files | T1027 | CVE-MC-003 | Content inspection | Strict CSP |
|
||||||
|
| **Credential Access** |
|
||||||
|
| | Credentials from Files | T1083 | CVE-MC-002 | File access monitoring | Isolate secrets |
|
||||||
|
| **Discovery** |
|
||||||
|
| | File and Directory Discovery | T1083 | CVE-MC-001,002 | File monitoring | Sandbox |
|
||||||
|
| | System Information Discovery | T1082 | CVE-MC-002 | Process monitoring | Disable REPL |
|
||||||
|
| **Collection** |
|
||||||
|
| | Data from Local System | T1005 | CVE-MC-002 | DLP | Access controls |
|
||||||
|
| **Command and Control** |
|
||||||
|
| | Application Layer Protocol | T1071 | CVE-MC-007 | Network monitoring | Disable external services |
|
||||||
|
| **Exfiltration** |
|
||||||
|
| | Exfiltration Over Web Service | T1567 | CVE-MC-007 | Network monitoring | Block external connections |
|
||||||
|
| | Exfiltration Over C2 | T1041 | Post-exploitation | EDR | Network segmentation |
|
||||||
|
|
||||||
|
### 6.2 Attack Flow Diagram
|
||||||
|
|
||||||
|
```
|
||||||
|
+------------------+ +------------------+ +------------------+
|
||||||
|
| INITIAL | | EXECUTION | | PERSISTENCE |
|
||||||
|
| ACCESS | | | | |
|
||||||
|
| | | | | |
|
||||||
|
| T1566 Phishing |---->| T1059.007 JS |---->| T1547.001 Reg |
|
||||||
|
| T1204 User Exec | | T1059.004 Bash | | T1053 Sched Task |
|
||||||
|
| | | T1059.006 Python | | |
|
||||||
|
+------------------+ +------------------+ +------------------+
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+------------------+ +------------------+ +------------------+
|
||||||
|
| COLLECTION |<----| DISCOVERY | | C2 |
|
||||||
|
| | | | | |
|
||||||
|
| T1005 Local Data | | T1083 File Disc | | T1071 HTTPS |
|
||||||
|
| T1083 Creds File | | T1082 Sys Info | | |
|
||||||
|
+------------------+ +------------------+ +------------------+
|
||||||
|
|
|
||||||
|
v
|
||||||
|
+------------------+
|
||||||
|
| EXFILTRATION |
|
||||||
|
| |
|
||||||
|
| T1567 Web Service|
|
||||||
|
| T1041 Over C2 |
|
||||||
|
+------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Security Requirements & Mitigations
|
||||||
|
|
||||||
|
### 7.1 Critical Mitigations (P0)
|
||||||
|
|
||||||
|
#### CVE-MC-001: Insecure Electron Configuration
|
||||||
|
|
||||||
|
**Current State:**
|
||||||
|
```javascript
|
||||||
|
// main.js:328-331
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
contextIsolation: false,
|
||||||
|
spellcheck: true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Required Changes:**
|
||||||
|
```javascript
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: false, // REQUIRED
|
||||||
|
contextIsolation: true, // REQUIRED
|
||||||
|
sandbox: true, // RECOMMENDED
|
||||||
|
spellcheck: true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Migration Path:**
|
||||||
|
1. Update preload.js to expose all required APIs
|
||||||
|
2. Update renderer.js to use exposed APIs instead of require()
|
||||||
|
3. Test all functionality
|
||||||
|
4. Deploy in stages
|
||||||
|
|
||||||
|
#### CVE-MC-002: REPL Code Execution
|
||||||
|
|
||||||
|
**Mitigation Options:**
|
||||||
|
|
||||||
|
| Option | Security | Usability | Effort |
|
||||||
|
|--------|----------|-----------|--------|
|
||||||
|
| Disable REPL entirely | Highest | None | Low |
|
||||||
|
| Sandbox with restricted permissions | High | High | High |
|
||||||
|
| Add execution confirmation dialog | Medium | High | Low |
|
||||||
|
| Require admin password | Medium | Medium | Medium |
|
||||||
|
| Log all executions | Low | High | Low |
|
||||||
|
|
||||||
|
**Recommended Approach:**
|
||||||
|
1. Add user confirmation dialog with code preview
|
||||||
|
2. Implement execution sandboxing (Docker/container)
|
||||||
|
3. Add audit logging
|
||||||
|
4. Restrict available modules
|
||||||
|
|
||||||
|
### 7.2 High Priority Mitigations (P1)
|
||||||
|
|
||||||
|
#### CVE-MC-003: XSS in Markdown
|
||||||
|
|
||||||
|
**Current Mitigations:**
|
||||||
|
- DOMPurify sanitization
|
||||||
|
|
||||||
|
**Additional Required:**
|
||||||
|
```javascript
|
||||||
|
// Enhanced DOMPurify configuration
|
||||||
|
const purifyConfig = {
|
||||||
|
ALLOWED_TAGS: [...],
|
||||||
|
ALLOWED_ATTR: [...],
|
||||||
|
FORBID_TAGS: ['script', 'iframe', 'object', 'embed'],
|
||||||
|
FORBID_ATTR: ['onerror', 'onload', 'onclick'],
|
||||||
|
ADD_ATTR: ['target'],
|
||||||
|
FORCE_BODY: true
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
#### CVE-MC-005: Weak CSP
|
||||||
|
|
||||||
|
**Current CSP:**
|
||||||
|
```
|
||||||
|
default-src 'self';
|
||||||
|
script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net;
|
||||||
|
style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com;
|
||||||
|
img-src 'self' data: blob: file:;
|
||||||
|
font-src 'self' data:;
|
||||||
|
connect-src 'self' https://www.plantuml.com;
|
||||||
|
```
|
||||||
|
|
||||||
|
**Recommended CSP:**
|
||||||
|
```
|
||||||
|
default-src 'self';
|
||||||
|
script-src 'self';
|
||||||
|
style-src 'self';
|
||||||
|
img-src 'self' data:;
|
||||||
|
font-src 'self';
|
||||||
|
connect-src 'self';
|
||||||
|
frame-src 'none';
|
||||||
|
object-src 'none';
|
||||||
|
base-uri 'self';
|
||||||
|
form-action 'self';
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** This requires:
|
||||||
|
- Bundling all dependencies locally
|
||||||
|
- Removing PlantUML server dependency (use local rendering)
|
||||||
|
- Removing unsafe-inline and unsafe-eval
|
||||||
|
|
||||||
|
### 7.3 Medium Priority Mitigations (P2)
|
||||||
|
|
||||||
|
#### CVE-MC-006/008: Window Security Consistency
|
||||||
|
|
||||||
|
**Affected Windows:**
|
||||||
|
- PDF export window (main.js:2579-2585)
|
||||||
|
- Hidden conversion window (main.js:3263-3268)
|
||||||
|
|
||||||
|
**Fix:**
|
||||||
|
```javascript
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: false,
|
||||||
|
contextIsolation: true,
|
||||||
|
sandbox: true,
|
||||||
|
preload: path.join(__dirname, 'preload-pdf.js')
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### CVE-MC-007: PlantUML Data Exfiltration
|
||||||
|
|
||||||
|
**Options:**
|
||||||
|
1. Use local PlantUML JAR file
|
||||||
|
2. Use PlantUML npm package
|
||||||
|
3. Add warning before sending to external server
|
||||||
|
4. Allow configuration of PlantUML server URL
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Attack Tree Summary
|
||||||
|
|
||||||
|
### 8.1 Primary Attack Tree - Full System Compromise
|
||||||
|
|
||||||
|
```
|
||||||
|
GOAL: Full System Compromise via MarkdownConverter
|
||||||
|
│
|
||||||
|
├── [BRANCH A] Exploit CVE-MC-001 (nodeIntegration)
|
||||||
|
│ │
|
||||||
|
│ ├── [A.1] XSS via malicious markdown
|
||||||
|
│ │ ├── [A.1.1] HTML injection
|
||||||
|
│ │ ├── [A.1.2] SVG script injection
|
||||||
|
│ │ └── [A.1.3] DOMPurify bypass
|
||||||
|
│ │
|
||||||
|
│ ├── [A.2] Compromised CDN script
|
||||||
|
│ │ ├── [A.2.1] jsdelivr compromise
|
||||||
|
│ │ └── [A.2.2] cdnjs compromise
|
||||||
|
│ │
|
||||||
|
│ └── [A.3] PlantUML SVG injection
|
||||||
|
│ └── [A.3.1] Compromised plantuml.com
|
||||||
|
│
|
||||||
|
├── [BRANCH B] Exploit CVE-MC-002 (REPL)
|
||||||
|
│ │
|
||||||
|
│ ├── [B.1] Social engineering
|
||||||
|
│ │ ├── [B.1.1] Malicious tutorial document
|
||||||
|
│ │ └── [B.1.2] Phishing with "config file"
|
||||||
|
│ │
|
||||||
|
│ └── [B.2] Code execution
|
||||||
|
│ ├── [B.2.1] JavaScript (Node.js)
|
||||||
|
│ ├── [B.2.2] Python
|
||||||
|
│ └── [B.2.3] Bash/Shell
|
||||||
|
│
|
||||||
|
└── [BRANCH C] Chain Exploits
|
||||||
|
│
|
||||||
|
├── [C.1] XSS -> RCE (CVE-MC-003 + CVE-MC-001)
|
||||||
|
│ └── Impact: CVSS 9.8
|
||||||
|
│
|
||||||
|
├── [C.2] Path Traversal -> Privilege Escalation
|
||||||
|
│ └── Impact: CVSS 8.5
|
||||||
|
│
|
||||||
|
└── [C.3] PlantUML -> XSS -> RCE
|
||||||
|
└── Impact: CVSS 9.1
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.2 Attack Success Probability
|
||||||
|
|
||||||
|
| Attack Path | Complexity | Privileges Required | User Interaction | Probability |
|
||||||
|
|-------------|------------|---------------------|------------------|-------------|
|
||||||
|
| A.1 XSS->RCE | Low | None | Required | 75% |
|
||||||
|
| A.2 CDN Compromise | High | None | None | 15% |
|
||||||
|
| A.3 PlantUML->RCE | Medium | None | Required | 40% |
|
||||||
|
| B.1 REPL Social Eng | Low | None | Required | 60% |
|
||||||
|
| C.1 Combined XSS-RCE | Low | None | Required | 70% |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Recommendations
|
||||||
|
|
||||||
|
### 9.1 Immediate Actions (0-30 days)
|
||||||
|
|
||||||
|
1. **CVE-MC-001**: Enable `contextIsolation: true` and `nodeIntegration: false` for main window
|
||||||
|
2. **CVE-MC-002**: Add confirmation dialog before REPL execution with code preview
|
||||||
|
3. **CVE-MC-005**: Remove `unsafe-inline` and `unsafe-eval` from CSP
|
||||||
|
4. **CVE-MC-006**: Fix PDF export window security settings
|
||||||
|
|
||||||
|
### 9.2 Short-term Actions (30-90 days)
|
||||||
|
|
||||||
|
1. **CVE-MC-002**: Implement sandboxed code execution environment
|
||||||
|
2. **CVE-MC-003**: Enhance DOMPurify configuration, add CSP reporting
|
||||||
|
3. **CVE-MC-007**: Implement local PlantUML rendering option
|
||||||
|
4. Add comprehensive security audit logging
|
||||||
|
|
||||||
|
### 9.3 Long-term Actions (90+ days)
|
||||||
|
|
||||||
|
1. **CVE-MC-010**: Implement dependency pinning and SCA scanning
|
||||||
|
2. Security awareness training for users
|
||||||
|
3. Implement secure development lifecycle (SDL)
|
||||||
|
4. Regular penetration testing schedule
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Appendix
|
||||||
|
|
||||||
|
### A. Security Configuration Audit
|
||||||
|
|
||||||
|
**Main Window (main.js:323-334)**
|
||||||
|
```javascript
|
||||||
|
// CURRENT (INSECURE)
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true, // CRITICAL: Allows require() in renderer
|
||||||
|
contextIsolation: false, // CRITICAL: No isolation between contexts
|
||||||
|
spellcheck: true
|
||||||
|
}
|
||||||
|
|
||||||
|
// RECOMMENDED
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: false,
|
||||||
|
contextIsolation: true,
|
||||||
|
sandbox: true,
|
||||||
|
spellcheck: true,
|
||||||
|
webSecurity: true,
|
||||||
|
allowRunningInsecureContent: false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**CSP Configuration (index.html:5)**
|
||||||
|
```html
|
||||||
|
<!-- CURRENT (WEAK) -->
|
||||||
|
<meta http-equiv="Content-Security-Policy"
|
||||||
|
content="default-src 'self';
|
||||||
|
script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net;
|
||||||
|
...">
|
||||||
|
|
||||||
|
<!-- RECOMMENDED -->
|
||||||
|
<meta http-equiv="Content-Security-Policy"
|
||||||
|
content="default-src 'self';
|
||||||
|
script-src 'self';
|
||||||
|
style-src 'self';
|
||||||
|
img-src 'self' data:;
|
||||||
|
connect-src 'self';
|
||||||
|
frame-src 'none';
|
||||||
|
object-src 'none'">
|
||||||
|
```
|
||||||
|
|
||||||
|
### B. IPC Channel Security Review
|
||||||
|
|
||||||
|
**High-Risk Channels:**
|
||||||
|
| Channel | Risk | Recommendation |
|
||||||
|
|---------|------|----------------|
|
||||||
|
| `execute-code` | Critical | Remove or sandbox |
|
||||||
|
| `save-file` | High | Add path validation |
|
||||||
|
| `batch-convert` | Medium | Rate limiting exists |
|
||||||
|
| `git-*` | Medium | Audit git operations |
|
||||||
|
|
||||||
|
### C. Dependency Security
|
||||||
|
|
||||||
|
**Critical Dependencies:**
|
||||||
|
| Package | Version | Known CVEs | Recommendation |
|
||||||
|
|---------|---------|------------|----------------|
|
||||||
|
| electron | 37.4.0 | None | Pin version |
|
||||||
|
| dompurify | 3.3.1 | None | Keep updated |
|
||||||
|
| marked | 17.0.3 | None | Keep updated |
|
||||||
|
| mermaid | 11.12.3 | None | Review CSP impact |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Document Control
|
||||||
|
|
||||||
|
| Version | Date | Author | Changes |
|
||||||
|
|---------|------|--------|---------|
|
||||||
|
| 1.0 | 2026-03-15 | Security Team | Initial threat model |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*This threat model should be reviewed and updated after any significant architectural changes or at minimum annually.*
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@@ -7,6 +7,8 @@
|
|||||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self' https://www.plantuml.com;">
|
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self' https://www.plantuml.com;">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>MarkdownConverter</title>
|
<title>MarkdownConverter</title>
|
||||||
|
<!-- Design tokens - loaded first for CSS variable availability -->
|
||||||
|
<link rel="stylesheet" href="styles/tokens.css">
|
||||||
<link rel="stylesheet" href="fonts.css">
|
<link rel="stylesheet" href="fonts.css">
|
||||||
<link rel="stylesheet" href="styles.css">
|
<link rel="stylesheet" href="styles.css">
|
||||||
<link rel="stylesheet" href="styles-modern.css">
|
<link rel="stylesheet" href="styles-modern.css">
|
||||||
@@ -16,6 +18,8 @@
|
|||||||
<link rel="stylesheet" href="../node_modules/highlight.js/styles/default.css">
|
<link rel="stylesheet" href="../node_modules/highlight.js/styles/default.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<!-- Skip link for keyboard navigation -->
|
||||||
|
<a href="#editor-container" class="skip-link">Skip to editor</a>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<!-- App Header with ConcreteInfo Logo -->
|
<!-- App Header with ConcreteInfo Logo -->
|
||||||
<div class="app-header" id="app-header">
|
<div class="app-header" id="app-header">
|
||||||
|
|||||||
@@ -0,0 +1,347 @@
|
|||||||
|
/**
|
||||||
|
* Design Tokens - Shadcn/ui Compatible
|
||||||
|
*
|
||||||
|
* This file provides CSS custom properties (design tokens) following
|
||||||
|
* the Shadcn/ui convention. These tokens enable consistent theming
|
||||||
|
* and easy theme switching between light and dark modes.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* color: hsl(var(--primary));
|
||||||
|
* background: hsl(var(--background));
|
||||||
|
*
|
||||||
|
* @version 4.1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
:root {
|
||||||
|
/* ============================================
|
||||||
|
* Base Colors - Light Mode
|
||||||
|
* ============================================ */
|
||||||
|
|
||||||
|
/* Background and foreground */
|
||||||
|
--background: 0 0% 100%;
|
||||||
|
--foreground: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
/* Card */
|
||||||
|
--card: 0 0% 100%;
|
||||||
|
--card-foreground: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
/* Popover/Dropdown */
|
||||||
|
--popover: 0 0% 100%;
|
||||||
|
--popover-foreground: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
/* Primary - Brand color (ConcreteInfo blue-purple) */
|
||||||
|
--primary: 227 44% 52%;
|
||||||
|
--primary-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
/* Secondary */
|
||||||
|
--secondary: 210 40% 96.1%;
|
||||||
|
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
/* Muted - Subtle backgrounds */
|
||||||
|
--muted: 210 40% 96.1%;
|
||||||
|
--muted-foreground: 215.4 16.3% 46.9%;
|
||||||
|
|
||||||
|
/* Accent - Highlight color */
|
||||||
|
--accent: 210 40% 96.1%;
|
||||||
|
--accent-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
/* Destructive - Error/danger states */
|
||||||
|
--destructive: 0 84.2% 60.2%;
|
||||||
|
--destructive-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
/* Success - Positive states */
|
||||||
|
--success: 142 76% 36%;
|
||||||
|
--success-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
/* Warning - Caution states */
|
||||||
|
--warning: 38 92% 50%;
|
||||||
|
--warning-foreground: 0 0% 0%;
|
||||||
|
|
||||||
|
/* Info - Informational states */
|
||||||
|
--info: 199 89% 48%;
|
||||||
|
--info-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
/* Border and input */
|
||||||
|
--border: 214.3 31.8% 91.4%;
|
||||||
|
--input: 214.3 31.8% 91.4%;
|
||||||
|
|
||||||
|
/* Focus ring */
|
||||||
|
--ring: 227 44% 52%;
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
* Spacing & Sizing
|
||||||
|
* ============================================ */
|
||||||
|
|
||||||
|
--radius: 0.5rem;
|
||||||
|
--radius-sm: calc(var(--radius) - 4px);
|
||||||
|
--radius-md: calc(var(--radius) - 2px);
|
||||||
|
--radius-lg: var(--radius);
|
||||||
|
--radius-xl: calc(var(--radius) + 4px);
|
||||||
|
|
||||||
|
/* Spacing unit (4px base) */
|
||||||
|
--spacing-1: 0.25rem;
|
||||||
|
--spacing-2: 0.5rem;
|
||||||
|
--spacing-3: 0.75rem;
|
||||||
|
--spacing-4: 1rem;
|
||||||
|
--spacing-5: 1.25rem;
|
||||||
|
--spacing-6: 1.5rem;
|
||||||
|
--spacing-8: 2rem;
|
||||||
|
--spacing-10: 2.5rem;
|
||||||
|
--spacing-12: 3rem;
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
* Typography
|
||||||
|
* ============================================ */
|
||||||
|
|
||||||
|
--font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
--font-mono: 'JetBrains Mono', 'Fira Code', 'SF Mono', Monaco, 'Courier New', monospace;
|
||||||
|
|
||||||
|
--text-xs: 0.75rem;
|
||||||
|
--text-sm: 0.875rem;
|
||||||
|
--text-base: 1rem;
|
||||||
|
--text-lg: 1.125rem;
|
||||||
|
--text-xl: 1.25rem;
|
||||||
|
--text-2xl: 1.5rem;
|
||||||
|
--text-3xl: 1.875rem;
|
||||||
|
|
||||||
|
--font-normal: 400;
|
||||||
|
--font-medium: 500;
|
||||||
|
--font-semibold: 600;
|
||||||
|
--font-bold: 700;
|
||||||
|
|
||||||
|
--leading-tight: 1.25;
|
||||||
|
--leading-normal: 1.5;
|
||||||
|
--leading-relaxed: 1.625;
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
* Shadows
|
||||||
|
* ============================================ */
|
||||||
|
|
||||||
|
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||||
|
--shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
||||||
|
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||||
|
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||||
|
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
* Transitions
|
||||||
|
* ============================================ */
|
||||||
|
|
||||||
|
--transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
--transition-normal: 200ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
--transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
* Z-Index Scale
|
||||||
|
* ============================================ */
|
||||||
|
|
||||||
|
--z-dropdown: 50;
|
||||||
|
--z-sticky: 100;
|
||||||
|
--z-modal: 200;
|
||||||
|
--z-popover: 300;
|
||||||
|
--z-tooltip: 400;
|
||||||
|
--z-toast: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
* Dark Mode
|
||||||
|
* ============================================ */
|
||||||
|
|
||||||
|
.dark,
|
||||||
|
[data-theme="dark"] {
|
||||||
|
/* Background and foreground */
|
||||||
|
--background: 222.2 84% 4.9%;
|
||||||
|
--foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
/* Card */
|
||||||
|
--card: 222.2 84% 4.9%;
|
||||||
|
--card-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
/* Popover/Dropdown */
|
||||||
|
--popover: 222.2 84% 4.9%;
|
||||||
|
--popover-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
/* Primary */
|
||||||
|
--primary: 227 44% 52%;
|
||||||
|
--primary-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
/* Secondary */
|
||||||
|
--secondary: 217.2 32.6% 17.5%;
|
||||||
|
--secondary-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
/* Muted */
|
||||||
|
--muted: 217.2 32.6% 17.5%;
|
||||||
|
--muted-foreground: 215 20.2% 65.1%;
|
||||||
|
|
||||||
|
/* Accent */
|
||||||
|
--accent: 217.2 32.6% 17.5%;
|
||||||
|
--accent-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
/* Destructive */
|
||||||
|
--destructive: 0 62.8% 30.6%;
|
||||||
|
--destructive-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
/* Success */
|
||||||
|
--success: 142 76% 26%;
|
||||||
|
--success-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
/* Warning */
|
||||||
|
--warning: 38 92% 40%;
|
||||||
|
--warning-foreground: 0 0% 100%;
|
||||||
|
|
||||||
|
/* Info */
|
||||||
|
--info: 199 89% 38%;
|
||||||
|
--info-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
/* Border and input */
|
||||||
|
--border: 217.2 32.6% 17.5%;
|
||||||
|
--input: 217.2 32.6% 17.5%;
|
||||||
|
|
||||||
|
/* Focus ring */
|
||||||
|
--ring: 227 44% 52%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
* Semantic Color Classes
|
||||||
|
* ============================================ */
|
||||||
|
|
||||||
|
.bg-background { background-color: hsl(var(--background)); }
|
||||||
|
.bg-foreground { background-color: hsl(var(--foreground)); }
|
||||||
|
.bg-card { background-color: hsl(var(--card)); }
|
||||||
|
.bg-primary { background-color: hsl(var(--primary)); }
|
||||||
|
.bg-secondary { background-color: hsl(var(--secondary)); }
|
||||||
|
.bg-muted { background-color: hsl(var(--muted)); }
|
||||||
|
.bg-accent { background-color: hsl(var(--accent)); }
|
||||||
|
.bg-destructive { background-color: hsl(var(--destructive)); }
|
||||||
|
|
||||||
|
.text-foreground { color: hsl(var(--foreground)); }
|
||||||
|
.text-primary { color: hsl(var(--primary)); }
|
||||||
|
.text-secondary { color: hsl(var(--secondary-foreground)); }
|
||||||
|
.text-muted-foreground { color: hsl(var(--muted-foreground)); }
|
||||||
|
.text-destructive { color: hsl(var(--destructive)); }
|
||||||
|
|
||||||
|
.border-border { border-color: hsl(var(--border)); }
|
||||||
|
.border-primary { border-color: hsl(var(--primary)); }
|
||||||
|
.border-input { border-color: hsl(var(--input)); }
|
||||||
|
|
||||||
|
/* ============================================
|
||||||
|
* Utility Classes
|
||||||
|
* ============================================ */
|
||||||
|
|
||||||
|
/* Focus ring */
|
||||||
|
.focus-ring:focus-visible {
|
||||||
|
outline: 2px solid hsl(var(--ring));
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button base styles */
|
||||||
|
.btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: var(--spacing-2) var(--spacing-4);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
font-weight: var(--font-medium);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
transition: all var(--transition-fast);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:focus-visible {
|
||||||
|
outline: 2px solid hsl(var(--ring));
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: hsl(var(--primary));
|
||||||
|
color: hsl(var(--primary-foreground));
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: hsl(var(--primary) / 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background-color: hsl(var(--secondary));
|
||||||
|
color: hsl(var(--secondary-foreground));
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background-color: hsl(var(--secondary) / 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-destructive {
|
||||||
|
background-color: hsl(var(--destructive));
|
||||||
|
color: hsl(var(--destructive-foreground));
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-destructive:hover {
|
||||||
|
background-color: hsl(var(--destructive) / 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-ghost {
|
||||||
|
background-color: transparent;
|
||||||
|
color: hsl(var(--foreground));
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-ghost:hover {
|
||||||
|
background-color: hsl(var(--accent));
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid hsl(var(--border));
|
||||||
|
color: hsl(var(--foreground));
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline:hover {
|
||||||
|
background-color: hsl(var(--accent));
|
||||||
|
color: hsl(var(--accent-foreground));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Badge styles */
|
||||||
|
.badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: var(--spacing-1) var(--spacing-2);
|
||||||
|
font-size: var(--text-xs);
|
||||||
|
font-weight: var(--font-medium);
|
||||||
|
border-radius: 9999px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-primary {
|
||||||
|
background-color: hsl(var(--primary));
|
||||||
|
color: hsl(var(--primary-foreground));
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-secondary {
|
||||||
|
background-color: hsl(var(--secondary));
|
||||||
|
color: hsl(var(--secondary-foreground));
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-destructive {
|
||||||
|
background-color: hsl(var(--destructive));
|
||||||
|
color: hsl(var(--destructive-foreground));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input styles */
|
||||||
|
.input {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
padding: var(--spacing-2) var(--spacing-3);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
border: 1px solid hsl(var(--input));
|
||||||
|
border-radius: var(--radius);
|
||||||
|
background-color: hsl(var(--background));
|
||||||
|
color: hsl(var(--foreground));
|
||||||
|
transition: border-color var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input:focus-visible {
|
||||||
|
outline: 2px solid hsl(var(--ring));
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input::placeholder {
|
||||||
|
color: hsl(var(--muted-foreground));
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
Reference in New Issue
Block a user