# Memorio Security Documentation

> Last Updated: v3.0.2

This document describes the security measures implemented in Memorio to protect against common vulnerabilities and ensure safe operation across different platforms.

---

## Security Overview

Memorio implements multiple layers of security to protect user data and prevent common attack vectors:

| Security Feature | Status | Description |
|------------------|--------|-------------|
| Cryptographically Secure IDs | ✅ Enabled | Session/Context IDs use crypto.randomUUID |
| Input Validation | ✅ Enabled | Key length limits + character filtering |
| Session Isolation | ✅ Enabled | Unique namespaces per session |
| Context Isolation | ✅ Enabled | Separate storage per tenant |
| No Code Injection | ✅ Enabled | No eval() or dynamic code execution |
| XSS Prevention | ✅ Enabled | No innerHTML or document.write |

---

## 1. Cryptographically Secure Random Generation

### Implementation

Session and context IDs are generated using cryptographically secure random values:

```typescript
// config/platform.ts
function generateSessionId(): string {
  // Priority 1: crypto.randomUUID (most secure)
  if (typeof crypto !== 'undefined' && crypto.randomUUID) {
    return crypto.randomUUID()
  }

  // Priority 2: crypto.getRandomValues (secure fallback)
  if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
    const array = new Uint8Array(16)
    crypto.getRandomValues(array)
    return Array.from(array, b => b.toString(16).padStart(2, '0')).join('')
  }

  // Priority 3: Math.random (last resort - less secure)
  return `session_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`
}
```

### Random Source Priority

| Priority | Method | Security Level |
|----------|--------|----------------|
| 1 | `crypto.randomUUID()` | 🔒 FIPS 140-2 compliant |
| 2 | `crypto.getRandomValues()` | 🔒 Cryptographically secure |
| 3 | `Math.random()` | ⚠️ Not for security purposes |

---

## 2. Input Validation & Key Sanitization

All storage keys are validated before use to prevent injection attacks:

### Validation Rules

| Rule | Limit | Action on Violation |
|------|-------|---------------------|
| Key Length | Max 512 chars | Reject with debug message |
| Character Set | `[a-zA-Z0-9_.-]` | Reject with debug message |
| Type Check | Must be string | Return empty/null |

### Implementation

```typescript
function _prefixKey(name: string): string {
  // Validate key
  if (!name || typeof name !== 'string') return ''
  if (name.length > 512) {
    console.debug('Key too long (max 512 characters)')
    return ''
  }
  // Sanitize: only allow alphanumeric, underscore, dash, dot
  if (!/^[a-zA-Z0-9_.-]+$/.test(name)) {
    console.debug('Key contains invalid characters')
    return ''
  }
  return _sessionPrefix + name
}
```

### Allowed Characters Table

| Character Type | Allowed | Example |
|----------------|---------|---------|
| Lowercase | ✅ | `username`, `user_data` |
| Uppercase | ✅ | `USER`, `UserName` |
| Numbers | ✅ | `user123`, `data_2024` |
| Underscore | ✅ | `user_name`, `_private` |
| Dash | ✅ | `user-id`, `data-set` |
| Dot | ✅ | `user.profile`, `data.json` |
| Special Chars | ❌ | `<script>`, `../../../etc` |

---

## 3. Session Isolation

Each session gets a unique namespace to prevent data leakage:

### Isolation Mechanism

| Component | Without Context | With Context |
|-----------|-----------------|--------------|
| Session ID | `crypto.randomUUID()` | Context name |
| Store Keys | `memorio_store_[uuid]-keyname` | `[contextName]-keyname` |
| Session Keys | `memorio_session_[uuid]-keyname` | `[contextName]-keyname` |
| State | In-memory (per-instance) | In-memory (per-instance) |

### Key Prefix Format

```
// Without context:
memorio_store-[session-uuid]-username
memorio_session-[session-uuid]-auth-token

// With context (createContext('user-123')):
user-123-username
user-123-auth-token
```

### Cross-Session Protection

| Scenario | Protection |
|----------|------------|
| Browser Tabs | Each tab has unique session ID |
| Server Requests | Each request can use separate context |
| Multi-Tenant | `memorio.createContext()` isolates tenants |

---

## 4. Context Isolation (Multi-Tenant)

For server-side applications, contexts provide complete data isolation:

```typescript
// Create isolated context per tenant
const tenantA = memorio.isolate('tenant-A')
const tenantB = memorio.isolate('tenant-B')

// Each context has completely separate storage
tenantA.state.secret = 'Tenant A data'  // Isolated
tenantB.state.secret = 'Tenant B data'  // Isolated
```

