You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
winreg.SetValueEx should check the returned value #88150
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=Nonecreated_at=<Date2021-04-30.08:42:01.576>labels= ['3.10', 'type-bug', '3.9', 'OS-windows', '3.11']
title='winreg.SetValueEx should check the returned value'updated_at=<Date2021-05-01.09:48:29.376>user='https://bugs.python.org/r3pwnx'
When the type is set with reg.REG_DWORD, PyLong_AsUnsignedLong(value) will change the value's type, and then memcpy the returned value directly, without any check.
changed the title [-][security]winreg.SetValueEx shoule check the returned value[/-][+][security] winreg.SetValueEx should check the returned value[/+]on Apr 30, 2021
changed the title [-][security]winreg.SetValueEx shoule check the returned value[/-][+][security] winreg.SetValueEx should check the returned value[/+]on Apr 30, 2021
I'm changing this issue to a behavior bug. Many issues have the potential to be exploited as a security vulnerability in some contrived scenario, but the security issue type is for cases that have provably significant security implications, such as privilege escalation, which should be reported using the documented procedure [1]. Registry keys are secured, and modifying system keys requires privileged access, so a bug that sets an incorrect value is not particularly exploitable. Anyone that can set a system value already has full control of the system.
The suggested fix is correct, except the C macro is FALSE, not False. I would simply cast to DWORD instead of unsigned long. Also, the REG_QWORD conversion has the same problem with not checking for an overflow after calling PyLong_AsUnsignedLongLong().
changed the title [-][security] winreg.SetValueEx should check the returned value[/-][+]winreg.SetValueEx should check the returned value[/+]on Apr 30, 2021
changed the title [-][security] winreg.SetValueEx should check the returned value[/-][+]winreg.SetValueEx should check the returned value[/+]on Apr 30, 2021
Activity
r3pwnx commentedon Apr 30, 2021
The library winreg[1] can be used to access registry on windows.
In the source file of "PC/winreg.c",
Py2Regis called firstPy2Regis implemented in the same file:When the type is set with reg.REG_DWORD,
PyLong_AsUnsignedLong(value)will change the value's type, and then memcpy the returned value directly, without any check.In the Objects/longobject.c, as the comment said:
/* Get a C unsigned long int from an int object.
Returns -1 and sets an error condition if overflow occurs. */
If PyLong_AsUnsignedLong return -1, the -1 will be stored in the registry though the error occured
PoC:
try:
print("Set Subkey X: -1337")
reg.SetValueEx(key, 'X', 0, reg.REG_DWORD, -1337)
except Exception as e:
print("Get Subkey: ", reg.QueryValueEx(key, "X")[0])
try:
print("Set Subkey Y: 2**33")
reg.SetValueEx(key, 'Y', 0, reg.REG_DWORD, 2**33)
except Exception as e:
print("Get Subkey: ", reg.QueryValueEx(key, "Y")[0])
The Test Environment
OS: Windows
Python Version: 3.9.0
python winreg_bug.py
Set Subkey X: -1337
Get Subkey: 4294967295
Set Subkey Y: 2**33
Get Subkey: 4294967295
the return value should be checked:
+ if (d == (unsigned long)-1 && PyErr_Occurred())
+ return False;
memcpy(*retDataBuf, &d, sizeof(DWORD));
[1] https://docs.python.org/3.9/library/winreg.html#winreg.SetValueEx
shreyanavigyan commentedon Apr 30, 2021
+1 on my side.
[-][security]winreg.SetValueEx shoule check the returned value[/-][+][security] winreg.SetValueEx should check the returned value[/+][-][security]winreg.SetValueEx shoule check the returned value[/-][+][security] winreg.SetValueEx should check the returned value[/+]eryksun commentedon Apr 30, 2021
I'm changing this issue to a behavior bug. Many issues have the potential to be exploited as a security vulnerability in some contrived scenario, but the security issue type is for cases that have provably significant security implications, such as privilege escalation, which should be reported using the documented procedure [1]. Registry keys are secured, and modifying system keys requires privileged access, so a bug that sets an incorrect value is not particularly exploitable. Anyone that can set a system value already has full control of the system.
The suggested fix is correct, except the C macro is
FALSE, notFalse. I would simply cast to DWORD instead ofunsigned long. Also, the REG_QWORD conversion has the same problem with not checking for an overflow after calling PyLong_AsUnsignedLongLong().---
[1] https://www.python.org/dev/security
[-][security] winreg.SetValueEx should check the returned value[/-][+]winreg.SetValueEx should check the returned value[/+][-][security] winreg.SetValueEx should check the returned value[/-][+]winreg.SetValueEx should check the returned value[/+]shreyanavigyan commentedon Apr 30, 2021
I have a patch ready for this issue. Should I convert it to a PR?
shreyanavigyan commentedon May 1, 2021
I'm attaching a PR to fix this issue.