mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-135815: skip netrc
security checks if os.getuid
is missing (#135816)
This commit is contained in:
parent
e7295a89b8
commit
b57b619e34
4 changed files with 30 additions and 18 deletions
|
@ -24,12 +24,14 @@ the Unix :program:`ftp` program and other FTP clients.
|
|||
a :exc:`FileNotFoundError` exception will be raised.
|
||||
Parse errors will raise :exc:`NetrcParseError` with diagnostic
|
||||
information including the file name, line number, and terminating token.
|
||||
|
||||
If no argument is specified on a POSIX system, the presence of passwords in
|
||||
the :file:`.netrc` file will raise a :exc:`NetrcParseError` if the file
|
||||
ownership or permissions are insecure (owned by a user other than the user
|
||||
running the process, or accessible for read or write by any other user).
|
||||
This implements security behavior equivalent to that of ftp and other
|
||||
programs that use :file:`.netrc`.
|
||||
programs that use :file:`.netrc`. Such security checks are not available
|
||||
on platforms that do not support :func:`os.getuid`.
|
||||
|
||||
.. versionchanged:: 3.4 Added the POSIX permission check.
|
||||
|
||||
|
|
29
Lib/netrc.py
29
Lib/netrc.py
|
@ -7,6 +7,19 @@ import os, stat
|
|||
__all__ = ["netrc", "NetrcParseError"]
|
||||
|
||||
|
||||
def _can_security_check():
|
||||
# On WASI, getuid() is indicated as a stub but it may also be missing.
|
||||
return os.name == 'posix' and hasattr(os, 'getuid')
|
||||
|
||||
|
||||
def _getpwuid(uid):
|
||||
try:
|
||||
import pwd
|
||||
return pwd.getpwuid(uid)[0]
|
||||
except (ImportError, LookupError):
|
||||
return f'uid {uid}'
|
||||
|
||||
|
||||
class NetrcParseError(Exception):
|
||||
"""Exception raised on syntax errors in the .netrc file."""
|
||||
def __init__(self, msg, filename=None, lineno=None):
|
||||
|
@ -142,18 +155,12 @@ class netrc:
|
|||
self._security_check(fp, default_netrc, self.hosts[entryname][0])
|
||||
|
||||
def _security_check(self, fp, default_netrc, login):
|
||||
if os.name == 'posix' and default_netrc and login != "anonymous":
|
||||
if _can_security_check() and default_netrc and login != "anonymous":
|
||||
prop = os.fstat(fp.fileno())
|
||||
if prop.st_uid != os.getuid():
|
||||
import pwd
|
||||
try:
|
||||
fowner = pwd.getpwuid(prop.st_uid)[0]
|
||||
except KeyError:
|
||||
fowner = 'uid %s' % prop.st_uid
|
||||
try:
|
||||
user = pwd.getpwuid(os.getuid())[0]
|
||||
except KeyError:
|
||||
user = 'uid %s' % os.getuid()
|
||||
current_user_id = os.getuid()
|
||||
if prop.st_uid != current_user_id:
|
||||
fowner = _getpwuid(prop.st_uid)
|
||||
user = _getpwuid(current_user_id)
|
||||
raise NetrcParseError(
|
||||
(f"~/.netrc file owner ({fowner}, {user}) does not match"
|
||||
" current user"))
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
import netrc, os, unittest, sys, textwrap
|
||||
from test import support
|
||||
from test.support import os_helper
|
||||
|
||||
try:
|
||||
import pwd
|
||||
except ImportError:
|
||||
pwd = None
|
||||
|
||||
temp_filename = os_helper.TESTFN
|
||||
|
||||
class NetrcTestCase(unittest.TestCase):
|
||||
|
@ -269,9 +265,14 @@ class NetrcTestCase(unittest.TestCase):
|
|||
machine bar.domain.com login foo password pass
|
||||
""", '#pass')
|
||||
|
||||
@unittest.skipUnless(support.is_wasi, 'WASI only test')
|
||||
def test_security_on_WASI(self):
|
||||
self.assertFalse(netrc._can_security_check())
|
||||
self.assertEqual(netrc._getpwuid(0), 'uid 0')
|
||||
self.assertEqual(netrc._getpwuid(123456), 'uid 123456')
|
||||
|
||||
@unittest.skipUnless(os.name == 'posix', 'POSIX only test')
|
||||
@unittest.skipIf(pwd is None, 'security check requires pwd module')
|
||||
@unittest.skipUnless(hasattr(os, 'getuid'), "os.getuid is required")
|
||||
@os_helper.skip_unless_working_chmod
|
||||
def test_security(self):
|
||||
# This test is incomplete since we are normally not run as root and
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
:mod:`netrc`: skip security checks if :func:`os.getuid` is missing.
|
||||
Patch by Bénédikt Tran.
|
Loading…
Add table
Add a link
Reference in a new issue