White-Hat Security Audit — wetheleader.orgவொயிட்-ஹேட் பாதுகாப்பு தணிக்கை — wetheleader.org

Non-destructive black-box review of the public site & backend api-2.wetheleader.org · Updated 6 June 2026 பொது இணையதளம் & பின்தள api-2.wetheleader.org இன் சேதமற்ற (black-box) பரிசோதனை · புதுப்பிக்கப்பட்டது 6 ஜூன் 2026
"Active Leaders" counter"Active Leaders" எண்ணிக்கை
FAKE ✗போலி ✗
Computed from the clock (~4.5/sec), R²=0.988 vs timeகடிகாரத்தின் அடிப்படையில் கணக்கீடு (~4.5/வி), நேரத்துடன் R²=0.988
Mobile OTP verificationமொபைல் OTP சரிபார்ப்பு
REAL ✓உண்மை ✓
Server-validated; wrong codes rejected (HTTP 400)சர்வரில் சரிபார்ப்பு; தவறான குறியீடு நிராகரிப்பு (HTTP 400)
Open member-lookup (enumeration)திறந்த உறுப்பினர் தேடல் (enumeration)
EXPOSED ⚠வெளிப்பட்டது ⚠
Anyone can test if a number is a member — see live PoC ↓எந்த எண்ணும் உறுப்பினரா எனச் சோதிக்கலாம் — கீழே நேரடி PoC ↓

1. Where it's hosted & what it's built with1. எங்கு ஹோஸ்ட் செய்யப்பட்டுள்ளது & எந்த தொழில்நுட்பம்

DNS / nameserversDNS / பெயர்ச்சர்வர்கள் Cloudflare (rene.ns.cloudflare.com, elisa.ns.cloudflare.com)
Edge (web + API)எட்ஜ் (web + API) Cloudflare CDN/proxy — both wetheleader.org and api-2.wetheleader.org resolve to Cloudflare IPs (104.26.10.116, 104.26.11.116, 172.67.69.143); real origin IP is hidden. Cloudflare CDN/proxywetheleader.org மற்றும் api-2.wetheleader.org இரண்டும் Cloudflare IP களுக்கு (104.26.10.116, 104.26.11.116, 172.67.69.143) resolve ஆகின்றன; உண்மையான origin IP மறைக்கப்பட்டுள்ளது.
Origin web serverOrigin web server Caddy (leaked via via: 1.1 Caddy), fronting a JSON API service.Caddy (via: 1.1 Caddy மூலம் வெளிப்பட்டது), ஒரு JSON API சேவையை முன்னிலைப்படுத்துகிறது.
Emailமின்னஞ்சல் Google Workspace (MX) + Zoho Campaigns for bulk mail (SPF include:zcsend.in).Google Workspace (MX) + மொத்த அஞ்சலுக்கு Zoho Campaigns (SPF include:zcsend.in).
Error trackingபிழை கண்காணிப்பு Self-hosted Sentry at sentry.articunocoding.com.சுய-ஹோஸ்ட் Sentrysentry.articunocoding.com.
Build vendor (OSINT)உருவாக்கிய நிறுவனம் (OSINT) Sentry DSN leaks the developer: articunocoding.com (their site on AWS Mumbai ap-south-1).Sentry DSN டெவலப்பரை வெளிப்படுத்துகிறது: articunocoding.com (அவர்களின் தளம் AWS மும்பை ap-south-1 இல்).
Front-endமுன்தளம் Plain static multi-page HTML (not Next.js/React) + jQuery 3.6, Bootstrap 5.3, SweetAlert2, AOS, Slick carousel, Typed.js.எளிய நிலையான பல-பக்க HTML (Next.js/React அல்ல) + jQuery 3.6, Bootstrap 5.3, SweetAlert2, AOS, Slick carousel, Typed.js.
Back-endபின்தளம் Separate API at api-2.wetheleader.org — auth, OTP, counter, voice-feed, grassroots answers.தனி API — api-2.wetheleader.org — auth, OTP, counter, voice-feed, grassroots answers.

2. Why the counter is FAKE — evidence2. எண்ணிக்கை ஏன் போலி — ஆதாரம்

