Skip to content

Implement CSP compliance with nonce support for strict policies#718

Open
micahstubbs wants to merge 1 commit intovasturiano:masterfrom
micahstubbs:710/fix-csp-inline-styles
Open

Implement CSP compliance with nonce support for strict policies#718
micahstubbs wants to merge 1 commit intovasturiano:masterfrom
micahstubbs:710/fix-csp-inline-styles

Conversation

@micahstubbs
Copy link
Contributor

Problem Summary

Issue: The library uses inline styles that violate strict Content Security Policies (CSP)
Impact: High - Breaks tooltips and interactive features in security-compliant environments
Root Cause: Inline style usage both directly in the library and through dependencies like float-tooltip

Technical Analysis

The issue was caused by CSP violations from inline styles:

  1. Direct inline styles in 3d-force-graph.js:

    • renderer().domElement.style.cursor = null
    • state.container.style.position = 'relative'
  2. Dependency inline styles from float-tooltip using D3's .style() method

These violations prevented:

  • Cursor style changes during interaction
  • Container positioning for proper layout
  • Tooltip styling and positioning

Solution Implemented

1. CSS Class-Based Approach (Default)

Replaced inline styles with CSS classes for CSP compliance:

.force-graph-container {
  position: relative;
}

.force-graph-renderer {
  cursor: default;
}

2. CSP Nonce Support (Advanced)

Added a new cspNonce property for strict CSP environments:

const graph = new ForceGraph3D(element)
  .cspNonce('your-nonce-value')  // CSP nonce from your server
  .graphData(data);

3. Utility Functions

Implemented CSP-compliant styling utilities:

  • injectCSPCompliantStyle() - Creates style elements with nonce support
  • setCSPCompliantStyle() - Applies styles using dynamic CSS classes
  • makeD3CSPCompliant() - Monkey-patches D3 selections for tooltip compatibility

Usage Examples

Basic Usage (CSS Classes)

// Default behavior - uses CSS classes (CSP-compliant for most policies)
const graph = new ForceGraph3D(document.getElementById('graph'))
  .graphData(data);

Strict CSP with Nonce

<\!-- HTML with strict CSP -->
<meta http-equiv="Content-Security-Policy" content="
  default-src 'self';
  style-src 'self' 'nonce-abc123';
  script-src 'self' 'nonce-abc123';
">
// JavaScript with nonce support
const graph = new ForceGraph3D(document.getElementById('graph'))
  .cspNonce('abc123')  // Must match nonce in CSP header
  .graphData(data);

TypeScript Support

New method added to the interface:

// CSP compliance
cspNonce(): string | null;
cspNonce(nonce: string | null): ChainableInstance;

Testing & Examples

  • ✅ Created comprehensive CSP test example (example/csp-compliance/)
  • ✅ Verified no CSP violations with strict policy
  • ✅ Confirmed tooltip functionality works with nonce
  • ✅ Tested both CSS classes and nonce-based approaches

Benefits

  1. Security Compliance: Works with strict CSP policies required in enterprise environments
  2. Flexibility: Supports both CSS classes and nonce-based approaches
  3. Backward Compatibility: Existing code continues to work without changes
  4. Performance: CSS classes are more efficient than inline styles
  5. Maintainability: Centralized styling in CSS files

Impact

Before Fix

CSP Violation: Refused to apply inline style because it violates CSP directive: "style-src 'self'"
- Tooltips fail to display
- Cursor interactions broken  
- Container positioning fails

After Fix (Default)

✅ No CSP violations with default CSS classes
✅ Full functionality in most CSP environments
✅ Backward compatible behavior

After Fix (With Nonce)

✅ Strict CSP compliance achieved
✅ All dynamic styles work properly
✅ Enterprise security requirements met

Deployment Notes

  1. Breaking Change: None - this is a backward-compatible enhancement
  2. Runtime Impact: Minimal - CSS classes are more efficient than inline styles
  3. Security Enhancement: Enables deployment in high-security environments
  4. User Action: Optional - existing code works without modification

Fix #710

- Replace inline styles with CSS classes for default CSP compliance
- Add cspNonce property for strict CSP environments
- Create CSP-compliant style injection utilities
- Add TypeScript definitions for new cspNonce method
- Include comprehensive test example and documentation

Fixes issue where library violated Content Security Policy by using inline styles, breaking functionality in security-compliant environments.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refactor dynamic style handling so a strict content security policy can be used

1 participant