From fe7638287bb11419474ea314652404e7e9b314b2 Mon Sep 17 00:00:00 2001 From: Micah Snyder Date: Wed, 10 Jan 2024 12:09:15 -0500 Subject: [PATCH] ClamD: Disable VirusEvent '%f' feature, use environment var instead The '%f' filename format character has been disabled and will no longer be replaced with the file name, due to command injection security concerns. Use the 'CLAM_VIRUSEVENT_FILENAME' environment variable instead. For the same reason, you should NOT use the environment variables in the command directly, but should use it carefully from your executed script. --- clamd/clamd_others.c | 8 +++++--- common/optparser.c | 2 +- docs/man/clamd.conf.5.in | 14 ++++++++++---- etc/clamd.conf.sample | 18 ++++++++++++------ win32/conf_examples/clamd.conf.sample | 18 ++++++++++++------ 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/clamd/clamd_others.c b/clamd/clamd_others.c index 23f3b022c7..32d0701a0d 100644 --- a/clamd/clamd_others.c +++ b/clamd/clamd_others.c @@ -101,6 +101,8 @@ void virusaction(const char *filename, const char *virname, #define VE_FILENAME "CLAM_VIRUSEVENT_FILENAME" #define VE_VIRUSNAME "CLAM_VIRUSEVENT_VIRUSNAME" +#define FILENAME_DISABLED_MESSAGE "The filename format character has been disabled due to security concerns, use the 'CLAM_VIRUSEVENT_FILENAME' environment variable instead." + void virusaction(const char *filename, const char *virname, const struct optstruct *opts) { @@ -145,7 +147,7 @@ void virusaction(const char *filename, const char *virname, } len = strlen(opt->strarg); buffer_cmd = - (char *)calloc(len + v * strlen(virname) + f * strlen(filename) + 1, sizeof(char)); + (char *)calloc(len + v * strlen(virname) + f * strlen(FILENAME_DISABLED_MESSAGE) + 1, sizeof(char)); if (!buffer_cmd) { if (path) xfree(env[0]); @@ -160,8 +162,8 @@ void virusaction(const char *filename, const char *virname, j += strlen(virname); i++; } else if (i + 1 < len && opt->strarg[i] == '%' && opt->strarg[i + 1] == 'f') { - strcat(buffer_cmd, filename); - j += strlen(filename); + strcat(buffer_cmd, FILENAME_DISABLED_MESSAGE); + j += strlen(FILENAME_DISABLED_MESSAGE); i++; } else { buffer_cmd[j++] = opt->strarg[i]; diff --git a/common/optparser.c b/common/optparser.c index a7bdbee064..1be7afe867 100644 --- a/common/optparser.c +++ b/common/optparser.c @@ -333,7 +333,7 @@ const struct clam_option __clam_options[] = { {"DisableCache", "disable-cache", 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option allows you to disable clamd's caching feature.", "no"}, - {"VirusEvent", NULL, 0, CLOPT_TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMD, "Execute a command when a virus is found. In the command string %v will be\nreplaced with the virus name and %f will be replaced with the file name.\nAdditionally, two environment variables will be defined: $CLAM_VIRUSEVENT_FILENAME\nand $CLAM_VIRUSEVENT_VIRUSNAME.", "/usr/bin/mailx -s \"ClamAV VIRUS ALERT: %v\" alert < /dev/null"}, + {"VirusEvent", NULL, 0, CLOPT_TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMD, "Execute a command when virus is found.\nUse the following environment variables to identify the file and virus names:\n- $CLAM_VIRUSEVENT_FILENAME\n- $CLAM_VIRUSEVENT_VIRUSNAME\nIn the command string, '%v' will also be replaced with the virus name.\nNote: The '%f' filename format character has been disabled and will no longer\nbe replaced with the file name, due to command injection security concerns.\nUse the 'CLAM_VIRUSEVENT_FILENAME' environment variable instead.\nFor the same reason, you should NOT use the environment variables in the\ncommand directly, but should use it carefully from your executed script.", "/opt/send_virus_alert_sms.sh"}, {"ExitOnOOM", NULL, 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD, "Stop the daemon when libclamav reports an out of memory condition.", "yes"}, diff --git a/docs/man/clamd.conf.5.in b/docs/man/clamd.conf.5.in index 2d9748a39e..a9926533b9 100644 --- a/docs/man/clamd.conf.5.in +++ b/docs/man/clamd.conf.5.in @@ -240,10 +240,16 @@ Enable non-blocking (multi-threaded/concurrent) database reloads. This feature w Default: yes .TP \fBVirusEvent COMMAND\fR -Execute a command when a virus is found. In the command string %v will be -replaced with the virus name and %f will be replaced with the file name. -Additionally, two environment variables will be defined: $CLAM_VIRUSEVENT_FILENAME -and $CLAM_VIRUSEVENT_VIRUSNAME. +Execute a command when virus is found. +Use the following environment variables to identify the file and virus names: +- $CLAM_VIRUSEVENT_FILENAME +- $CLAM_VIRUSEVENT_VIRUSNAME +In the command string, '%v' will also be replaced with the virus name. +Note: The '%f' filename format character has been disabled and will no longer +be replaced with the file name, due to command injection security concerns. +Use the 'CLAM_VIRUSEVENT_FILENAME' environment variable instead. +For the same reason, you should NOT use the environment variables in the +command directly, but should use it carefully from your executed script. \fR .br Default: disabled diff --git a/etc/clamd.conf.sample b/etc/clamd.conf.sample index 37fb03bf20..54738128da 100644 --- a/etc/clamd.conf.sample +++ b/etc/clamd.conf.sample @@ -209,12 +209,18 @@ Example # Default: yes #ConcurrentDatabaseReload no -# Execute a command when virus is found. In the command string %v will -# be replaced with the virus name and %f will be replaced with the file name. -# Additionally, two environment variables will be defined: $CLAM_VIRUSEVENT_FILENAME -# and $CLAM_VIRUSEVENT_VIRUSNAME. -# Default: no -#VirusEvent /usr/local/bin/send_sms 123456789 "VIRUS ALERT: %v in %f" +# Execute a command when virus is found. +# Use the following environment variables to identify the file and virus names: +# - $CLAM_VIRUSEVENT_FILENAME +# - $CLAM_VIRUSEVENT_VIRUSNAME +# In the command string, '%v' will also be replaced with the virus name. +# Note: The '%f' filename format character has been disabled and will no longer +# be replaced with the file name, due to command injection security concerns. +# Use the 'CLAM_VIRUSEVENT_FILENAME' environment variable instead. +# For the same reason, you should NOT use the environment variables in the +# command directly, but should use it carefully from your executed script. +# Default: no +#VirusEvent /opt/send_virus_alert_sms.sh # Run as another user (clamd must be started by root for this option to work) # Default: don't drop privileges diff --git a/win32/conf_examples/clamd.conf.sample b/win32/conf_examples/clamd.conf.sample index 5a8a9cfeae..a4813f99cb 100644 --- a/win32/conf_examples/clamd.conf.sample +++ b/win32/conf_examples/clamd.conf.sample @@ -182,12 +182,18 @@ TCPAddr localhost # Default: yes #ConcurrentDatabaseReload no -# Execute a command when virus is found. In the command string %v will -# be replaced with the virus name and %f will be replaced with the file name. -# Additionally, two environment variables will be defined: $CLAM_VIRUSEVENT_FILENAME -# and $CLAM_VIRUSEVENT_VIRUSNAME. -# Default: no -#VirusEvent "C:\example\SendEmail.ps1" email@addresscom "VIRUS ALERT: %v in %f" +# Execute a command when virus is found. +# Use the following environment variables to identify the file and virus names: +# - $CLAM_VIRUSEVENT_FILENAME +# - $CLAM_VIRUSEVENT_VIRUSNAME +# In the command string, '%v' will also be replaced with the virus name. +# Note: The '%f' filename format character has been disabled and will no longer +# be replaced with the file name, due to command injection security concerns. +# Use the 'CLAM_VIRUSEVENT_FILENAME' environment variable instead. +# For the same reason, you should NOT use the environment variables in the +# command directly, but should use it carefully from your executed script. +# Default: no +#VirusEvent "C:\example\SendVirusAlertEmail.ps1" # Run as another user (clamd must be started by root for this option to work) # Default: don't drop privileges