🎯 Red team test — rules of engagement
MySelf-Lab is a showcase deliberately exposed to attack. It inverts OWASP Juice Shop: here the application is protected by the MySelf ecosystem (SelfRecover, SelfDataGuard, SelfModerate), and the goal is to prove — or disprove — that protection under real conditions. Anyone following the rules below is authorised to carry out research here.
📊 The lab in numbers
23days online
1authentication attempts repelled
1reports received
0flag captured
Aggregated from data the lab already collects — no audience measurement, no tracking cookie, no address retained.
📍 Scope
✅ In scope
- The MySelf-Lab web application (this site) and all its paths
- SelfRecover authentication (sign-up, log-in, recovery)
- SelfDataGuard encrypted private messages and profiles
- SelfModerate reputation and voting
- The report submission form below
⛔ Out of scope
- Any infrastructure, domain or service other than this site
- The server's SSH service (port 22) — authentication attempts there trigger a network-level block that would also cut off your access to this site
- The hosting provider, the registrar, third-party suppliers
- Accounts or data belonging to real people
- The maintainer's machine, accounts and mailboxes
An extended scope (other MySelf components) may be agreed privately with a selected team, under written agreement. It is not published here.
🏁 Objectives (capture the flag)
Season 2 — two flags, in two demonstration accounts:
FLAG-E2E-… in the personal memo of ctf_alpha — encrypted in the browser (Argon2id → HKDF → AES-256-GCM), key never present on the server.
FLAG-DM-… in a private message from ctf_beta to ctf_gamma — encrypted at rest on the server by SelfDataGuard (XChaCha20-Poly1305), with a key held outside the database.
FLAG-E2E: neither a database dump nor administrator access reveals it — the key is only ever derived in its owner's browser. Full control of the server does defeat it: that server is what ships the derivation script, and whoever controls it can ship another one that harvests the key on the next unlock. "End-to-end" therefore holds as long as the server ships the published code. FLAG-DM: a dump alone is not enough, but the server key (.blindkey) brings it down — the accepted limit of server-side encryption. The challenge is to bring either one back in the clear.
MITRE ATT&CK and OWASP references are given per objective (web application vulnerabilities map to OWASP/CWE, outside the ATT&CK scope).
- 🎯 Exfiltrate FLAG-E2E, the memo of
ctf_alpha, and produce it in the clear core objective - 🔓 Bypass SelfRecover authentication (take over an account without its password) ATT&CK T1110 · T1078 · OWASP A07
- 💬 Read FLAG-DM, the message from
ctf_beta to ctf_gamma, in the clear OWASP A01 - ⚖️ Manipulate SelfModerate reputation (bury a member with coordinated fake accounts, or promote yourself) CAPEC-210
- 🪪 Hijack a session or land an authenticated CSRF attack ATT&CK T1539 · CWE-352
- 🧨 Escalate privileges: obtain administrator access (the
/admin panel) ATT&CK T1078 · OWASP A01
✅ Allowed
- Web application testing: injection (SQL, command), XSS, IDOR, authentication bypass, business logic
- Cryptanalysis of SelfDataGuard blobs
- Attempts to dump the database through an application flaw
- Reasoned fuzzing of endpoints
- Interception and replay within scope
⛔ Forbidden
- Denial of service, flooding, volumetric stress (DoS / DDoS)
- Social engineering aimed at real people, the maintainer or the hosting provider
- Physical attacks, or attacks on premises
- Pivoting or scanning outside the declared scope
- Destruction, encryption (ransomware) or permanent alteration of data
- Mass exfiltration beyond proof; spam; illegal content
⏱️ Technical note — rate limiting
The authentication endpoints (/api/login.php, /api/register.php) are rate-limited to 10 requests per second, with a burst allowance of 20.
A 429 response signals this rate limiting — or the account's anti-brute-force lockout. It is not a denial of service you caused, and there is no need to report it as one.
Reasoned fuzzing is unaffected: only massively parallel requests are. No ban is applied — on this server, scanning is part of the game.
📐 Known and accepted limits
What follows is already established, and published so you don't spend time on it: a documented limit is not a finding. Going past one is a finding: a working exploitation of any of these boundaries, not the argument that it exists.
- The memo vault has two locks. Its key is drawn at random, then sealed twice: under the account password, and under a passphrase specific to the vault. Anyone who obtains the blobs attacks the cheaper of the two offline, with no attempt counter; the cost per attempt is a single Argon2id derivation at
t=3, m=64 MiB, p=1 (the profile shared with SelfDataGuard). "End-to-end" says the server never sees the key — not that the memo withstands a weak password, nor that the server always ships the same code: it is the server that delivers the derivation script, and whoever controls it can deliver another. - A third party shuts an account's login in five requests. The failed-login counter is fed by the SUBMITTED name, which nobody needs to own: five failures lock the login for fifteen minutes — the correct password included — and a steady burst keeps it shut. That counter does not reach recovery: its throttle counts elsewhere, and the correct passphrase opens a level-1 recovery while the login is locked. The recovery throttles — levels 1, 2 and 3 — and the device-enrolment one count under a label derived from a server secret, which a third party cannot forge: the login counter is the only one left under the name in the clear. The per-ORIGIN ceiling now counts recovery doors only: an address saturated with failed logins keeps its recovery open. ⚠️ Saturating an address with failed RECOVERY attempts still throttles recovery coming from it — denial of service per origin, out of scope, and you must share your target's address to reach them.
- A third party can occupy an account's only level-3 case slot. Opening a case requires nothing but an account name, and an account has only one active case at a time: whoever opens first holds the slot, and the account holder cannot clear it themselves. Their way out goes through the arbiter, who has an abandon action — it closes a case without counting anything. A refusal no longer freezes anything by itself: it is counted and reported to the arbiter, and only an arbiter places a freeze, which they lift. This is denial of service, hence out of scope — published here because all it takes is a name.
- The two passphrases do not share a floor. The account recovery passphrase is generated with 6 words — 77.55 bits — and every typed word is validated against the 7776-word list; typing is nonetheless accepted from 4 words, that is 51.70 bits. The memo vault passphrase goes through at 4 words and 16 characters, with no list validation and through a browser-side check: four made-up words will seal it.
- The browser holds the device's second factor, not the server. An enrolled device's private key lives in browser storage, encrypted under a key derived from the memorised word — a word whose floor, four characters, is itself checked by the browser. The server only ever verifies a signature: whoever obtains that blob attacks the word offline, with no attempt counter. The device really is a second factor; it simply is not guarded where you would expect.
🧭 Responsible conduct
- On a critical finding: stop exploiting, secure minimal proof, report without delay.
- Proof means a minimal extract — a screenshot, one decrypted record — not a full dump.
- Coordinated disclosure: no publication before a fix and mutual agreement. Reference window: 90 days.
🛟 Safe harbour
As long as your research follows these rules, we consider it authorised and carried out in good faith. We will take no action against you, and we will do our best to clear up any uncertainty quickly. If in doubt about the scope or a technique: ask before you act, using the form below.
🌐 These rules exist in French and English. In case of discrepancy between versions, the French text prevails.
🏆 Hall of fame
No validated contribution yet. Be the first to appear here.