Skip to content

Commit

Permalink
HPCC-32999 Sanitize user provided password to ZAP file
Browse files Browse the repository at this point in the history
- Single-quote the entire password to preserve all characters but prevent
  interpretation as metacharacters.
- Replace any single quote in the original string with a sequence of characters
  that breaks the single-quoted password into three parts
    (1) a single-quoted prefix
    (2) a double-quoted single quote and
    (3) a single-quoted suffix
- The shell quote-removal deletes double-quotes around any single quote at the
  same time that it de-quotes the single-quoted prefix and suffix, leaving any
  single quote inside the password string that is tokenized as a single
  argument.

This will require a different approach for Windows targets as a future task.

Signed-off-by: Terrence Asselin <[email protected]>
  • Loading branch information
asselitx committed Dec 6, 2024
1 parent ab280fe commit 5dc0da6
Showing 1 changed file with 33 additions and 1 deletion.
34 changes: 33 additions & 1 deletion esp/services/ws_workunits/ws_workunitsHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4326,6 +4326,34 @@ 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 @@ -4496,7 +4524,11 @@ void CWsWuFileHelper::zipZAPFiles(const char* parentFolder, const char* zapFiles
else
zipCommand.setf("cd %s\nzip -r", parentFolder);
if (!isEmptyString(passwordReq))
zipCommand.append(" --password ").append(passwordReq);
{
StringBuffer sanitizedPassword;
sanitizeArg(passwordReq, sanitizedPassword);
zipCommand.append(" --password ").append(sanitizedPassword);
}
zipCommand.append(" ").append(zipFileNameWithFullPath).append(" ").append(zapFiles);
int zipRet = system(zipCommand);
if (zipRet != 0)
Expand Down

0 comments on commit 5dc0da6

Please sign in to comment.