Source: GET https://api-2.wetheleader.org/api/get-counter-v2 → {"count":…}. Three independent tests:மூலம்: GET https://api-2.wetheleader.org/api/get-counter-v2 → {"count":…}. மூன்று தனித் சோதனைகள்:

(a) It's computed per request, not read from a database(அ) ஒவ்வொரு கோரிக்கைக்கும் கணக்கிடப்படுகிறது, தரவுத்தளத்திலிருந்து அல்ல

Every response sets last-modified to the exact second of the request — a stored member tally would not:ஒவ்வொரு பதிலும் last-modifiedகோரிக்கையின் சரியான வினாடிக்கு அமைக்கிறது — சேமிக்கப்பட்ட உறுப்பினர் எண்ணிக்கை இப்படி இருக்காது:

date: Sat, 06 Jun 2026 14:21:01 GMT   last-modified: Sat, 06 Jun 2026 14:21:01 GMT   {"count":1458105}
date: Sat, 06 Jun 2026 14:21:03 GMT   last-modified: Sat, 06 Jun 2026 14:21:03 GMT   {"count":1458113}

(b) It's a near-perfect straight line vs the wall clock(ஆ) நேரத்துடன் ஒப்பிடுகையில் கிட்டத்தட்ட சரியான நேர்கோடு

15 timed samples, least-squares fit of count against epoch time:15 நேர மாதிரிகள், epoch நேரத்திற்கு எதிராக count இன் least-squares பொருத்தம்:

slope = ~4.55 counts / second
R²    = 0.988      (1.0 = a perfectly straight line vs time)
⇒ count ≈ 4.5 × current_time + constant

Real signups are bursty and dip overnight. A 0.988 fit to a straight line is mechanical.உண்மையான பதிவுகள் சீரற்றவை, இரவில் குறையும். நேர்கோட்டுக்கு 0.988 பொருத்தம் என்பது இயந்திரத்தனமானது.

(c) The implied rate is impossible(இ) குறிக்கப்படும் வேகம் சாத்தியமற்றது

~4.5/sec = ~345,000–393,000 new "leaders" every day, monotonic, 24/7, no day/night variation. Projecting that rate backwards, the counter would have been zero only ~3.7 days ago — yet the site claims years of programs and "50,000 lives impacted." The headline ~1.45 million is a decorative, time-seeded vanity counter. ~4.5/வி = தினமும் ~3,45,000–3,93,000 புதிய "leaders", தொடர்ந்து உயரும், 24/7, பகல்/இரவு வேறுபாடு இல்லை. இந்த வேகத்தைப் பின்னோக்கி நீட்டினால், எண்ணிக்கை ~3.7 நாட்களுக்கு முன்பு மட்டுமே பூஜ்ஜியமாக இருந்திருக்கும் — ஆனால் தளம் பல ஆண்டு திட்டங்களையும் "50,000 உயிர்களுக்கு தாக்கம்" என்றும் கூறுகிறது. தலைப்பிலுள்ள ~1.45 மில்லியன் என்பது அலங்கார, நேர-அடிப்படையிலான போலி எண்.

Live PoC — the counter is generated from the clockநேரடி PoC — எண்ணிக்கை கடிகாரத்திலிருந்து உருவாகிறது

Source: GET .../api/get-counter-v2. Routed through a same-origin proxy on this host so the browser can read the upstream Last-Modified header (the API sends no CORS headers).மூலம்: GET .../api/get-counter-v2. உலாவி upstream Last-Modified தலைப்பைப் படிக்க, இந்த ஹோஸ்டில் ஒரே-origin proxy வழியாக (API CORS தலைப்புகளை அனுப்பாது).

The tell: on every request Last-Modified equals the server's current time (Date), and the count rises smoothly at a fixed rate. A real COUNT(*) of members would carry the timestamp of the last actual signup and grow in irregular bursts — not tick like a clock.அடையாளம்: ஒவ்வொரு கோரிக்கையிலும் Last-Modified ஆனது சர்வரின் தற்போதைய நேரத்திற்கு (Date) சமம், எண்ணிக்கை நிலையான வேகத்தில் சீராக உயர்கிறது. உண்மையான உறுப்பினர் COUNT(*) கடைசி பதிவின் நேர முத்திரையைக் கொண்டிருக்கும், சீரற்ற முறையில் அதிகரிக்கும் — கடிகாரம் போல் அல்ல.

