CDSL: Security Architecture Analysis
Responsible Disclosure Notice: This post describes architectural weaknesses and their potential impact. No exact API endpoints (beyond the publicly visible URL paths), hardcoded key values, or step-by-step reproduction instructions are included. The reCAPTCHA site key is referenced by pattern, not by value. Findings have been reported through appropriate channels.
| Field | Detail |
|---|---|
| Application | Central Depository Services Limited (CDSL) — Easi / Easiest / Nomination / Consent portals |
| Ministry/Body | Ministry of Finance (MoF) / SEBI-regulated |
| Data Category | PAN, BOID (demat account IDs), KYC, nominee details, OTP, transaction instructions |
| Sensitivity | 🔴 High |
| Platform | Web (cdslindia.com ASP.NET WebForms + web.cdslindia.com login) |
| Analysis Date | 2026-06-14 |
| Critical Findings | 2 |
| High Findings | 3 |
| Medium Findings | 3 |
| Low Findings | 2 |
Summary
This analysis examined the client-side architecture of CDSL — India’s largest securities depository by number of demat accounts (5+ crore beneficial owners). The focus was on the public-facing authentication surfaces: Nomination Login, OTP Authentication, Consent Login, and the Easi/Easiest login landing.
CDSL’s client-side encryption uses AES-CBC with keys generated by Math.random() — JavaScript’s built-in pseudo-random number generator that is explicitly documented as not cryptographically secure. The PBKDF2 key-derivation function is called without an iterations parameter, defaulting to 1 iteration (effectively no brute-force resistance). Both the AES key (f) and IV (s) are base64-encoded and sent in the same POST body as the ciphertext (seck).
The analysis identified 2 critical, 3 high, 3 medium, and 2 low severity findings. The presence of Google reCAPTCHA v2 across endpoints is a positive contrast to the legacy image CAPTCHAs seen elsewhere in this series.
Risk Factors
- AES encryption keys generated using
Math.random()— JavaScript’s documented-not-cryptographic PRNG; predictable with knowledge of seed (typically time-based) - PBKDF2 called without
iterationsparameter — defaults to 1 iteration; provides zero brute-force resistance - AES key (
f), IV (s), and ciphertext (seck) all sent in same POST body — encryption theatre - CryptoJS v3.1.2 (2013) bundled as
cpemain/includes/lib/CryptoCDSL/aes.js— same outdated version as PM-Kisan - Single reCAPTCHA v2 site key shared across multiple endpoints — if the site key is ever rate-limit-abused or the v2 challenge is bypassed at scale (commercial solving services charge ~$1–3 per 1,000 solves), all endpoints lose their CAPTCHA protection simultaneously
web.cdslindia.com(the Easi/Easiest login host) returned HTTP 530 (Cloudflare block) on direct curl from a residential-class IP — suggests aggressive bot mitigation that may also block legitimate automated tooling and security researchers- ASP.NET WebForms ViewState on
NominationLogin.aspxwithout visible__VIEWSTATEUSERKEY—ViewState tampering / replay risk Math.random()returns 64-bit doubles; effective entropy of an 8-character “random” string fromMath.random()is far below the cryptographic 128-bit baseline
Impact Scenarios
Scenario: Math.random() Enables Key Prediction
CDSL’s AESutil.js defines:
function getf() {
return randomString(16, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
}
function gets() { /* same */ }
function randomString(length, chars) {
var result = '';
for (var i = length; i > 0; --i)
result += chars[Math.round(Math.random() * (chars.length - 1))];
return result;
}
Math.random() is the V8/SpiderMonkey PRNG — typically an xorshift128+ variant seeded with the current time and a per-process state. It is explicitly documented as not cryptographically secure in every major JS engine and in MDN. For a 16-character string from a 62-character alphabet, the theoretical entropy is ~95 bits — but the effective entropy is bounded by the PRNG state, which is recoverable with as few as 4–5 observed outputs in academic attacks. An attacker who can sniff a single CDSL login request (e.g., via a compromised ISP, a corporate proxy with logging, or a TLS MITM with a rogue CA) can observe the base64-decoded f and s values, recover the PRNG state, and predict future keys for other sessions on the same V8 isolate.
Scenario: PBKDF2 Default Iterations = Zero Brute-Force Resistance
The same AESutil.js defines:
function generateKey(s, p) {
return CryptoJS.PBKDF2(p, s, { keySize: 256/32 });
}
CryptoJS’s PBKDF2 defaults to 1 iteration when iterations is not specified. The function comment mentions iterationCount = 1000, but that value is never passed to the PBKDF2 call. OWASP recommends at least 600,000 iterations for PBKDF2-SHA256 as of 2023. A single-iteration PBKDF2 is equivalent to a single SHA-256 hash — brute-forceable at billions of attempts per second on commodity GPUs.
Even though this function appears unused in the live login flow (the actual flow uses getf()/gets() directly), its presence in shipped code indicates the development team’s understanding of KDF parameters is below the bar — and any future refactor that wires generateKey() into production will inherit the 1-iteration default.
Scenario: Single reCAPTCHA Key Across Endpoints
The same data-sitekey value is used on:
www.cdslindia.com/bo/NominationLogin.aspxwww.cdslindia.com/eservices/consent/Login
And likely on every other CDSL login surface. If this v2 site key is ever solved at scale (commercial CAPTCHA-solving services already achieve >90% solve rates on reCAPTCHA v2 image challenges for under $3 per 1,000 solves), all CDSL endpoints that depend on it lose their primary bot-mitigation control simultaneously. Best practice is to use per-endpoint site keys for tiered risk (login = stricter, public lookup = looser) and to migrate to reCAPTCHA v3 / Enterprise with score-based thresholds.
Scenario: BOID Enumeration via Predictable Encoding
The Nomination Login page encodes the BOID (Beneficial Owner ID — the 16-digit demat account number) with btoa() (plain base64) before submission:
var EncodedBOID = btoa(document.getElementById('txtboid').value);
$("#txtBOIDencoded").val(EncodedBOID);
Plain base64 is reversible by anyone who reads the request. If an attacker can sniff or proxy the request, they recover the BOID in cleartext. Combined with the AES-key disclosure above, both the BOID and the PAN are recoverable from a single captured login request.
Findings Overview
| Severity | Category | Detail |
|---|---|---|
| 🔴 CRITICAL | Non-Cryptographic PRNG for AES Keys | Math.random() used to generate AES key and IV — predictable |
| 🔴 CRITICAL | PBKDF2 with Default 1 Iteration | generateKey() calls PBKDF2 without iterations parameter — zero brute-force resistance |
| 🟠 HIGH | AES Key+IV+Ciphertext in Same POST | f, s, seck form fields all sent together — encryption theatre |
| 🟠 HIGH | Plain Base64 Encoding of BOID | Demat account number encoded with reversible btoa() |
| 🟠 HIGH | Single reCAPTCHA v2 Site Key Across Endpoints | Shared site key compromises all endpoints on bypass |
| 🟡 MEDIUM | Obsolete Crypto Library | CryptoJS v3.1.2 (2013) bundled as cpemain/includes/lib/CryptoCDSL/aes.js |
| 🟡 MEDIUM | ViewState Without User Key | ASP.NET WebForms ViewState lacks visible __VIEWSTATEUSERKEY |
| 🟡 MEDIUM | Login Host Blocks Researcher Traffic | web.cdslindia.com returns HTTP 530 to non-browser clients — limits independent security research |
| 🔵 LOW | Deprecated X-XSS-Protection Header | x-xss-protection: 1; mode=block set (deprecated per MDN) |
| 🔵 LOW | Infrastructure Header Leakage | cf-cache-status: DYNAMIC and server: cloudflare reveal CDN topology |
Why This Matters
CDSL is the larger of India’s two securities depositories by account count:
- 5+ crore demat accounts (versus NSDL’s ~3 crore)
- PAN-seeded identity for every beneficial owner
- Easi / Easiest — primary retail-investor-facing portals for holdings, transactions, and inter-depository transfers
- Nomination — critical for succession planning; if compromised, attackers could redirect nominee details
- Consent Login — used for DP (Depository Participant) authorisation flows
When the cryptographic layer protecting logins uses non-cryptographic PRNG and single-iteration PBKDF2, the effective security is dramatically below what SEBI’s Cybersecurity & Cyber Resilience Framework (CSCRF, 2024) requires of a MIIs (Market Infrastructure Institutions). Depositories are explicitly designated as MIIs and are held to a higher cryptographic bar than general fintech apps.
This analysis continues the series on Indian government / quasi-government portals that ship cryptographic primitives to the client. CDSL is notable because the client-side code (AESutil.js, 965 bytes) is small enough to audit in full — the weaknesses are not buried in a 1.6 MB bundle, they are in plain sight. That they have persisted into 2026 suggests the development team has not had an independent security review of the crypto layer.
Responsible Disclosure Timeline
| Date | Event |
|---|---|
| 2026-06-14 | Blog analysis published with redacted details |
| 2026-06-14 | CERT-In disclosure initiated (V1–V6 format) for Math.random() PRNG |
| 2026-06-14 | SEBI CSCRF compliance escalation for MII cybersecurity framework |
| ~2026-09-12 | 90-day responsible disclosure deadline |
Recommendations
Immediate (0–7 days)
- Replace
Math.random()withcrypto.getRandomValues()inAESutil.js. The Web Crypto API provides a cryptographically secure PRNG available in all modern browsers. - Add explicit
iterations: 600000parameter to the PBKDF2 call ingenerateKey()(OWASP 2023 minimum for PBKDF2-SHA256). Or migrate to Argon2id. - Stop sending the AES key (
f) and IV (s) in the same POST body as the ciphertext. Either remove client-side encryption entirely (rely on TLS) or implement proper hybrid encryption with a server-provided RSA public key so the AES key is never transmitted. - Rotate the reCAPTCHA site key as a precaution, and assign separate site keys per endpoint tier.
Short-Term (1–4 weeks)
- Migrate from reCAPTCHA v2 to reCAPTCHA v3 / Enterprise with score-based thresholds — v3 is invisible to users and substantially harder to solve via commercial services.
- Replace plain
btoa()BOID encoding with the same encryption scheme used for PAN (when fixed) or with server-side session storage of the BOID. - Add
__VIEWSTATEUSERKEYto all ASP.NET WebForms pages to prevent ViewState replay across users. - Upgrade CryptoJS from v3.1.2 to a modern cryptographic library (e.g.,
@noble/ciphersor WebCrypto API), or eliminate client-side crypto entirely. - Whitelist security-researcher user agents (or publish a security.txt with a friendly scan policy) on
web.cdslindia.comso that legitimate researchers can audit the login flow without being blocked at the CDN edge.
Structural (1–3 months)
- Adopt a uniform client-side crypto policy across all CDSL properties — server-provided RSA public keys, per-session AES keys generated via Web Crypto, no client-side constants.
- Independent security audit by a CERT-In empanelled auditor against SEBI CSCRF (with MII-tier scope), with findings published in summary form.
- Publish a
security.txt(/.well-known/security.txt) on all CDSL domains with a vulnerability-disclosure contact. - Bug bounty programme on Intigriti or HackerOne to crowdsource ongoing review of the authentication surfaces.
Cross-References
- Aadhaar (UIDAI): Security Architecture Analysis — foundational identity layer
- NSDL: Security Architecture Analysis — peer depository (same series, prior analysis)
- PM-Kisan: Security Architecture Analysis — same client-side AES anti-pattern in DBT
- Series index: Indian Government Portal Security Audit (tag:
india-gov)
This post is part of an ongoing series of responsible-disclosure security analyses of Indian government and quasi-government digital portals. No exploit details, exact endpoints, or hardcoded secret values are included. If you are a CDSL operator or SEBI official and would like to coordinate on remediation, contact CERT-In or SEBI’s cybersecurity division directly.