mirror of
https://github.com/github/codeql.git
synced 2026-05-03 20:58:03 +02:00
Merge pull request #319 from raulgarciamsft/users/raulga/c6277
C++ : NULL application name with an unquoted path in call to CreateProcess
This commit is contained in:
11
cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.cpp
Normal file
11
cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
STARTUPINFOW si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
// ...
|
||||
|
||||
CreateProcessW( // BUG
|
||||
NULL, // lpApplicationName
|
||||
(LPWSTR)L"C:\\Program Files\\MyApp", // lpCommandLine
|
||||
NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
|
||||
|
||||
// ...
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>This query indicates that there is a call to a function of the <code>CreateProcess*</code> family of functions, which introduces a security vulnerability.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>Do not use <code>NULL</code> for the <code>lpApplicationName</code> argument to the <code>CreateProcess*</code> function.</p>
|
||||
<p>If you pass <code>NULL</code> for <code>lpApplicationName</code>, use quotation marks around the executable path in <code>lpCommandLine</code>.</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>In the following example, <code>CreateProcessW</code> is called with a <code>NULL</code> value for <code>lpApplicationName</code>,
|
||||
and the value for <code>lpCommandLine</code> that represent the application path is not quoted and has spaces in it.</p>
|
||||
<p>If an attacker has access to the file system, they can elevate privileges by creating a file such as <code>C:\Program.exe</code> that will be executed instead of the intended application.</p>
|
||||
<sample src="UnsafeCreateProcessCall.cpp" />
|
||||
|
||||
<p>To fix this issue, specify a valid string for <code>lpApplicationName</code>, or quote the path for <code>lpCommandLine</code>. For example:</p>
|
||||
<p><code>(LPWSTR)L"\"C:\\Program Files\\MyApp\"", // lpCommandLine</code></p>
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
<a href="https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessa">CreateProcessA function (Microsoft documentation).</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessw">CreateProcessW function (Microsoft documentation).</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessasusera">CreateProcessAsUserA function (Microsoft documentation).</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessasuserw">CreateProcessAsUserW function (Microsoft documentation).</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createprocesswithlogonw">CreateProcessWithLogonW function (Microsoft documentation).</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createprocesswithtokenw">CreateProcessWithTokenW function (Microsoft documentation).</a>
|
||||
</li>
|
||||
</references>
|
||||
|
||||
</qhelp>
|
||||
130
cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql
Normal file
130
cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql
Normal file
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* @name NULL application name with an unquoted path in call to CreateProcess
|
||||
* @description Calling a function of the CreateProcess* family of functions, where the path contains spaces, introduces a security vulnerability.
|
||||
* @id cpp/unsafe-create-process-call
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
* @precision medium
|
||||
* @msrc.severity important
|
||||
* @tags security
|
||||
* external/cwe/cwe-428
|
||||
* external/microsoft/C6277
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.DataFlow
|
||||
import semmle.code.cpp.dataflow.DataFlow2
|
||||
|
||||
predicate isCreateProcessFunction(FunctionCall call, int applicationNameIndex, int commandLineIndex) {
|
||||
(
|
||||
call.getTarget().hasGlobalName("CreateProcessA")
|
||||
and applicationNameIndex = 0
|
||||
and commandLineIndex = 1
|
||||
) or (
|
||||
call.getTarget().hasGlobalName("CreateProcessW")
|
||||
and applicationNameIndex = 0
|
||||
and commandLineIndex = 1
|
||||
) or (
|
||||
call.getTarget().hasGlobalName("CreateProcessWithTokenW")
|
||||
and applicationNameIndex = 2
|
||||
and commandLineIndex = 3
|
||||
) or (
|
||||
call.getTarget().hasGlobalName("CreateProcessWithLogonW")
|
||||
and applicationNameIndex = 4
|
||||
and commandLineIndex = 5
|
||||
) or (
|
||||
call.getTarget().hasGlobalName("CreateProcessAsUserA")
|
||||
and applicationNameIndex = 1
|
||||
and commandLineIndex = 2
|
||||
) or (
|
||||
call.getTarget().hasGlobalName("CreateProcessAsUserW")
|
||||
and applicationNameIndex = 1
|
||||
and commandLineIndex = 2
|
||||
)
|
||||
}
|
||||
/**
|
||||
* A function call to CreateProcess (either wide-char or single byte string versions)
|
||||
*/
|
||||
class CreateProcessFunctionCall extends FunctionCall {
|
||||
CreateProcessFunctionCall() {
|
||||
isCreateProcessFunction( this, _, _)
|
||||
}
|
||||
|
||||
int getApplicationNameArgumentId() {
|
||||
isCreateProcessFunction( this, result, _)
|
||||
}
|
||||
|
||||
int getCommandLineArgumentId() {
|
||||
isCreateProcessFunction( this, _, result)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dataflow that detects a call to CreateProcess with a NULL value for lpApplicationName argument
|
||||
*/
|
||||
class NullAppNameCreateProcessFunctionConfiguration extends DataFlow::Configuration {
|
||||
NullAppNameCreateProcessFunctionConfiguration() {
|
||||
this = "NullAppNameCreateProcessFunctionConfiguration"
|
||||
}
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
nullValue(source.asExpr())
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(
|
||||
CreateProcessFunctionCall call, Expr val |
|
||||
val = sink.asExpr() |
|
||||
val = call.getArgument(call.getApplicationNameArgumentId())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dataflow that detects a call to CreateProcess with an unquoted commandLine argument
|
||||
*/
|
||||
class QuotedCommandInCreateProcessFunctionConfiguration extends DataFlow2::Configuration {
|
||||
QuotedCommandInCreateProcessFunctionConfiguration() {
|
||||
this = "QuotedCommandInCreateProcessFunctionConfiguration"
|
||||
}
|
||||
|
||||
override predicate isSource(DataFlow2::Node source) {
|
||||
exists( string s |
|
||||
s = source.asExpr().getValue().toString()
|
||||
and
|
||||
not isQuotedOrNoSpaceApplicationNameOnCmd(s)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow2::Node sink) {
|
||||
exists(
|
||||
CreateProcessFunctionCall call, Expr val |
|
||||
val = sink.asExpr() |
|
||||
val = call.getArgument(call.getCommandLineArgumentId())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
bindingset[s]
|
||||
predicate isQuotedOrNoSpaceApplicationNameOnCmd(string s){
|
||||
s.regexpMatch("\"([^\"])*\"(\\s|.)*") // The first element (path) is quoted
|
||||
or
|
||||
s.regexpMatch("[^\\s]+") // There are no spaces in the string
|
||||
}
|
||||
|
||||
from CreateProcessFunctionCall call, string msg1, string msg2
|
||||
where
|
||||
exists( Expr source, Expr appName,
|
||||
NullAppNameCreateProcessFunctionConfiguration nullAppConfig |
|
||||
appName = call.getArgument(call.getApplicationNameArgumentId())
|
||||
and nullAppConfig.hasFlow(DataFlow2::exprNode(source), DataFlow2::exprNode(appName))
|
||||
and msg1 = call.toString() + " with lpApplicationName == NULL (" + appName + ")"
|
||||
)
|
||||
and
|
||||
exists( Expr source, Expr cmd,
|
||||
QuotedCommandInCreateProcessFunctionConfiguration quotedConfig |
|
||||
cmd = call.getArgument(call.getCommandLineArgumentId())
|
||||
and quotedConfig.hasFlow(DataFlow2::exprNode(source), DataFlow2::exprNode(cmd))
|
||||
and msg2 = " and with an unquoted lpCommandLine (" + cmd + ") introduces a security vulnerability if the path contains spaces."
|
||||
)
|
||||
select call, msg1 + " " + msg2
|
||||
@@ -0,0 +1,430 @@
|
||||
// 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;
|
||||
|
||||
// CreatePorcessA
|
||||
CreateProcessA( //BUG
|
||||
NULL,
|
||||
(char*)"C:\\Program Files\\MyApp",
|
||||
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
|
||||
|
||||
// CreatePorcessW
|
||||
CreateProcessW( //BUG
|
||||
NULL,
|
||||
(wchar_t*)L"C:\\Program Files\\MyApp",
|
||||
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
|
||||
|
||||
// CreatePorcess
|
||||
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);
|
||||
|
||||
// CreatePorcess 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;
|
||||
|
||||
// CreatePorcessA
|
||||
CreateProcessA(
|
||||
NULL,
|
||||
(char*)"\"C:\\Program Files\\MyApp\"",
|
||||
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
|
||||
|
||||
// CreatePorcessW
|
||||
CreateProcessW(
|
||||
NULL,
|
||||
(wchar_t*)L"\"C:\\Program Files\\MyApp\"",
|
||||
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
|
||||
|
||||
// CreatePorcess
|
||||
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);
|
||||
|
||||
// CreatePorcess 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";
|
||||
|
||||
// CreatePorcessA
|
||||
CreateProcessA(
|
||||
(char*)"MyApp.exe",
|
||||
(char*)"C:\\Program Files\\MyApp",
|
||||
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
|
||||
|
||||
// CreatePorcessW
|
||||
CreateProcessW(
|
||||
(wchar_t*)L"MyApp.exe",
|
||||
(wchar_t*)L"C:\\Program Files\\MyApp",
|
||||
NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL);
|
||||
|
||||
// CreatePorcess
|
||||
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);
|
||||
|
||||
// CreatePorcess 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);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
| UnsafeCreateProcessCall.cpp:103:5:103:18 | call to CreateProcessA | call to CreateProcessA with lpApplicationName == NULL (0) and with an unquoted lpCommandLine (C:\\Program Files\\MyApp) introduces a security vulnerability if the path contains spaces. |
|
||||
| UnsafeCreateProcessCall.cpp:109:5:109:18 | call to CreateProcessW | call to CreateProcessW with lpApplicationName == NULL (0) and with an unquoted lpCommandLine (C:\\Program Files\\MyApp) introduces a security vulnerability if the path contains spaces. |
|
||||
| UnsafeCreateProcessCall.cpp:115:5:115:17 | call to CreateProcessW | call to CreateProcessW with lpApplicationName == NULL (0) and with an unquoted lpCommandLine (C:\\Program Files\\MyApp) introduces a security vulnerability if the path contains spaces. |
|
||||
| UnsafeCreateProcessCall.cpp:121:5:121:17 | call to CreateProcessW | call to CreateProcessW with lpApplicationName == NULL (0) and with an unquoted lpCommandLine (lpCommandLine) introduces a security vulnerability if the path contains spaces. |
|
||||
| UnsafeCreateProcessCall.cpp:127:5:127:27 | call to CreateProcessWithTokenW | call to CreateProcessWithTokenW with lpApplicationName == NULL (0) and with an unquoted lpCommandLine (C:\\Program Files\\MyApp) introduces a security vulnerability if the path contains spaces. |
|
||||
| UnsafeCreateProcessCall.cpp:135:5:135:27 | call to CreateProcessWithLogonW | call to CreateProcessWithLogonW with lpApplicationName == NULL (0) and with an unquoted lpCommandLine (C:\\Program Files\\MyApp) introduces a security vulnerability if the path contains spaces. |
|
||||
| UnsafeCreateProcessCall.cpp:145:5:145:24 | call to CreateProcessAsUserA | call to CreateProcessAsUserA with lpApplicationName == NULL (0) and with an unquoted lpCommandLine (C:\\Program Files\\MyApp) introduces a security vulnerability if the path contains spaces. |
|
||||
| UnsafeCreateProcessCall.cpp:152:5:152:24 | call to CreateProcessAsUserW | call to CreateProcessAsUserW with lpApplicationName == NULL (0) and with an unquoted lpCommandLine (C:\\Program Files\\MyApp) introduces a security vulnerability if the path contains spaces. |
|
||||
| UnsafeCreateProcessCall.cpp:159:5:159:23 | call to CreateProcessAsUserW | call to CreateProcessAsUserW with lpApplicationName == NULL (0) and with an unquoted lpCommandLine (C:\\Program Files\\MyApp) introduces a security vulnerability if the path contains spaces. |
|
||||
| UnsafeCreateProcessCall.cpp:167:5:167:17 | call to CreateProcessW | call to CreateProcessW with lpApplicationName == NULL (lpApplicationName) and with an unquoted lpCommandLine (C:\\Program\tFiles\\MyApp) introduces a security vulnerability if the path contains spaces. |
|
||||
| UnsafeCreateProcessCall.cpp:176:5:176:17 | call to CreateProcessW | call to CreateProcessW with lpApplicationName == NULL (0) and with an unquoted lpCommandLine (lpCommandLine) introduces a security vulnerability if the path contains spaces. |
|
||||
| UnsafeCreateProcessCall.cpp:209:5:209:27 | call to CreateProcessWithTokenW | call to CreateProcessWithTokenW with lpApplicationName == NULL (lpApplicationName) and with an unquoted lpCommandLine (C:\\Program Files\\MyApp) introduces a security vulnerability if the path contains spaces. |
|
||||
| UnsafeCreateProcessCall.cpp:258:5:258:27 | call to CreateProcessWithLogonW | call to CreateProcessWithLogonW with lpApplicationName == NULL (lpApplicationName) and with an unquoted lpCommandLine (C:\\Program Files\\MyApp) introduces a security vulnerability if the path contains spaces. |
|
||||
@@ -0,0 +1 @@
|
||||
Security/CWE/CWE-428/UnsafeCreateProcessCall.ql
|
||||
Reference in New Issue
Block a user