Skip to content

Commit

Permalink
HPCC-32999 Address review comments
Browse files Browse the repository at this point in the history
- Rename sanitize function to better indicate purpose
- Move function to jstring
- Correct unsigned vs signed comparison in for loop

Signed-off-by: Terrence Asselin <[email protected]>
  • Loading branch information
asselitx committed Dec 11, 2024
1 parent 5dc0da6 commit 580bfae
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 29 deletions.
30 changes: 1 addition & 29 deletions esp/services/ws_workunits/ws_workunitsHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4326,34 +4326,6 @@ void readWUComponentLogOptionsReq(T* logReq, WUComponentLogOptions& options)
}
}

// For preventing command injection, sanitize the argument to be passed to the system command.
// - Quote the entire argument with single quotes to prevent interpretation of shell metacharacters.
// - Since a single-quoted string can't contain single quotes, replace each single quote in the
// argument with the sequence '"'"' . That closes the single quoted string, appends a literal
// single quote, and reopens the single quoted string

StringBuffer& sanitizeArg(const char* arg, StringBuffer& sanitized)
{
#if defined(__linux__) || defined(__APPLE__)
if (!isEmptyString(arg))
{
size_t len = strlen(arg);
sanitized.append('\'');
for (int i = 0; i < len; i++)
{
if (arg[i] == '\'')
sanitized.append(R"('"'"')");
else
sanitized.append(arg[i]);
}
sanitized.append('\'');
}
#else
sanitized.append(arg);
#endif
return sanitized;
}

void CWsWuFileHelper::sendWUComponentLogStreaming(CHttpRequest* request, CHttpResponse* response)
{
StringBuffer wuid, fileName;
Expand Down Expand Up @@ -4526,7 +4498,7 @@ void CWsWuFileHelper::zipZAPFiles(const char* parentFolder, const char* zapFiles
if (!isEmptyString(passwordReq))
{
StringBuffer sanitizedPassword;
sanitizeArg(passwordReq, sanitizedPassword);
sanitizeCommandArg(passwordReq, sanitizedPassword);
zipCommand.append(" --password ").append(sanitizedPassword);
}
zipCommand.append(" ").append(zipFileNameWithFullPath).append(" ").append(zapFiles);
Expand Down
29 changes: 29 additions & 0 deletions system/jlib/jstring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2983,3 +2983,32 @@ const void * jmemmem(size_t lenHaystack, const void * haystack, size_t lenNeedle

return nullptr;
}

/**
* For preventing command injection, sanitize the argument to be passed to the system command.
* - Quote the entire argument with single quotes to prevent interpretation of shell metacharacters.
* - Since a single-quoted string can't contain single quotes, even escaped, replace each single
* quote in the argument with the sequence '"'"' . That closes the single quoted string, appends
* a literal single quote, and reopens the single quoted string
*/
StringBuffer& sanitizeCommandArg(const char* arg, StringBuffer& sanitized)
{
#if defined(__linux__) || defined(__APPLE__)
if (!isEmptyString(arg))
{
size_t len = strlen(arg);
sanitized.append('\'');
for (size_t i = 0; i < len; i++)
{
if (arg[i] == '\'')
sanitized.append(R"('"'"')");
else
sanitized.append(arg[i]);
}
sanitized.append('\'');
}
#else
sanitized.append(arg);
#endif
return sanitized;
}
3 changes: 3 additions & 0 deletions system/jlib/jstring.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,4 +659,7 @@ extern jlib_decl void ensureSeparator(StringBuffer & out, char separator);
//Search for one block of bytes within another block of bytes - memmem is not standard, so we provide our own
extern jlib_decl const void * jmemmem(size_t lenHaystack, const void * haystack, size_t lenNeedle, const void *needle);

// For preventing command injection, sanitize the argument to be passed to the system command
extern jlib_decl StringBuffer& sanitizeCommandArg(const char* arg, StringBuffer& sanitized);

#endif

0 comments on commit 580bfae

Please sign in to comment.