Skip to content

Commit 80f7445

Browse files
committed
Add a workaround for a squidGuard bug that unescape the URL and send it back unescaped. This could conduct in wrong result and ssquidclamav crash especially with URL containing the %0D or %0A character. John Xue
1 parent 5806d10 commit 80f7445

File tree

1 file changed

+43
-2
lines changed

1 file changed

+43
-2
lines changed

Diff for: src/squidclamav.c

+43-2
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ void cfgreload_command(char *, int, char **);
133133
int create_pipe(char *command);
134134
int dconnect (void);
135135
int connectINET(char *serverHost, uint16_t serverPort);
136-
136+
char * replace(const char *s, const char *old, const char *new);
137137

138138
/* ----------------------------------------------------- */
139139

@@ -365,10 +365,14 @@ int squidclamav_check_preview_handler(char *preview_data, int preview_data_len,
365365

366366
/* Check URL header against squidGuard */
367367
if (usepipe == 1) {
368+
char *rbuff = NULL;
368369
ci_debug_printf(2, "DEBUG squidclamav_check_preview_handler: Sending request to chained program: %s\n", squidguard);
369370
ci_debug_printf(2, "DEBUG squidclamav_check_preview_handler: Request: %s %s %s %s\n", httpinf.url,clientip,username,httpinf.method);
370-
fprintf(sgfpw,"%s %s %s %s\n",httpinf.url,clientip,username,httpinf.method);
371+
/* escaping escaped character to prevent unescaping by squidguard */
372+
rbuff = replace(httpinf.url, "%", "%25");
373+
fprintf(sgfpw,"%s %s %s %s\n",rbuff,clientip,username,httpinf.method);
371374
fflush(sgfpw);
375+
xfree(rbuff);
372376
/* the chained redirector must return empty line if ok or the redirection url */
373377
chain_ret = (char *)malloc(sizeof(char)*MAX_URL_SIZE);
374378
if (chain_ret != NULL) {
@@ -1628,3 +1632,40 @@ connectINET(char *serverHost, uint16_t serverPort)
16281632
return asockd;
16291633
}
16301634

1635+
1636+
/**
1637+
* Searches all occurrences of old into s
1638+
* and replaces with new
1639+
*/
1640+
char *
1641+
replace(const char *s, const char *old, const char *new)
1642+
{
1643+
char *ret;
1644+
int i, count = 0;
1645+
size_t newlen = strlen(new);
1646+
size_t oldlen = strlen(old);
1647+
1648+
for (i = 0; s[i] != '\0'; i++) {
1649+
if (strstr(&s[i], old) == &s[i]) {
1650+
count++;
1651+
i += oldlen - 1;
1652+
}
1653+
}
1654+
ret = malloc(i + 1 + count * (newlen - oldlen));
1655+
if (ret != NULL) {
1656+
i = 0;
1657+
while (*s) {
1658+
if (strstr(s, old) == s) {
1659+
strcpy(&ret[i], new);
1660+
i += newlen;
1661+
s += oldlen;
1662+
} else {
1663+
ret[i++] = *s++;
1664+
}
1665+
}
1666+
ret[i] = '\0';
1667+
}
1668+
1669+
return ret;
1670+
}
1671+

0 commit comments

Comments
 (0)