DEV Community

Akhouri Anmol Kumar
Akhouri Anmol Kumar

Posted on

Windows 'file locking' apps are mostly theater. Here's how I made files actually unreadable.

Most "lock this file" apps don't lock anything

Go look at almost any Windows file-lock utility. Under the hood, most of them do one of two things:

Rename/hide the file and hope nobody turns on "show hidden files"
Wrap it in their own password prompt — while the actual file sits on disk, fully readable by literally any other program on the machine

Neither of those is locking. That's a UI illusion sitting on top of a completely open file.

When I built File Guard for ATLOCK, I wanted the lock to be real — enforced by Windows itself, not by my app's goodwill.

The actual fix: Windows ACLs, not app-level gatekeeping

Windows already has a real permission system: NTFS Access Control Lists (ACLs). Every file has a security descriptor that says exactly who can read, write, or execute it. Normally your own user account has full rights to everything you own.

File Guard's trick is simple to describe and annoying to get right: strip the read/write ACL entries for the file's owner, and hand file-guard the only key back to restoring them.

Once that's done, it doesn't matter if someone:

Opens the file in Notepad
Copies it to another folder
Tries to read it from a different app entirely

Windows itself refuses, before my app is even in the picture.

Conceptually, using pywin32, it looks something like this:

python
import win32security
import ntsecuritycon as con

def strip_read_access(filepath, user_sid):
sd = win32security.GetFileSecurity(
filepath, win32security.DACL_SECURITY_INFORMATION
)
dacl = sd.GetSecurityDescriptorDacl()

# Deny read/write explicitly for the owning user
dacl.AddAccessDeniedAce(
    win32security.ACL_REVISION,
    con.FILE_GENERIC_READ | con.FILE_GENERIC_WRITE,
    user_sid
)

sd.SetSecurityDescriptorDacl(1, dacl, 0)
win32security.SetFileSecurity(
    filepath, win32security.DACL_SECURITY_INFORMATION, sd
)
Enter fullscreen mode Exit fullscreen mode

Unlocking reverses it — pull the deny-ACE back out once the correct password/PIN is verified. The point isn't the exact code, it's the shift in where the enforcement lives: not in my Python process, but in the OS security subsystem that every process on the machine has to go through.

The second problem: catching intruders without freezing the UI

File Guard tells you that someone was blocked. Intruder Ops tells you who.

The naive version — call cv2.VideoCapture(0), grab a frame, save it — works fine as a demo and then completely locks up your UI thread the first time a webcam takes 400ms to initialize on a cold start. Tkinter (which the whole ATLOCK UI runs on) is single-threaded for rendering, so any blocking call on the main thread means a frozen window during exactly the moment you need the app to look completely normal to whoever's poking at it.

The fix was moving capture into a background thread with a small state machine:

python
import threading
import cv2

def capture_intruder_photo(save_path, on_done):
def worker():
cam = cv2.VideoCapture(0)
ok, frame = cam.read()
if ok:
cv2.imwrite(save_path, frame)
cam.release()
on_done(ok) # callback marshals back to the UI thread

threading.Thread(target=worker, daemon=True).start()
Enter fullscreen mode Exit fullscreen mode

Wrong password #1 fires a photo thread. Wrong attempt #3/#4 fires a 10-second video thread plus an alarm sound, all without the lock screen so much as flickering. The attacker sees a password box. What they don't see is a camera light and a background thread quietly building a case file.

Why this matters beyond one app

The general lesson: if you're building anything that claims to "secure" a file, ask where the enforcement actually lives. App-level password prompts are convenience, not security — they stop your little brother, not anyone who knows how to open a terminal. Real enforcement has to live somewhere the attacker can't route around from outside your process: the OS permission layer, the filesystem, the kernel — not a tkinter.Entry widget.

That's the whole design philosophy behind ATLOCK v4 — Lockdown, File Guard, Vault, and Intruder Ops are all built around "assume the attacker is already looking at your screen, what's the layer they can't talk their way past."

Try it

ATLOCK v4 is free. Built solo in Python — customtkinter for UI, OpenCV for capture, pywin32 for the ACL work, cryptography for the vault encryption.
👇
🔗 https://github.com/Akhouri-Anmol-Kumar/ATLOCK 👈
👆
Would genuinely love feedback from anyone who's done lower-level Windows security work — I'm certain there are edge cases in the ACL handling I haven't hit yet. Tell me where it breaks.

— Akhouri Anmol Kumar, Akhouri Systems

Top comments (0)