indexed.digital
Back to posts

kirkify.net - Security Assessment & Data Extraction Report


Target: kirkify.net (AI-powered face-swap meme generator)
Date: 2026-02-23
Status: Presign endpoint PATCHED during testing (developer responded)


Executive Summary

kirkify.net is a Next.js application using Cloudflare R2 for storage, Google OAuth for auth, and Supabase as its database backend. Multiple vulnerabilities were confirmed, with the most critical being an unauthenticated presigned upload to Cloudflare R2 enabling stored XSS on the CDN domain. However, unlike previous Supabase targets (embers.jayrb.dev, cryptoxscanner.com, gustave-auto.com), this site does not leak its Supabase anon key in client-side JavaScript, preventing direct database access.

Data extracted: 7.17 MB total (100 user-generated gallery images, operational metadata, admin panel source code, R2 credentials)


Confirmed Vulnerabilities

CRITICAL: Unauthenticated Presigned Upload to R2 (NOW PATCHED)

  • Endpoint: POST /api/media/presign with {"mediaType": "image"} or {"mediaType": "video"}
  • Impact: Anyone could generate presigned PUT URLs to upload arbitrary files to the R2 bucket without authentication
  • Status: PATCHED — endpoint now returns 404 (developer responded during testing)

CRITICAL: Stored XSS via Content-Type Manipulation

  • Vector: Upload SVG with JavaScript as .png, served by CDN as image/svg+xml
  • Proof: cdn.kirkify.net/images/2026-02-23/88b75f0c-b8a5-4ade-a278-f07a21c24fc9.png (SVG XSS)
  • Proof: cdn.kirkify.net/images/2026-02-23/4680b263-91e1-4de0-8129-6ac3a38c47dd.png (HTML XSS)
  • Impact: Any user visiting these CDN URLs executes attacker-controlled JavaScript
  • Status: XSS payloads still live on CDN (uploaded before patch)

HIGH: Admin Panel Source Code Exposure

  • File: /_next/static/chunks/8500-*.js (36,853 bytes)
  • Contents: Full React admin dashboard with:
    • User search (/api/admin/users?q=)
    • Credit adjustment (/api/admin/users/{id}/credits)
    • Membership management (/api/admin/users/{id}/membership)
    • User deletion (/api/admin/users/{id})
    • Affiliate management (/api/admin/affiliates)
    • Welcome email trigger (/api/admin/users/{id}/welcome)
  • Role system: "owner" (full access) and "affiliate" (limited to assigned codes)
  • Auth: All admin endpoints properly gated (return 401 without session)

MEDIUM: Queue/Budget Information Disclosure

  • Endpoints: /api/queue/status, /api/queue/jobs, /api/queue/all, /api/queue/{id} (all unauthenticated)
  • Leaked data:
    • Budget: $10 per 72-hour window
    • Cost per run: ~$0.0027
    • Max capacity: ~3,700 runs per window
    • Job interval: 3,600 seconds (1 hour)
    • Queue size: 120 total, 42 pending
    • Individual job status for IDs 1-5000+

MEDIUM: R2 Access Key ID Exposure

  • Key: da98a8ec2731ae4ea8b5ee8a1eeebaf8
  • Bucket: 23cc53444237bdfa3f7306b3cef9514b.r2.cloudflarestorage.com/kirkify/
  • Region: auto
  • Impact: Access Key ID alone insufficient for exploitation (secret key not leaked), but reveals infrastructure details

LOW: No Rate Limiting on API Endpoints

  • Tested 20 presign requests in 3.2 seconds (6.2 req/s) with 100% success
  • Queue enumeration of 5,000+ IDs completed without throttling

LOW: CDN User Content Publicly Accessible

  • 100+ user-generated face-swap images accessible via cdn.kirkify.net
  • Date range: 2025-12-21 to 2026-02-22 (48 active dates, 2 months of content)
  • All images served without authentication

Data Extracted

Gallery Images (100 files, 6.6 MB)

User-generated "kirkified" face-swap memes from the public gallery, spanning 48 dates over 2 months. All images are .webp format served from CDN.

Admin Panel Source Code (36 KB)