Live graph — "membership" growth in real timeநேரடி வரைபடம் — "உறுப்பினர்" வளர்ச்சி நிகழ்நேரத்தில்

This page auto-samples the counter every 3 seconds and plots it live. Watch the near-perfectly straight, ever-rising line — the signature of a clock-driven number, not organic human sign-ups (which would be jagged and flatten overnight).இந்தப் பக்கம் ஒவ்வொரு 3 வினாடிக்கும் எண்ணிக்கையை தானாக மாதிரியெடுத்து நேரடியாக வரைகிறது. கிட்டத்தட்ட சரியான நேர்கோடு, தொடர்ந்து உயரும் கோடு — கடிகாரத்தால் இயக்கப்படும் எண்ணின் அடையாளம், இயற்கையான மனித பதிவுகள் அல்ல.

— green = actual cumulative · amber dashed = least-squares straight-line fit (R² shown above)— பச்சை = உண்மையான மொத்தம் · ஆம்பர் புள்ளிக்கோடு = least-squares நேர்கோட்டுப் பொருத்தம் (R² மேலே)

Rate of change — new "members" per second (the real tell)மாற்ற வேகம் — வினாடிக்கு புதிய "உறுப்பினர்" (உண்மையான அடையாளம்)

The derivative of the line above (trailing-window slope). Real human sign-ups would be jagged here and dip toward zero overnight; a clock-driven number sits on a flat horizontal line.மேலே உள்ள கோட்டின் வகையீடு (trailing-window சாய்வு). உண்மையான மனித பதிவுகள் இங்கே சீரற்றதாகவும் இரவில் பூஜ்ஜியத்தை நோக்கிக் குறையும்; கடிகாரத்தால் இயக்கப்படும் எண் தட்டையான கிடைமட்டக் கோட்டில் இருக்கும்.

3. Why ~345k–393k registrations/day from Tamil Nadu is not possible3. தமிழ்நாட்டிலிருந்து நாளொன்றுக்கு ~3.45–3.93 லட்சம் பதிவுகள் ஏன் சாத்தியமற்றது

Registration is gated by a real, server-validated OTP (§4) — every counted member must receive an SMS, read it, and enter a valid code. Against reality:பதிவு உண்மையான, சர்வரில் சரிபார்க்கப்படும் OTP மூலம் தடைசெய்யப்படுகிறது (§4) — எண்ணப்படும் ஒவ்வொரு உறுப்பினரும் SMS பெற்று, படித்து, சரியான குறியீட்டை உள்ளிட வேண்டும். உண்மையுடன் ஒப்பிடுகையில்:

The genuine OTP is exactly what proves the counter false: real OTP gating makes the displayed growth rate physically impossible, so the number cannot be real members.உண்மையான OTP தான் எண்ணிக்கை போலி என்பதை நிரூபிக்கிறது: உண்மையான OTP தடை, காட்டப்படும் வளர்ச்சி வேகத்தை இயற்பியல் ரீதியாக சாத்தியமற்றதாக்குகிறது, எனவே அந்த எண் உண்மையான உறுப்பினர்களாக இருக்க முடியாது.

4. Why the OTP is REAL4. OTP ஏன் உண்மை

The entered code is never compared in the browser; it is sent to the server, which decides. A bogus code is rejected:உள்ளிட்ட குறியீடு உலாவியில் ஒருபோதும் ஒப்பிடப்படுவதில்லை; அது சர்வருக்கு அனுப்பப்பட்டு, சர்வரே முடிவு செய்கிறது. போலிக் குறியீடு நிராகரிக்கப்படுகிறது:

POST /api/auth/register   {"otp":"000000", ...}
→ HTTP 400  {"error":"Invalid or expired OTP"}

No hard-coded code anywhere in client JS. +91 numbers get SMS OTP; other countries fall back to email OTP.client JS இல் எங்கும் hard-code செய்யப்பட்ட குறியீடு இல்லை. +91 எண்கள் SMS OTP பெறும்; பிற நாடுகள் மின்னஞ்சல் OTP பெறும்.

5. Live PoC — Phone-number enumeration MEDIUM5. நேரடி PoC — தொலைபேசி எண் enumeration நடுத்தரம்

