Skip to main content
claude

FB Exposed Project

Investigation into Facebook's surveillance capabilities on iOS devices.

Technical Diagrams

Security Features (Implemented 2026-01-15) Line 16
| Feature | Implementation |
|---------|----------------|
| Session persistence | File-based at `/var/lib/fbexposed/sessions.json` |
| Token hashing | SHA-256 hash stored, not plaintext |
| Key hashing | Keys stored as SHA-256 hashes |
| Rate limiting | 5 attempts/minute per IP |
| Generic errors | All auth failures return "Authentication failed" |
| Image size limit | 5MB max upload |
Valid key images are stored in `./keys/`: Line 62
| File | Description |
|------|-------------|
| `tom-base.png` | Base image for encoding keys |
| `key-3-1c0797a5.png` | Valid key (hash: 1c0797a5...) |
Server Paths Line 71
| Path | Purpose |
|------|---------|
| `/var/www/fb.definitelynot.ai/` | SSR deployment |
| `/var/lib/fbexposed/valid-keys.json` | Hashed valid keys |
| `/var/lib/fbexposed/sessions.json` | Active sessions |
| `/var/lib/fbexposed/tom-base.png` | Base image for key generation |
Line 118
├── CLAUDE.md              # This file
├── keys/                  # Valid key images
│   ├── tom-base.png       # Base image for encoding
│   └── key-3-*.png        # Valid key images
├── website/               # Astro source
│   ├── src/
│   │   ├── lib/           # Auth, sessions, rate limiting
│   │   ├── pages/         # Routes
│   │   └── components/    # React components
│   └── dist/              # Build output
├── evidence/              # Investigation evidence
├── scripts/               # Analysis scripts
└── data-exfil/            # Data exfiltration research

Code Evidence

Bash
ssh adept
cd /var/www/fb.definitelynot.ai
node /usr/local/bin/fbexposed-keygen.mjs generate /path/to/output.png
Bash
node /usr/local/bin/fbexposed-keygen.mjs list
Bash
node /usr/local/bin/fbexposed-keygen.mjs revoke <hash-prefix>
Bash
cd ./website
node /usr/local/bin/fbexposed-keygen.mjs generate ./keys/new-key.png
Bash
cd ./website
npm run build

# Deploy
rsync -avz dist/ adept:/tmp/fb-dist/
ssh adept "sudo rm -rf /var/www/fb.definitelynot.ai.backup && \
  sudo mv /var/www/fb.definitelynot.ai /var/www/fb.definitelynot.ai.backup && \
  sudo mv /tmp/fb-dist /var/www/fb.definitelynot.ai && \
  sudo chown -R caddy:caddy /var/www/fb.definitelynot.ai"

# Copy package.json and install deps
ssh adept "cd /var/www/fb.definitelynot.ai && \
  sudo cp /var/www/fb.definitelynot.ai.backup/package.json . && \
  sudo chown caddy:caddy package.json && \
  sudo -u caddy npm install --omit=dev"

# Restart service
ssh adept "sudo systemctl restart fb-exposed"
Bash
# Check status
ssh adept "systemctl status fb-exposed"

# View logs
ssh adept "journalctl -u fb-exposed -f"

# Restart
ssh adept "sudo systemctl restart fb-exposed"
Plain Text
 CLAUDE.md              # This file
├── keys/                  # Valid key images
│   ├── tom-base.png       # Base image for encoding
│   └── key-3-*.png        # Valid key images
├── website/               # Astro source
│   ├── src/
│   │   ├── lib/           # Auth, sessions, rate limiting
│   │   ├── pages/         # Routes
│   │   └── components/    # React components
│   └── dist/              # Build output
├── evidence/              # Investigation evidence
├── scripts/               # Analysis scripts
└── data-exfil/            # Data exfiltration research

Investigation into Facebook's surveillance capabilities on iOS devices.

Website (fb.definitelynot.ai)

Astro SSR site with steganographic key-based authentication.

Architecture

    undefined

Security Features (Implemented 2026-01-15)

FeatureImplementation
Session persistenceFile-based at `/var/lib/fbexposed/sessions.json`
Token hashingSHA-256 hash stored, not plaintext
Key hashingKeys stored as SHA-256 hashes
Rate limiting5 attempts/minute per IP
Generic errorsAll auth failures return "Authentication failed"
Image size limit5MB max upload

Key Management

Keys are stored as SHA-256 hashes on the server. The key image contains the plaintext key which gets hashed during validation.

Generate New Key (on server)

Bash
ssh adept
cd /var/www/fb.definitelynot.ai
node /usr/local/bin/fbexposed-keygen.mjs generate /path/to/output.png

List Valid Keys

Bash
node /usr/local/bin/fbexposed-keygen.mjs list

Revoke a Key

Bash
node /usr/local/bin/fbexposed-keygen.mjs revoke <hash-prefix>

Local Key Generation

From local machine (requires sharp):

Bash
cd ./website
node /usr/local/bin/fbexposed-keygen.mjs generate ./keys/new-key.png

Key Files

Valid key images are stored in `./keys/`:

FileDescription
`tom-base.png`Base image for encoding keys
`key-3-1c0797a5.png`Valid key (hash: 1c0797a5...)

**Note**: Key images encode the key `FBEXPOSED-<64-char-hex>` into pixel values along row 0.

Server Paths

PathPurpose
`/var/www/fb.definitelynot.ai/`SSR deployment
`/var/lib/fbexposed/valid-keys.json`Hashed valid keys
`/var/lib/fbexposed/sessions.json`Active sessions
`/var/lib/fbexposed/tom-base.png`Base image for key generation

Building & Deploying

Bash
cd ./website
npm run build


rsync -avz dist/ adept:/tmp/fb-dist/
ssh adept "sudo rm -rf /var/www/fb.definitelynot.ai.backup && \
  sudo mv /var/www/fb.definitelynot.ai /var/www/fb.definitelynot.ai.backup && \
  sudo mv /tmp/fb-dist /var/www/fb.definitelynot.ai && \
  sudo chown -R caddy:caddy /var/www/fb.definitelynot.ai"


ssh adept "cd /var/www/fb.definitelynot.ai && \
  sudo cp /var/www/fb.definitelynot.ai.backup/package.json . && \
  sudo chown caddy:caddy package.json && \
  sudo -u caddy npm install --omit=dev"


ssh adept "sudo systemctl restart fb-exposed"

Service Management

Bash

ssh adept "systemctl status fb-exposed"


ssh adept "journalctl -u fb-exposed -f"


ssh adept "sudo systemctl restart fb-exposed"

Project Structure

Plain Text
 CLAUDE.md              # This file
├── keys/                  # Valid key images
│   ├── tom-base.png       # Base image for encoding
│   └── key-3-*.png        # Valid key images
├── website/               # Astro source
│   ├── src/
│   │   ├── lib/           # Auth, sessions, rate limiting
│   │   ├── pages/         # Routes
│   │   └── components/    # React components
│   └── dist/              # Build output
├── evidence/              # Investigation evidence
├── scripts/               # Analysis scripts
└── data-exfil/            # Data exfiltration research

Steganography Format

Keys are encoded into images using LSB-style encoding:

    undefined

The encoding uses high/low values (220/35) for each bit, making extraction robust against minor image manipulation.

Related Reports