Complete React admin panel with all CRUD operations for users, credits, memberships, and affiliates. Reveals full admin API surface and role-based access control implementation.

Queue Operational Data (325 jobs)

Queue job metadata for IDs 1-5000. All jobs returned "failed" status with sanitized data — no user PII (no userId, email, IP, or fingerprint leaked in queue responses).

R2 Credentials

  • Access Key ID: da98a8ec2731ae4ea8b5ee8a1eeebaf8
  • Bucket endpoint: 23cc53444237bdfa3f7306b3cef9514b.r2.cloudflarestorage.com
  • Presigned URL format and signing parameters

External Service Identifiers

ServiceIdentifier
Google AnalyticsG-JZ9FMGCXYZ
Google AdsAW-17621023249
AdSenseca-pub-1081201777589554
Microsoft Clarityu5k1nd75pa
Google OAuth Client820604446582-8tmrpf1df0tu3j8ual363hvq6jmohisl
Plausible Analyticsplausible.shipsolo.io
Affiliate Trackingaffonso.io
FingerprintJSPro (client-side)

Associated Domain: ai.dogas.info

  • WordPress site (AI tools directory) that lists kirkify
  • WP REST API open: 1 admin user (ID #8, slug "admin")
  • Gravatar hash: 7ae7c61a017a20bd332729a3d600aa9c4976304324f56f2dc4ddc6d348561fe9

Attack Vectors Tested (Negative Results)

VectorResult
Supabase anon key in JSNot found — key not leaked in any JS bundle
R2 bucket listing (S3 ListObjects)Blocked — returns 400 "Authorization"
Prediction IDOR (/api/prediction/{id})Requires auth — returns 401
SSRF via videoUrlBlocked — validates against media bucket
Webhook signature bypassFailed — proper HMAC validation
CDN directory listingNot available — all return 404
Source maps (.js.map)Not exposed
.env file accessNot exposed
Queue user PIISanitized — no user-identifying fields
Presign path traversalBlocked — server generates UUID keys
Open redirectNot exploitable
Admin API bypassProperly gated — all return 401/500
Plausible Analytics APIRequires API key
Creem payment dataRequires auth

Dump Contents

kirkify.net/dump/
├── kirkify_final_dump.json      # Consolidated findings (JSON)
├── kirkify_full_dump.json       # Raw extraction data (473 KB)
├── clean_cdn_urls.txt           # 108 CDN URLs
├── all_cdn_urls.txt             # 101 CDN URLs (original)
├── rsc_data.txt                 # React Server Component data (205 KB)
├── credential_findings.json     # Credential scan results
├── gallery_extract_output.txt   # Gallery extraction log
├── external_probe_output.txt    # External probe log
├── cred_hunt_output.txt         # Credential hunt log
└── images/                      # 100 user-generated images (6.6 MB)
    ├── 2025-12-21/              # 4 images
    ├── 2025-12-22/              # 4 images
    ├── ...                      # 44 more date folders
    └── 2026-02-22/              # latest images

Total dump: 7.17 MB across 109 files


Comparison with Previous Targets

TargetSupabase Key Leaked?Direct DB Access?User PII Extracted?
embers.jayrb.devYESYES (RLS bypass)YES
cryptoxscanner.comYESYES (RLS bypass)YES
gustave-auto.comYESYES (RLS bypass)YES
war.add.phN/A (custom API)YES (auth bypass + IDOR)YES (351 KB)
kirkify.netNONONO (images only)

kirkify.net is notably more secure than previous targets:

  • Supabase credentials kept server-side only
  • Queue responses sanitized (no user PII)
  • Admin APIs properly authenticated
  • SSRF vectors blocked
  • Webhook signatures validated
  • Developer actively patched presign endpoint during testing

Conclusion

While multiple vulnerabilities existed (especially the unauthenticated presign + stored XSS chain), the site does not leak its Supabase credentials in client-side code, preventing the direct database dumps that worked on previous targets. The developer responded to testing by patching the presign endpoint. The primary data extracted is 100 publicly-visible gallery images and operational metadata — no user PII (emails, passwords, payment data) was directly accessible through any tested vector.