Skip to content
Permalink
Browse files

Fix XSS vulnerability in WMTS and WMS error messages

Reported as
https://lists.osgeo.org/pipermail/mapserver-users/2017-August/080142.html

For WMTS error messages put inside XML comments, 'escape' the hyphen character
as -

For WMS error messages, put them directly as XML text (instead of a CDATA section)
as before and use escaping of the 5 special characters &,<,>,',".
  • Loading branch information...
rouault committed Aug 8, 2017
1 parent 26916de commit f28398700f406f2b10f41aab1fa3062fe0099b99
Showing with 61 additions and 4 deletions.
  1. +8 −0 include/mapcache.h
  2. +3 −3 lib/service_wms.c
  3. +3 −1 lib/service_wmts.c
  4. +47 −0 lib/util.c
@@ -1333,6 +1333,14 @@ char* mapcache_util_quadkey_encode(mapcache_context *ctx, int x, int y, int z);
*/
char* mapcache_util_str_sanitize(apr_pool_t *pool, const char *str, const char* from, char to);

typedef enum {
MAPCACHE_UTIL_XML_SECTION_TEXT,
MAPCACHE_UTIL_XML_SECTION_ATTRIBUTE,
MAPCACHE_UTIL_XML_SECTION_COMMENT
} mapcache_util_xml_section_type;

char* mapcache_util_str_xml_escape(apr_pool_t *pool, const char *str, mapcache_util_xml_section_type xml_section_type);

char* mapcache_util_get_tile_dimkey(mapcache_context *ctx, mapcache_tile *tile, char* sanitized_chars, char *sanitize_to);

char* mapcache_util_get_tile_key(mapcache_context *ctx, mapcache_tile *tile, char *stemplate,
@@ -1033,9 +1033,7 @@ void _format_error_wms(mapcache_context *ctx, mapcache_service *service, char *m
\"http://schemas.opengis.net/wms/1.1.1/exception_1_1_1.dtd\">\n\
<ServiceExceptionReport version=\"1.1.1\">\n\
<ServiceException>\n\
<![CDATA[\n\
%s\n\
]]>\n\
</ServiceException>\n\
%s\
</ServiceExceptionReport>";
@@ -1052,7 +1050,9 @@ void _format_error_wms(mapcache_context *ctx, mapcache_service *service, char *m
}
}

*err_body = apr_psprintf(ctx->pool,template,msg,exceptions);
*err_body = apr_psprintf(ctx->pool,template,
mapcache_util_str_xml_escape(ctx->pool, msg, MAPCACHE_UTIL_XML_SECTION_TEXT),
exceptions);
apr_table_set(headers, "Content-Type", "application/vnd.ogc.se_xml");
}

@@ -1014,7 +1014,9 @@ void _error_report_wmts(mapcache_context *ctx, mapcache_service *service, char *
"<Exception exceptionCode=\"%s\" locator=\"%s\"/>",elts[i].key,elts[i].val),NULL);
}

*err_body = apr_psprintf(ctx->pool,template,msg,exceptions);
*err_body = apr_psprintf(ctx->pool,template,
mapcache_util_str_xml_escape(ctx->pool, msg, MAPCACHE_UTIL_XML_SECTION_COMMENT),
exceptions);
apr_table_set(headers, "Content-Type", "application/xml");


@@ -185,6 +185,53 @@ char* mapcache_util_str_sanitize(apr_pool_t *pool, const char *str, const char*
return pstr;
}

char* mapcache_util_str_xml_escape(apr_pool_t *pool, const char *str,
mapcache_util_xml_section_type xml_section_type)
{
int outpos = 0;
char* outstr = apr_pcalloc(pool, 6 * strlen(str) + 1);
for( ; *str != '\0'; str ++ ) {
if( xml_section_type == MAPCACHE_UTIL_XML_SECTION_COMMENT ) {
if( *str == '-' ) {
memcpy(outstr + outpos, "&#45;", 5);
outpos += 5;
}
else {
outstr[outpos] = *str;
outpos ++;
}
}
else {
if( *str == '&' ) {
memcpy(outstr + outpos, "&amp;", 5);
outpos += 5;
}
else if( *str == '<' ) {
memcpy(outstr + outpos, "&lt;", 4);
outpos += 4;
}
else if( *str == '>' ) {
memcpy(outstr + outpos, "&gt;", 4);
outpos += 4;
}
else if( *str == '"' ) {
memcpy(outstr + outpos, "&quot;", 6);
outpos += 6;
}
else if( *str == '\'' ) {
/* See https://github.com/mapserver/mapserver/issues/1040 */
memcpy(outstr + outpos, "&#39;", 5);
outpos += 5;
}
else {
outstr[outpos] = *str;
outpos ++;
}
}
}
return outstr;
}

#if APR_MAJOR_VERSION < 1 || (APR_MAJOR_VERSION < 2 && APR_MINOR_VERSION < 3)
APR_DECLARE(apr_table_t *) apr_table_clone(apr_pool_t *p, const apr_table_t *t)
{

0 comments on commit f283987

Please sign in to comment.
You can’t perform that action at this time.