CWE-283, Unverified Ownership, is a product that does not properly verify that a critical resource is owned by the proper entity.
If your code sends secrets over a socket, reads from a device, or loads a file because of its path alone, this applies.
How it happens
The program assumes that the thing at a known path is the thing it expects. An attacker who can create or replace that object first gets the program to talk to them.
MITRE's two examples:
- CVE-2001-0178 (Gold): a program does not verify the owner of a UNIX socket that is used for sending a password.
- CVE-2004-2012 (Gold): the owner of a special device is not checked, allowing root.
What an attacker gains
MITRE lists gaining privileges or assuming identity, and unauthorized access to system resources. In the socket case, the attacker receives a password meant for someone else.
How to find it
- Find places where code connects to a socket or opens a device by path.
- Check whether the code inspects the owner and mode before use.
- Review whether the parent directory is writable by others.
How to fix it
Verify before you trust. Check the owner and permissions of the object, and use a location that only a trusted account can write to. Where possible, use the file descriptor you already hold instead of re-resolving the path.
import os, stat
st = os.stat("/run/app/app.sock")
if st.st_uid != os.geteuid() or (st.st_mode & stat.S_IWOTH):
raise RuntimeError("socket owner or mode is not trusted")
Quick check
Is checking the owner enough if the directory is world-writable?
Not on its own. An attacker could swap the object between your check and your use, so place sockets in directories only trusted users can write to.
Sources
- MITRE CWE-283: https://cwe.mitre.org/data/definitions/283.html
- Safeguard Gold entry: https://gold.safeguard.sh/cwe/CWE-283