this post was submitted on 12 Feb 2026
65 points (93.3% liked)
Technology
81078 readers
4048 users here now
This is a most excellent place for technology news and articles.
Our Rules
- Follow the lemmy.world rules.
- Only tech related news or articles.
- Be excellent to each other!
- Mod approved content bots can post up to 10 articles per day.
- Threads asking for personal tech support may be deleted.
- Politics threads may be removed.
- No memes allowed as posts, OK to post as comments.
- Only approved bots from the list below, this includes using AI responses and summaries. To ask if your bot can be added please contact a mod.
- Check for duplicates before posting, duplicates may be removed
- Accounts 7 days and younger will have their posts automatically removed.
Approved Bots
founded 2 years ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
view the rest of the comments
The details on how it works from the website for those reading this chain.
"how does this work
k-id, the age verification provider discord uses doesn't store or send your face to the server. instead, it sends a bunch of metadata about your face and general process details. while this is good for your privacy (well, considering some other providers send actual videos of your face to their servers), its also bad for them, because we can just send legitimate looking metadata to their servers and they have no way to tell its not legitimate. while this was easy in the past, k-id's partner for face verification (faceassure) has made this significantly harder to achieve after amplitudes k-id verifier was released, (which doesn't work anymore because of it.)
with discord's decision of making the age verification requirement global, we decided to look into it again to see if we can bypass the new checks. step 1: encrypted_payload and auth_tag
the first thing we noticed that the old implementation doesn't send when comparing a legitimate request payload with a generated one, is its missing encrypted_payload, auth_tag, timestamp and iv in the body.
looking at the code, this appears to be a simple AES-GCM cipher with the key being nonce + timestamp + transaction_id, derived using HKDF (sha256). we can easily replicate this and also create the missing parameters in our generated output. step 2: prediction data
heres where it kind of gets tricky, even after perfectly replicating the encryption, our verification attempt still doesn't succeed, so they must also be doing checks on the actual payload.
after some trial and error, we narrowed the checked part to the prediction arrays, which are outputs, primaryOutputs and raws.
turns out, both outputs and primaryOutputs are generated from raws. basically, the raw numbers are mapped to age outputs, and then the outliers get removed with z-score (once for primaryOutputs and twice for outputs).
there is also some other differences:
XScaledShiftAmt and yScaledShiftAmt in predictions are not random but rather can be one of two values It is checked that the media name (camera) matches one of your media devices in the array of devices It is checked if the states completion times match the state timeline
with all of that done, we can officially verify our age as an adult. all of this code is open source and available on github, so you can actually see how we do this exactly."