DEV Community

Cover image for I Tried to Break My Own Security Suite. It Fought Back (and I Found 1 Thing I'm Not Happy About)
Akhouri Anmol Kumar
Akhouri Anmol Kumar

Posted on

I Tried to Break My Own Security Suite. It Fought Back (and I Found 1 Thing I'm Not Happy About)

Description: "8,432 lines of Python, 200 bit-flips, 460 fuzzed inputs, and one honest flaw. Here's what happened when I attacked ATLOCK v5 before releasing it."

TL;DR: I built a single-file security suite in pure Python. Before release, I locked it in a clean virtual environment and tried to wreck it. Most things held. One thing made me frown. You can try the current version (v4) today, and v5 is already built and waiting for a milestone. 👇


🎬 The setup

Everyone says "my tool is secure." Almost nobody publishes the receipts.

So I did something slightly uncomfortable: I took ATLOCK v5 (not public yet), dropped it into a fresh venv, and attacked it like a stranger would. No GUI clicking, no gentle demos. Raw crypto functions, corrupted files, wrong passwords, forged keys.

python -m venv atenv && source atenv/bin/activate
pip install cryptography argon2-cffi pillow numpy qrcode requests
python ATLOCK_v5.py --selftest
Enter fullscreen mode Exit fullscreen mode

First, some context on what we're even looking at:

ATLOCK v4 (public today) ATLOCK v5 (built, unreleased)
Size 3,074 lines · 23 classes 8,432 lines · 55 classes
File encryption Fernet (AES-128-CBC + HMAC) AES-256-GCM, chunked, key-committing
Password hashing PBKDF2-SHA256, 200k iterations Argon2id (64 MiB floor, 128 MiB for vault)
Sharing files none X25519 + Ed25519 public-key encrypt & sign
Recovery none Shamir secret sharing (3-of-5)
2FA none TOTP + FIDO2 hardware keys
Built-in self-test none 33 checks + a corruption fuzzer

Fun fact: v5 is nearly 3x the code of v4. So the real question was: did the extra code add security, or just extra places to crash?


🧪 Round 1: The built-in self-test

$ python ATLOCK_v5.py --selftest
  [OK] Zip-slip / traversal names rejected
  [OK] Doctored-header KDF ceiling is enforced (no DoS via .atl file)
  [OK] Empty (0-byte) file container round-trips
  [OK] Recovery key split into shares (3 of 5) rebuilds exactly
  [OK] Frozen v1 / v2 / v3.0 containers from ATLOCK 5.0 still open
  ...
----------------------------------------
ALL PASSED   (33/33)
Enter fullscreen mode Exit fullscreen mode

Passing your own tests is the easy part, of course. So I stopped trusting them and wrote my own.


💥 Round 2: Try to corrupt it

The attack: seal a 5 MB random file, then flip one random bit, anywhere in the encrypted blob. Do that 200 times. If even one flip decrypts to wrong data without complaint, that's silent corruption, the nightmare scenario.

bitflip_200: rejected=200  silent_corruption=0  unexpected_crash=0
truncation (5 cut points): rejected=5/5
wrong password: AtlockAuthError
same input sealed twice -> different ciphertext: True
Enter fullscreen mode Exit fullscreen mode

200 out of 200 rejected. Zero silent corruption. Zero crashes.

Then I let the built-in fuzzer loose:

$ python ATLOCK_v5.py --fuzz 300
fuzzed 300 container mutations, 100 garbage shares, 60 junk imports:
no crashes, no silent corruption.
Enter fullscreen mode Exit fullscreen mode

That's 460 hostile inputs, no drama.


⚡ Round 3: Is it slow? (Security that's painful gets switched off)

Operation Result
Seal 5 MB file 0.77 s
Open 5 MB file 0.63 s
Container overhead 134 bytes
Argon2id (64 MiB, t=3) 0.16 s
Argon2id (128 MiB, t=4, vault) 0.45 s
PBKDF2 200k (what v4 uses) 0.05 s

This is the part I find genuinely interesting. v4's PBKDF2 takes ~50 ms. An attacker with a GPU rig loves that. v5's Argon2id makes each guess cost 128 MiB of RAM, which is exactly what GPUs are bad at. Same login delay for you, a far worse deal for them.


🔐 Round 4: Public-key mode (the new toy)

Two identities, Alice and Bob. Alice encrypts and signs a file for Bob.

Scenario Outcome
Bob decrypts ✅ works, signature verified
Alice tries to open Bob's file ❌ "encrypted for a different identity"
Flip one byte in the file ❌ rejected
Edit the file after signing ❌ signature check fails
Shamir: any of the 10 possible 3-of-5 combos ✅ rebuilds the key exactly
Shamir: only 2 shares ❌ refused

Everything behaved. Except...


😬 The thing I'm not happy about

I tested sender pinning: Bob says "I only trust files from this key," then I hand him a file signed by someone else.

>>> atl_pk_decrypt_file(enc, out, "bobpass", expected_sender_pub=wrong_key)
{'signed': True, 'signer_matches': False}
Enter fullscreen mode Exit fullscreen mode

It decrypted anyway. The app shows WARNING: this is NOT the sender key you pasted!, but it does not stop.

Is that a bug? Honestly, it's a design choice, and I can argue both sides:

  • Warn-only: the user stays in control, and you might genuinely want to read a file first and ask the sender later.
  • Hard-fail: if you pinned a key, you already told the app you don't want anyone else. A warning is a polite way to get ignored.

I lean towards hard-fail when a key is pinned. Where do you land? This is my real question for the comments. 👇


🔎 Other things the scan flagged

I ran bandit over both files:

v4 v5
High 0 1
Medium 0 3
  • The 1 "High" is SHA-1, used for the Have I Been Pwned password check. That API requires SHA-1, and only the first 5 characters of the hash ever leave your machine (k-anonymity). Flagged, explained, fine.
  • The 3 "Mediums" are urlopen calls. Worth pinning URL schemes in the final release. Noted.

Also caught a docs bug while reading: the v5 header still says "UI is unchanged from v5". A copy-paste leftover from earlier versions. Embarrassing, tiny, getting fixed.


🧱 What I did NOT test (be honest, right?)

ATLOCK is Windows-first, and my sandbox was Linux. So:

  • ✅ Tested: all crypto, container format, fuzzing, Shamir, public-key, signatures, CLI
  • ❌ Not tested here: the GUI, Windows Hello, DPAPI (falls back to a dev mode off-Windows), BitLocker checks, camera/intruder capture, the startup watchdog, FIDO2 with a real YubiKey

The project's own docs say it plainly too: a pure-Python tool cannot stop an attacker who is already running code as you, and secure-delete can't be guaranteed on SSDs. ATLOCK raises the cost; it doesn't claim magic. I'd rather you hear that from me than discover it later.


🚀 Try it, then come back for v5

ATLOCK v4 is public right now:

👉 Download ATLOCK v4

Here's the deal I'm offering:

  1. Grab v4 and try it for a few days. Lock a file. Break a password on purpose. Tell me what annoys you.
  2. Wait a little. v5 is already finished (everything above came from it), but I'm releasing it when Akhouri Systems crosses 1,000 downloads.
  3. Right now we're at 910. That's 90 downloads away. 🎯

When it lands, you upgrade to Argon2id, AES-256-GCM, hardware-key 2FA and public-key encryption, with your existing v4 habits intact.


💬 Let's argue (nicely)

I'd really like your takes on these:

  1. Pinned sender key doesn't match: warn or hard-fail?
  2. Would you trust a pure-Python security tool with real files, or does that make you nervous? Be brutal.
  3. Argon2id at 128 MiB: too heavy for older laptops, or still not enough?
  4. What would make you switch from your current vault or file locker?

Drop a comment. The best criticism ends up in the v5 changelog with your name on it. 🏷️

Built by Akhouri Anmol Kumar · An Akhouri Systems product

Top comments (16)

Collapse
 
merbayerp profile image
Mustafa ERBAY •

Really nice write-up. I especially appreciate that you included what you did not test — that makes the security claims much more credible.

On sender pinning, I’d strongly prefer hard-fail.

If expected_sender_pub is explicitly provided, that is no longer just informational metadata; it is a security policy. Returning successfully with signer_matches=False means the cryptographic layer detected a policy violation but left enforcement to the caller/UI.

I’d probably make the semantics explicit:

  • no pinned sender → decrypt normally and report signer identity
  • pinned sender + match → decrypt successfully
  • pinned sender + mismatch → fail closed with a dedicated exception
  • if someone really wants “decrypt anyway”, require an explicit override rather than making that the default

That also makes the API safer for future integrations where there may be no human around to notice the warning.

One other thing I’d test before v5: make sure authentication happens before any plaintext becomes observable, especially with chunked AES-GCM. Corrupting random bits is a great test, but deliberately targeting chunk boundaries, lengths, nonces, tags, reordered/duplicated chunks, and the final truncated chunk would be interesting too.

Overall, publishing the failure cases alongside the successful tests is exactly the kind of security engineering write-up I like seeing. 👍

Collapse
 
akhourianmolkumar profile image
Akhouri Anmol Kumar •

Thank you brooo, this is exactly the review I was hoping for. I ran your chunk-level attacks: 91 targeted mutations (length prefixes, tags, reordering, duplication, dropped and truncated final chunks, cross-seal splices) were all rejected, and 82/82 header bit-flips with the hash recomputed were rejected toooo,
Your pinning point turned out to be worse than I'd written: a pinned sender with an unsigned file also decrypted silently. V5 now fails closed with a dedicated exception, and an explicit override is required to decrypt anyway.

You also made me look at plaintext release: the streaming path hands out authenticated chunks before later ones are verified, and one viewing helper left partiaL plaintext on Disk after A failure. Both are fixed....:)

Collapse
 
merbayerp profile image
Mustafa ERBAY •

Hahaha, now this is why I enjoy security reviews. 😄

I came looking for one pinning edge case and somehow we ended up finding an unsigned-sender path, streaming plaintext exposure, and partial plaintext left on disk after failure.

That’s a very productive rabbit hole. 😂

More importantly, huge respect for actually testing the suggestions, publishing what you found, and fixing the behavior instead of defending the original design.

This is exactly how security software should mature. 🔐👍

Thread Thread
 
akhourianmolkumar profile image
Akhouri Anmol Kumar •

I especially published the post and commented on post to trigger you
"Mustafa ERBAY hehehe" because I know you will use your security top tier mind and give me feedbacks, and more.
Bro Can I mention you later when ATLOCK v5 will publicly released in ATLOCK v5 repo your name?

Thread Thread
 
akhourianmolkumar profile image
Akhouri Anmol Kumar •

Also Bro How can i make this post viral too?

Thread Thread
 
akhourianmolkumar profile image
Akhouri Anmol Kumar •

mustafa bro, should I port ATLOCK v5 for linux and mac too?
currently it is only for windows.

Thread Thread
 
akhourianmolkumar profile image
Akhouri Anmol Kumar •

reply?

Collapse
 
xulingfeng profile image
xulingfeng •

You may refer to Jev, which works like an access control system. If identity verification fails, it blocks the operation entirely rather than just showing a warning.

Collapse
 
akhourianmolkumar profile image
Akhouri Anmol Kumar •

I will definitely look at it.

Collapse
 
akhourianmolkumar profile image
Akhouri Anmol Kumar •

bro how can I make this post viral too

Collapse
 
xulingfeng profile image
xulingfeng •

There’s no guaranteed trick to make a post go viral. Virality relies on a mix of topic, headline, timing and luck.
Your security suite project is interesting. Try writing a hands‑on article about breaking your own ATLOCK, similar to this post. Stories about finding flaws and fixing them always attract developers. But don’t chase virality as your main goal. Focus on telling a genuine technical story first.

Thread Thread
 
akhourianmolkumar profile image
Akhouri Anmol Kumar •

yeah, that's the point.
Mustafa ERBAY just helped me a lot.
due to him I fixed one flaw in ATLOCK v5.

Thread Thread
 
xulingfeng profile image
xulingfeng •

Great to hear! External feedback is priceless for tightening up security tools 🔐

Collapse
 
koda2026 profile image
Harun - solo dev •

@akhourianmolkumar Bro, this is the spirit of true engineering.

"I tried to break it... it fought back." That is the best compliment a security tool can receive. If it doesn’t fight back, it’s useless.

Finding "1 thing you’re not happy about" is actually a win. Most people hide those flaws until they explode in production. You surfaced it now, while you can fix it.

KODA and ATLOCK are siblings in chaos. I’m shipping fast and fixing bugs in hours; you’re stress-testing boundaries and finding cracks. We are covering the full spectrum of HYNAWEB: Velocity + Resilience.

Drop the link when you patch that flaw. I’ll be first in line to test it against my Worker’s injection defenses. Let’s see if KODA’s 1µs regex filter can catch what ATLOCK misses. 😂️🐯

Collapse
 
akhourianmolkumar profile image
Akhouri Anmol Kumar •

KODA & ATLOCK
2 greatest product ever made by 12-13

Collapse
 
akhourianmolkumar profile image
Akhouri Anmol Kumar •

Mustafa ERBAY hehehe