Skip to content

Security

Luara Oliveira edited this page Jul 3, 2026 · 3 revisions

Security

Felines was designed around a unique risk: the product maps locations of vulnerable animals. Security here isn't just data protection — it's physical protection of the cats.

Full audit report: AUDIT_REPORT.md


1. Progressive Location Blur

The most important security feature in the product — designed to protect cats, not just user data.

Level User Precision Offset
1 Anonymous Neighborhood ~600m
2 Authenticated Street level ~110m
3 Linked caretaker Exact Via RPC only

Implementation:

  • Database stores both exact and blurred coordinates
  • Exact columns: RLS protected, anon key returns 42501 permission denied
  • Blurred columns: intentionally public
  • Exact coordinates only via get_colony_exact_location RPC, which validates caretaker status server-side

Tested: SELECT latitude FROM colonies with anon key → 42501 permission denied


2. Row Level Security

RLS enabled on all 17 tables. Every policy was tested with direct API calls using the anon key.

Critical policies:

Table Anonymous Authenticated Caretaker
colonies Read blurred only Read blurred Read exact via RPC
reports No access Read (sensitive data) Read + update
knowledge_progress No access Own rows only Own rows only
profiles Read public fields Own full row Own full row
feedings Read Read + insert Read + insert
flags No access Insert only Insert only

3. Aikido Security Findings

Path Traversal (HIGH severity) ✅ Fixed

Problem: File uploads used unsanitized path prefixes. ../ sequences could write files outside the intended storage folder.

Affected files:

  • components/EditColonyForm.tsx
  • components/ProfileContent.tsx
  • components/ShareStoryButton.tsx
  • components/TimelineEventForm.tsx

Fix: Centralized buildSafeStoragePath() in lib/storage.ts:

  • Removes ../ sequences
  • Removes leading slashes
  • Allows only safe characters in prefix
  • UUID-based filename (no user input in the path)
  • Type validation (images only) + size limit (max 5MB)

Commit: security: fix path traversal vulnerability in file uploads — Aikido report


SSRF in Geocoding (LOW severity) ✅ Fixed

Problem: Nominatim API received lat/lon interpolated directly into the URL string without geographic range validation.

Fix:

  • lib/validateCoordinates.ts: validates lat -90/+90, lon -180/+180, rejects NaN/Infinity
  • lib/geocode.ts: URLSearchParams instead of string interpolation, redirect: "error"
  • Response shape validated before returning to client
  • Bonus: Fixed bug where geocoding always returned Portuguese regardless of user language

Commit: security: fix SSRF vulnerability in geocoding requests — Aikido report


4. Security Headers

Configured in next.config.ts:

Header Value Protection
X-Frame-Options DENY Clickjacking
X-Content-Type-Options nosniff MIME sniffing
Referrer-Policy strict-origin-when-cross-origin URL leakage
Content-Security-Policy (configured) XSS, injection
Permissions-Policy camera=(), microphone=(), geolocation=(self) Browser permissions

5. Rate Limiting

  • Anonymous users: max 10 reports per IP per hour
  • Authenticated users: max 30 reports per IP per hour
  • Friendly message shown when limit is reached
  • Automatic reset after 1 hour

6. Input Validation

  • All fields validated client-side AND server-side
  • Field size limits on all database columns (migration 0067)
  • File uploads: type check + 5MB max before upload
  • No dangerouslySetInnerHTML with user content
  • Coordinate validation before any external API call

7. Security Migrations

Migration Fix
0044 Critical RPCs reject anon key
0045 Secondary RPCs reject anon key
0065 Notification RPCs hardened against spam injection
0066 Streaks restricted to own user
0067 Field size limits added to all columns
0068 Self-thanking blocked
0069 Unique constraint on knowledge_progress
0070 Flag deduplication

8. Animal Safety as a Design Decision

Several product decisions were made specifically to protect the physical safety of the cats — not just user data:

  • No people reporting — prevents digital vigilantism
  • 3-confirmation threshold — prevents one user from hiding serious reports
  • Sensitive reports never deleted — permanent evidence trail
  • Colony sharing disabled — direct links lower the barrier for malicious access
  • UUID filenames — original user input never reaches storage paths
  • Exact coordinates only via server-side RPC — never in any public API response

Reporting a Vulnerability

See SECURITY.md for the full responsible disclosure policy.

Clone this wiki locally