File httpd-2.2.x-bnc806458-mod_imagemap-xss.diff of Package apache2.1524
diff -rNU 30 ../httpd-2.2.12-o/modules/mappers/mod_imagemap.c ./modules/mappers/mod_imagemap.c
--- ../httpd-2.2.12-o/modules/mappers/mod_imagemap.c 2007-12-12 20:38:26.000000000 +0100
+++ ./modules/mappers/mod_imagemap.c 2013-03-26 18:27:57.000000000 +0100
@@ -315,61 +315,61 @@
strp++; /* step over the last double quote */
*string = strp;
}
}
/*
* returns the mapped URL or NULL.
*/
static char *imap_url(request_rec *r, const char *base, const char *value)
{
/* translates a value into a URL. */
int slen, clen;
char *string_pos = NULL;
const char *string_pos_const = NULL;
char *directory = NULL;
const char *referer = NULL;
char *my_base;
if (!strcasecmp(value, "map") || !strcasecmp(value, "menu")) {
return ap_construct_url(r->pool, r->uri, r);
}
if (!strcasecmp(value, "nocontent") || !strcasecmp(value, "error")) {
return apr_pstrdup(r->pool, value); /* these are handled elsewhere,
so just copy them */
}
if (!strcasecmp(value, "referer")) {
referer = apr_table_get(r->headers_in, "Referer");
if (referer && *referer) {
- return ap_escape_html(r->pool, referer);
+ return referer;
}
else {
/* XXX: This used to do *value = '\0'; ... which is totally bogus
* because it hammers the passed in value, which can be a string
* constant, or part of a config, or whatever. Total garbage.
* This works around that without changing the rest of this
* code much
*/
value = ""; /* if 'referer' but no referring page,
null the value */
}
}
string_pos_const = value;
while (apr_isalpha(*string_pos_const)) {
string_pos_const++; /* go along the URL from the map
until a non-letter */
}
if (*string_pos_const == ':') {
/* if letters and then a colon (like http:) */
/* it's an absolute URL, so use it! */
return apr_pstrdup(r->pool, value);
}
if (!base || !*base) {
if (value && *value) {
return apr_pstrdup(r->pool, value); /* no base: use what is given */
}
/* no base, no value: pick a simple default */
return ap_construct_url(r->pool, "/", r);
@@ -498,94 +498,105 @@
{
if (!strcasecmp(menu, "formatted")) {
ap_rputs("\n", r);
}
if (!strcasecmp(menu, "semiformatted")) {
ap_rputs("<br />\n", r);
}
if (!strcasecmp(menu, "unformatted")) {
ap_rputs("\n", r);
}
return;
}
static void menu_comment(request_rec *r, char *menu, char *comment)
{
if (!strcasecmp(menu, "formatted")) {
ap_rputs("\n", r); /* print just a newline if 'formatted' */
}
if (!strcasecmp(menu, "semiformatted") && *comment) {
ap_rvputs(r, comment, "\n", NULL);
}
if (!strcasecmp(menu, "unformatted") && *comment) {
ap_rvputs(r, comment, "\n", NULL);
}
return; /* comments are ignored in the
'formatted' form */
}
static void menu_default(request_rec *r, char *menu, char *href, char *text)
{
+ char *ehref, *etext;
if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
return; /* don't print such lines, these aren't
really href's */
}
+
+ ehref = ap_escape_uri(r->pool, href);
+ etext = ap_escape_html(r->pool, text);
+
if (!strcasecmp(menu, "formatted")) {
- ap_rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text,
- "</a></pre>\n", NULL);
+ ap_rvputs(r, "<pre>(Default) <a href=\"", ehref, "\">", etext,
+ "</a></pre>\n", NULL);
}
if (!strcasecmp(menu, "semiformatted")) {
- ap_rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text,
+ ap_rvputs(r, "<pre>(Default) <a href=\"", ehref, "\">", etext,
"</a></pre>\n", NULL);
}
if (!strcasecmp(menu, "unformatted")) {
- ap_rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
+ ap_rvputs(r, "<a href=\"", ehref, "\">", etext, "</a>", NULL);
}
return;
}
static void menu_directive(request_rec *r, char *menu, char *href, char *text)
{
+ char *ehref, *etext;
+
if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
return; /* don't print such lines, as this isn't
really an href */
}
+
+ ehref = ap_escape_uri(r->pool, href);
+ etext = ap_escape_html(r->pool, text);
+
if (!strcasecmp(menu, "formatted")) {
- ap_rvputs(r, "<pre> <a href=\"", href, "\">", text,
+ ap_rvputs(r, "<pre> <a href=\"", ehref, "\">", etext,
"</a></pre>\n", NULL);
}
if (!strcasecmp(menu, "semiformatted")) {
- ap_rvputs(r, "<pre> <a href=\"", href, "\">", text,
+ ap_rvputs(r, "<pre> <a href=\"", ehref, "\">", etext,
"</a></pre>\n", NULL);
}
if (!strcasecmp(menu, "unformatted")) {
- ap_rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
+ ap_rvputs(r, "<a href=\"", ehref, "\">", etext, "</a>", NULL);
}
return;
}
static void menu_footer(request_rec *r)
{
ap_rputs("\n\n</body>\n</html>\n", r); /* finish the menu */
}
static int imap_handler_internal(request_rec *r)
{
char input[MAX_STRING_LEN];
char *directive;
char *value;
char *href_text;
char *base;
char *redirect;
char *mapdflt;
char *closest = NULL;
double closest_yet = -1;
apr_status_t status;
double testpoint[2];
double pointarray[MAXVERTS + 1][2];
int vertex;
char *string_pos;
int showmenu = 0;
imap_conf_rec *icr;