Files
codeql/cpp/ql/test/query-tests/Security/CWE/CWE-428/UnsafeCreateProcessCall.cpp
Geoffrey White 4908eaf5ec C++: Typos.
2022-02-22 14:33:11 +00:00

431 lines
12 KiB
C++

// semmle-extractor-options: --microsoft
#define NULL 0
#define FALSE 0
#define LOGON_WITH_PROFILE 0x00000001
int
CreateProcessA(
const char* lpApplicationName,
char* lpCommandLine,
void* lpProcessAttributes,
void* lpThreadAttributes,
int bInheritHandles,
unsigned long dwCreationFlags,
void* lpEnvironment,
const char* lpCurrentDirectory,
void* lpStartupInfo,
void* lpProcessInformation
);
int
CreateProcessW(
const wchar_t* lpApplicationName,
wchar_t* lpCommandLine,
void* lpProcessAttributes,
void* lpThreadAttributes,
int bInheritHandles,
unsigned long dwCreationFlags,
void* lpEnvironment,
const wchar_t* lpCurrentDirectory,
void* lpStartupInfo,
void* lpProcessInformation
);
#define CreateProcess CreateProcessW
int
CreateProcessWithTokenW(
void* hToken,
unsigned long dwLogonFlags,
const wchar_t* lpApplicationName,
wchar_t* lpCommandLine,
unsigned long dwCreationFlags,
void* lpEnvironment,
const wchar_t* lpCurrentDirectory,
void* lpStartupInfo,
void* lpProcessInformation
);
int
CreateProcessWithLogonW(
const wchar_t* lpUsername,
const wchar_t* lpDomain,
const wchar_t* lpPassword,
unsigned long dwLogonFlags,
const wchar_t* lpApplicationName,
wchar_t* lpCommandLine,
unsigned long dwCreationFlags,
void* lpEnvironment,
const wchar_t* lpCurrentDirectory,
void* lpStartupInfo,
void* lpProcessInformation
);
int
CreateProcessAsUserA(
void* hToken,
const char* lpApplicationName,
char* lpCommandLine,
void* lpProcessAttributes,
void* lpThreadAttributes,
int bInheritHandles,
unsigned long dwCreationFlags,
void* lpEnvironment,
const char* lpCurrentDirectory,
void* lpStartupInfo,
void* lpProcessInformation
);
int
CreateProcessAsUserW(
void* hToken,
const wchar_t* lpApplicationName,
wchar_t* lpCommandLine,
void* lpProcessAttributes,
void* lpThreadAttributes,
int bInheritHandles,
unsigned long dwCreationFlags,
void* lpEnvironment,
const wchar_t* lpCurrentDirectory,
void* lpStartupInfo,
void* lpProcessInformation
);
#define CreateProcessAsUser CreateProcessAsUserW
void positiveTestCases()
{
const wchar_t* lpCommandLine = (const wchar_t*)L"C:\\Program Files\\MyApp";
void* h = 0;
wchar_t* lpApplicationName = NULL;
// CreateProcessA
CreateProcessA( //BUG
NULL,
(char*)"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcessW
CreateProcessW( //BUG
NULL,
(wchar_t*)L"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcess
CreateProcess( //BUG
NULL,
(wchar_t*)L"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// lpCommandLine as hardcoded variable
CreateProcess( //BUG
NULL,
(wchar_t*)lpCommandLine,
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcessWithTokenW
CreateProcessWithTokenW( //BUG
h,
LOGON_WITH_PROFILE,
NULL,
(wchar_t*)L"C:\\Program Files\\MyApp",
0, NULL, NULL, NULL, NULL);
// CreateProcessWithLogonW
CreateProcessWithLogonW( //BUG
(const wchar_t*)L"UserName",
(const wchar_t*)L"CONTOSO",
(const wchar_t*)L"<fake_password!>",
LOGON_WITH_PROFILE,
NULL,
(wchar_t*)L"C:\\Program Files\\MyApp",
0, NULL, NULL, NULL, NULL);
// CreateProcessAsUserA
CreateProcessAsUserA( //BUG
h,
NULL,
(char*)"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcessAsUserW
CreateProcessAsUserW( //BUG
h,
NULL,
(wchar_t*)L"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcessAsUser
CreateProcessAsUser( //BUG
h,
NULL,
(wchar_t*)L"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcess with a hardcoded variable for application Name (NULL)
// Variation: tab instead of space
CreateProcess( //BUG
lpApplicationName,
(wchar_t*)L"C:\\Program\tFiles\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
}
void PositiveTestCasesWithCmdLineParameter(wchar_t* lpCommandLine)
{
// lpCommandLine as variable
CreateProcess( //BUG - Depends on the caller
NULL,
lpCommandLine,
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
}
void PositiveTestCasesWithCmdLineParameter_caller()
{
PositiveTestCasesWithCmdLineParameter((wchar_t*)L"C:\\Program Files\\MyApp");
}
// NOTE: This function will not be flagged as having a bug by this rule.
// but as it is, the function can still be misused
void FalseNegativeTestCasesWithCmdLineParameter(wchar_t* lpCommandLine)
{
// lpCommandLine as variable
CreateProcess( //Depends on the caller, this time the caller will quote
NULL,
lpCommandLine,
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
}
void FalseNegativeTestCasesWithCmdLineParameter_caller()
{
// No bug - escaped command line
// But compare with "PositiveTestCasesWithCmdLineParameter"
FalseNegativeTestCasesWithCmdLineParameter((wchar_t*)L"\"C:\\Program Files\\MyApp\"");
}
void PositiveTestCasesWithAppNameParameter(wchar_t* lpApplicationName)
{
void* h = 0;
CreateProcessWithTokenW( //BUG - Depends on the caller. In this case the caller sends NULL
h,
LOGON_WITH_PROFILE,
lpApplicationName,
(wchar_t*)L"C:\\Program Files\\MyApp",
0, NULL, NULL, NULL, NULL);
}
void PositiveTestCasesWithAppNameParameter_caller()
{
PositiveTestCasesWithAppNameParameter(NULL);
}
// NOTE: This function will not be flagged as having a bug by this rule.
// but as it is, the function can still be misused
void FalseNegativeTestCasesWithAppNameParameter(wchar_t* lpApplicationName)
{
void* h = 0;
CreateProcessWithTokenW( // Depends on the caller. In this case the caller sends an ApplicatioName
h,
LOGON_WITH_PROFILE,
lpApplicationName,
(wchar_t*)L"C:\\Program Files\\MyApp",
0, NULL, NULL, NULL, NULL);
}
void FalseNegativeTestCasesWithAppNameParameter_caller()
{
// No bug - escaped command line
// But compare with "PositiveTestCasesWithAppNameParameter"
FalseNegativeTestCasesWithAppNameParameter((wchar_t*)L"MyApp.exe");
}
int MayReturnFalse()
{
// return ((rand() % 2) == 0);
return true;
}
void TestCaseProbablyBug()
{
const wchar_t* lpApplicationName = NULL;
if (!MayReturnFalse())
{
lpApplicationName = (const wchar_t*)L"app.exe";
}
CreateProcessWithLogonW( // BUG (Probably - depends on a condition that may be false)
(const wchar_t*)L"UserName",
(const wchar_t*)L"CONTOSO",
(const wchar_t*)L"<fake_password!>",
LOGON_WITH_PROFILE,
(wchar_t*)lpApplicationName,
(wchar_t*)L"C:\\Program Files\\MyApp",
0, NULL, NULL, NULL, NULL);
if (lpApplicationName)
{
delete[] lpApplicationName;
}
}
void negativeTestCases_quotedCommandLine()
{
const wchar_t* lpCommandLine = (const wchar_t*)L"\"C:\\Program Files\\MyApp\" with additional params";
void* h = 0;
wchar_t* lpApplicationName = NULL;
// CreateProcessA
CreateProcessA(
NULL,
(char*)"\"C:\\Program Files\\MyApp\"",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcessW
CreateProcessW(
NULL,
(wchar_t*)L"\"C:\\Program Files\\MyApp\"",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcess
CreateProcess(
NULL,
(wchar_t*)L"\"C:\\Program Files\\MyApp\"",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// lpCommandLine as hardcoded variable
CreateProcess(
NULL,
(wchar_t*)lpCommandLine,
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcessWithTokenW
CreateProcessWithTokenW(
h,
LOGON_WITH_PROFILE,
NULL,
(wchar_t*)L"\"C:\\Program Files\\MyApp\"",
0, NULL, NULL, NULL, NULL);
// CreateProcessWithLogonW
CreateProcessWithLogonW(
(const wchar_t*)L"UserName",
(const wchar_t*)L"CONTOSO",
(const wchar_t*)L"<fake_password!>",
LOGON_WITH_PROFILE,
NULL,
(wchar_t*)L"\"C:\\Program Files\\MyApp\"",
0, NULL, NULL, NULL, NULL);
// CreateProcessAsUserA
CreateProcessAsUserA(
h,
NULL,
(char*)"\"C:\\Program Files\\MyApp\"",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcessAsUserW
CreateProcessAsUserW(
h,
NULL,
(wchar_t*)L"\"C:\\Program Files\\MyApp\"",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcessAsUser
CreateProcessAsUser(
h,
NULL,
(wchar_t*)L"\"C:\\Program Files\\MyApp\"",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcess with a hardcoded variable for application Name (NULL)
CreateProcess(
lpApplicationName,
(wchar_t*)L"\"C:\\Program Files\\MyApp\"",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// Null AppName, but lpComamndLine has no spaces/tabs
CreateProcessA(
NULL,
(char*)"C:\\MyFolder\\MyApp.exe",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
}
void negativeTestCases_AppNameSet()
{
const wchar_t* lpCommandLine = (const wchar_t*)L"C:\\Program Files\\MyApp";
void* h = 0;
const wchar_t* lpApplicationName = (const wchar_t*)L"MyApp.exe";
// CreateProcessA
CreateProcessA(
(char*)"MyApp.exe",
(char*)"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcessW
CreateProcessW(
(wchar_t*)L"MyApp.exe",
(wchar_t*)L"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcess
CreateProcess(
(wchar_t*)L"MyApp.exe",
(wchar_t*)L"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// lpCommandLine as hardcoded variable
CreateProcess(
(wchar_t*)L"MyApp.exe",
(wchar_t*)lpCommandLine,
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcessWithTokenW
CreateProcessWithTokenW(
h,
LOGON_WITH_PROFILE,
(wchar_t*)L"MyApp.exe",
(wchar_t*)L"C:\\Program Files\\MyApp",
0, NULL, NULL, NULL, NULL);
// CreateProcessWithLogonW
CreateProcessWithLogonW(
(const wchar_t*)L"UserName",
(const wchar_t*)L"CONTOSO",
(const wchar_t*)L"<fake_password!>",
LOGON_WITH_PROFILE,
(wchar_t*)L"MyApp.exe",
(wchar_t*)L"C:\\Program Files\\MyApp",
0, NULL, NULL, NULL, NULL);
// CreateProcessAsUserA
CreateProcessAsUserA(
h,
(char*)"MyApp.exe",
(char*)"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcessAsUserW
CreateProcessAsUserW(
h,
(wchar_t*)L"MyApp.exe",
(wchar_t*)L"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcessAsUser
CreateProcessAsUser(
h,
(wchar_t*)L"MyApp.exe",
(wchar_t*)L"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
// CreateProcess with a hardcoded variable for application Name (NULL)
CreateProcess(
(wchar_t*)lpApplicationName,
(wchar_t*)L"C:\\Program Files\\MyApp",
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
}