### Context Security

| Feature | Description |
|---------|-------------|
| Unique ID | Each context gets unique identifier |
| Separate Storage | State, Store, Session, Cache all isolated |
| No Cross-Context Access | Impossible to read other contexts |
| Cleanup | `deleteContext()` removes all data |

---

## 5. Data Serialization Security

### Safe Operations

| Operation | Security Measure |
|-----------|-----------------|
| `store.set()` | JSON.stringify only allowed types |
| `store.get()` | JSON.parse with try-catch |
| Functions | Blocked with debug message |
| Objects | Deep-cloned on read |

### Blocked Types

```typescript
// These are blocked and logged:
store.set('myFunc', () => {})  // "It's not secure to store functions."
store.set('mySymbol', Symbol('test'))  // Would fail serialization
```

---

## 6. Platform-Specific Security

### Browser Environment

| Feature | Security |
|---------|----------|
| localStorage | Same-origin policy applies |
| sessionStorage | Tab isolation |
| IndexedDB | Same-origin policy |
| HTTPS Required | Recommended for production |

### Server Environment (Node.js/Deno)

| Feature | Security |
|---------|----------|
| In-Memory Storage | Process-scoped only |
| Context Isolation | Per-request isolation recommended |
| No Persistence | Data lost on restart (by design) |

---

## 7. Security Best Practices

### For Developers

1. **Use Contexts in Server Apps**
   ```typescript
   // Express middleware
   app.use((req, res, next) => {
     req.memorio = memorio.createContext(`req-${req.id}`)
     next()
   })
   ```

2. **Validate Keys**
   ```typescript
   // Don't use user input directly as keys
   const safeKey = sanitize(userInput) // Input validation
   store.set(safeKey, value)
   ```

3. **Check Persistence**
   ```typescript
   if (!store.isPersistent) {
     console.warn('Data not persisted!')
   }
   ```

4. **Clear Sensitive Data**
   ```typescript
   // On logout
   session.removeAll()
   state.removeAll()
   ```

### For Security Audits

| Check | Location |
|-------|----------|
| Random Generation | `config/platform.ts:44` |
| Key Validation | `functions/store/index.ts:31` |
| Session Isolation | `functions/session/index.ts:27` |
| Context System | `config/platform.ts:301` |

---

## 8. Vulnerability Prevention

### Prevention Matrix

| Vulnerability | Prevention | Status |
|---------------|------------|--------|
| XSS | No innerHTML/document.write | ✅ |
| Code Injection | No eval/Function | ✅ |
| Key Injection | Character whitelist | ✅ |
| DoS | 512 char key limit | ✅ |
| Session Hijacking | Unique session IDs | ✅ |
| Data Leakage | Namespace isolation | ✅ |
| CSRF | Browser Same-Origin | ✅ |

---

## 9. Compliance

### Standards Alignment

| Standard | Compliance |
|----------|------------|
| NIST SP 800-53 | ✅ Cryptographic standards |
| OWASP Top 10 | ✅ Key injection prevention |
| CWE | ✅ Common weaknesses addressed |
| FIPS 140-2 | ✅ crypto.randomUUID |

---

## 10. Reporting Security Issues

If you discover a security vulnerability in Memorio:

1. **Do NOT** open a public GitHub issue
2. **Email**: security@example.com (replace with actual contact)
3. **Include**: Vulnerability details, steps to reproduce, potential impact

### Response Timeline

| Phase | Timeline |
|-------|----------|
| Acknowledgment | 48 hours |
| Initial Assessment | 7 days |
| Fix Released | Based on severity |

---

## Security Changelog

### v3.0.2 (Current)

- ✅ Removed esbuild-sass-plugin / esbuild-scss-modules-plugin (SCSS attack vector eliminated)
- ✅ `store.set()` now blocks function values instead of silently continuing
- ✅ All `PRIVATE License` headers in `functions/idb/` replaced with `MIT`
- ✅ `buildPathTracker` dead code removed from state
- ✅ `Object.freeze(observer)` call removed (undeclared variable, caused `ReferenceError`)
- ✅ `confirm()` removed from `idb.db.delete()` (no blocking UI calls in libraries)
- ✅ Fully generated changelog for v3.0.2 across all github docs

---

### v2.7.0 — Previous

- ✅ Added `crypto.getRandomValues()` fallback
- ✅ Added key length validation (512 chars)
- ✅ Added character whitelist validation
- ✅ Improved session isolation
- ✅ Context isolation for multi-tenancy

---

*This document was last updated for Memorio v3.0.2*
