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/presignwith{"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 asimage/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)
- User search (
- 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
| Service | Identifier |
|---|---|
| Google Analytics | G-JZ9FMGCXYZ |
| Google Ads | AW-17621023249 |
| AdSense | ca-pub-1081201777589554 |
| Microsoft Clarity | u5k1nd75pa |
| Google OAuth Client | 820604446582-8tmrpf1df0tu3j8ual363hvq6jmohisl |
| Plausible Analytics | plausible.shipsolo.io |
| Affiliate Tracking | affonso.io |
| FingerprintJS | Pro (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)
| Vector | Result |
|---|---|
| Supabase anon key in JS | Not 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 videoUrl | Blocked — validates against media bucket |
| Webhook signature bypass | Failed — proper HMAC validation |
| CDN directory listing | Not available — all return 404 |
Source maps (.js.map) | Not exposed |
| .env file access | Not exposed |
| Queue user PII | Sanitized — no user-identifying fields |
| Presign path traversal | Blocked — server generates UUID keys |
| Open redirect | Not exploitable |
| Admin API bypass | Properly gated — all return 401/500 |
| Plausible Analytics API | Requires API key |
| Creem payment data | Requires 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
| Target | Supabase Key Leaked? | Direct DB Access? | User PII Extracted? |
|---|---|---|---|
| embers.jayrb.dev | YES | YES (RLS bypass) | YES |
| cryptoxscanner.com | YES | YES (RLS bypass) | YES |
| gustave-auto.com | YES | YES (RLS bypass) | YES |
| war.add.ph | N/A (custom API) | YES (auth bypass + IDOR) | YES (351 KB) |
| kirkify.net | NO | NO | NO (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.