The endpoint POST /api/auth/check returns {"exists":true|false} for any number, with no authentication — letting anyone test whether a given phone number belongs to a registered member. This is a privacy leak. The form below demonstrates it live (routed through a rate-limited proxy on this host, because the API omits CORS headers for browsers).POST /api/auth/check எண்ட்பாயிண்ட் எந்த எண்ணுக்கும் அங்கீகாரம் இல்லாமல் {"exists":true|false} திருப்பித் தருகிறது — கொடுக்கப்பட்ட தொலைபேசி எண் பதிவுசெய்யப்பட்ட உறுப்பினருக்கு சொந்தமா என யாரும் சோதிக்கலாம். இது தனியுரிமை கசிவு. கீழே உள்ள படிவம் இதை நேரடியாகக் காட்டுகிறது (API உலாவிகளுக்கு CORS தலைப்புகளை வழங்காததால், இந்த ஹோஸ்டில் வேக-வரம்பிட்ட proxy வழியாக).

Is this number a wetheleader.org member?இந்த எண் wetheleader.org உறுப்பினரா?

Proof-of-concept only. This calls the target's own public endpoint to demonstrate the enumeration flaw documented above. Single lookups only and rate-limited. Use it responsibly — ideally with a number you own. The fix is on the vendor's side: require authentication and stop disclosing membership existence.ஆதார நிரூபணம் மட்டுமே. மேலே ஆவணப்படுத்தப்பட்ட enumeration குறையைக் காட்ட இது இலக்கின் சொந்த பொது எண்ட்பாயிண்டை அழைக்கிறது. ஒற்றைத் தேடல்கள் மட்டுமே, வேக-வரம்பிடப்பட்டது. பொறுப்புடன் பயன்படுத்தவும் — முடிந்தால் உங்கள் சொந்த எண்ணுடன். சரிசெய்தல் வழங்குநரின் பக்கம்: அங்கீகாரத்தைக் கோரி, உறுப்பினர் இருப்பை வெளிப்படுத்துவதை நிறுத்த வேண்டும்.

6. Full findings6. முழு கண்டுபிடிப்புகள்

Fabricated counter presented as live membership HIGHநேரடி உறுப்பினராகக் காட்டப்படும் போலியான எண்ணிக்கை உயர்வு

Auto-generated number shown as real membership — deceptive to donors, partners and the public; an integrity / advertising-standards concern for a registered foundation.தானாக உருவாக்கப்பட்ட எண் உண்மையான உறுப்பினராகக் காட்டப்படுகிறது — நன்கொடையாளர்கள், கூட்டாளர்கள், பொதுமக்களை ஏமாற்றுவது; பதிவுசெய்யப்பட்ட அறக்கட்டளைக்கு நேர்மை / விளம்பர-தர கவலை.

OTP/SMS endpoint with no visible abuse controls HIGHதவறான பயன்பாட்டுக் கட்டுப்பாடு இல்லாத OTP/SMS எண்ட்பாயிண்ட் உயர்வு

POST /api/auth/send-otp is callable directly with the static token, no CAPTCHA, no rate-limit headers. If unthrottled server-side it enables SMS-bombing (harass real numbers + drain the SMS budget). Not load-tested, to avoid spamming real phones.POST /api/auth/send-otp ஐ நிலையான டோக்கனுடன் நேரடியாக அழைக்கலாம், CAPTCHA இல்லை, வேக-வரம்பு தலைப்புகள் இல்லை. சர்வர் பக்கம் கட்டுப்படுத்தப்படாவிட்டால் SMS-குண்டுவீச்சு சாத்தியம் (உண்மை எண்களைத் தொந்தரவு + SMS பட்ஜெட்டை வீணாக்கும்). உண்மையான தொலைபேசிகளுக்கு spam தவிர்க்க, சுமை-சோதனை செய்யப்படவில்லை.

Phone-number enumeration MEDIUMதொலைபேசி எண் enumeration நடுத்தரம்

/api/auth/check discloses membership existence to anyone — see live PoC (§5)./api/auth/check உறுப்பினர் இருப்பை யாருக்கும் வெளிப்படுத்துகிறது — நேரடி PoC (§5) ஐக் காண்க.

