K. Nielson
K. Nielson

Reputation: 191

How does the code example in the python os module documentation create a security hole?

The documentation for the os module makes the following assertion:


Note

Using access() to check if a user is authorized to e.g. open a file before actually doing so using open() creates a security hole, because the user might exploit the short time interval between checking and opening the file to manipulate it. It’s preferable to use EAFP techniques. For example:

if os.access("myfile", os.R_OK):
    with open("myfile") as fp:
    return fp.read()
return "some default data"`

is better written as:

try:
    fp = open("myfile")
except PermissionError:
    return "some default data"
else:
    with fp:
        return fp.read()

I don't understand how a user "might exploit" the interval. If open was going to raise an exception, I'm not sure how os.access would prevent that exception from being raised. Likewise, if the user manipulate the file somehow, why not perform the file manipulation prior to the EAFP version's open command?

I do understand that the second version may be more robust, since os.access may fail to correctly recognize a condition that could raise a PermissionError, but I don't see how the LBYL version is less secure. Can someone explain this?

Upvotes: 8

Views: 352

Answers (1)

user2357112
user2357112

Reputation: 281586

While the access-using code is unsafe, the second code snippet doesn't solve the security issues. These docs should be changed.

The purpose of os.access is to test whether the real user id has permission to access a file when the real and effective user ids are different. The danger with the os.access snippet is that the user could place a file access returns True for in the location being tested, then swap it out for a file access would have returned False for, bypassing the check. Since open uses the effective user id, the open call can still work, bypassing the access check.

The second snippet doesn't solve this problem. Now the user doesn't even need to go through the switcheroo. No part of the second snippet checks the real user id.

Upvotes: 8

Related Questions