"Security-theater" API auth MEDIUM"பாதுகாப்பு-நாடகம்" API அங்கீகாரம் நடுத்தரம்

Static Authorization: Bearer public-api shipped in client JS — not authentication; trivially replayed.client JS இல் அனுப்பப்படும் நிலையான Authorization: Bearer public-api — இது அங்கீகாரம் அல்ல; எளிதில் மீண்டும் பயன்படுத்தலாம்.

Loose CORS / inconsistent policy MEDIUMதளர்வான CORS / சீரற்ற கொள்கை நடுத்தரம்

API advertises access-control-allow-credentials: true with allow-origin: * for non-CORS clients, yet omits Allow-Origin entirely on real cross-origin requests — a contradictory, sloppy policy.API ஆனது non-CORS கிளையன்ட்களுக்கு allow-origin: * உடன் access-control-allow-credentials: true ஐக் காட்டுகிறது, ஆனால் உண்மையான cross-origin கோரிக்கைகளில் Allow-Origin ஐ முற்றிலும் விட்டுவிடுகிறது — முரண்பாடான, கவனக்குறைவான கொள்கை.

Missing security headers on the main site MEDIUMமுதன்மை தளத்தில் இல்லாத பாதுகாப்பு தலைப்புகள் நடுத்தரம்

No Strict-Transport-Security (HSTS), no Content-Security-Policy, no X-Frame-Options (→ clickjacking), no Permissions-Policy. Only X-Content-Type-Options is set.Strict-Transport-Security (HSTS) இல்லை, Content-Security-Policy இல்லை, X-Frame-Options இல்லை (→ clickjacking), Permissions-Policy இல்லை. X-Content-Type-Options மட்டுமே அமைக்கப்பட்டுள்ளது.

CDN scripts without Subresource Integrity LOWSubresource Integrity இல்லாத CDN ஸ்கிரிப்ட்கள் குறைவு

jQuery, Bootstrap, SweetAlert2, AOS, Slick, Typed.js loaded from jsdelivr/unpkg/code.jquery.com with no integrity= hashes — a CDN compromise = arbitrary JS on the site.jQuery, Bootstrap, SweetAlert2, AOS, Slick, Typed.js ஆகியவை integrity= hash இல்லாமல் jsdelivr/unpkg/code.jquery.com இலிருந்து ஏற்றப்படுகின்றன — CDN சமரசம் = தளத்தில் தன்னிச்சையான JS.

Client-side-only validation LOWclient பக்கம் மட்டும் சரிபார்ப்பு குறைவு

Age 18+, password strength and field checks run only in-browser and are bypassable via direct API calls; must be re-enforced server-side.வயது 18+, கடவுச்சொல் வலிமை, புல சரிபார்ப்புகள் உலாவியில் மட்டுமே இயங்குகின்றன, நேரடி API அழைப்புகள் மூலம் தவிர்க்கலாம்; சர்வர் பக்கம் மீண்டும் செயல்படுத்தப்பட வேண்டும்.

Telemetry may capture PII + exposed Sentry DSN LOWTelemetry PII ஐ சேகரிக்கலாம் + வெளிப்பட்ட Sentry DSN குறைவு

WTLSentry.captureValidation ships entered values (mobiles/emails) to self-hosted Sentry on failures; the DSN …@sentry.articunocoding.com/3 is exposed in client JS (allows event spoofing / quota abuse).WTLSentry.captureValidation தோல்விகளின்போது உள்ளிட்ட மதிப்புகளை (மொபைல்/மின்னஞ்சல்) சுய-ஹோஸ்ட் Sentry க்கு அனுப்புகிறது; DSN …@sentry.articunocoding.com/3 client JS இல் வெளிப்படுகிறது (event போலி / ஒதுக்கீடு தவறான பயன்பாடு).

Open read endpoint LOWதிறந்த படிக்கும் எண்ட்பாயிண்ட் குறைவு

GET /api/voice-feed is publicly readable; "impact" stats (+50,000 / +2000 / +50) are hard-coded copy, not data-backed.GET /api/voice-feed பொதுவாக படிக்கக்கூடியது; "impact" புள்ளிவிவரங்கள் (+50,000 / +2000 / +50) hard-code செய்யப்பட்ட உரை, தரவு அடிப்படையில் அல்ல.