Skip to content

Commit d719a81

Browse files
committed
Fix XSS vulnerability in WMTS and WMS error messages (#172)
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 &#45; 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 &,<,>,',".
1 parent b2bdb54 commit d719a81

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

include/mapcache.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,14 @@ char* mapcache_util_quadkey_encode(mapcache_context *ctx, int x, int y, int z);
13411341
*/
13421342
char* mapcache_util_str_sanitize(apr_pool_t *pool, const char *str, const char* from, char to);
13431343

1344+
typedef enum {
1345+
MAPCACHE_UTIL_XML_SECTION_TEXT,
1346+
MAPCACHE_UTIL_XML_SECTION_ATTRIBUTE,
1347+
MAPCACHE_UTIL_XML_SECTION_COMMENT
1348+
} mapcache_util_xml_section_type;
1349+
1350+
char* mapcache_util_str_xml_escape(apr_pool_t *pool, const char *str, mapcache_util_xml_section_type xml_section_type);
1351+
13441352
char* mapcache_util_get_tile_dimkey(mapcache_context *ctx, mapcache_tile *tile, char* sanitized_chars, char *sanitize_to);
13451353

13461354
char* mapcache_util_get_tile_key(mapcache_context *ctx, mapcache_tile *tile, char *stemplate,

lib/service_wms.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,9 +1033,7 @@ void _format_error_wms(mapcache_context *ctx, mapcache_service *service, char *m
10331033
\"http://schemas.opengis.net/wms/1.1.1/exception_1_1_1.dtd\">\n\
10341034
<ServiceExceptionReport version=\"1.1.1\">\n\
10351035
<ServiceException>\n\
1036-
<![CDATA[\n\
10371036
%s\n\
1038-
]]>\n\
10391037
</ServiceException>\n\
10401038
%s\
10411039
</ServiceExceptionReport>";
@@ -1052,7 +1050,9 @@ void _format_error_wms(mapcache_context *ctx, mapcache_service *service, char *m
10521050
}
10531051
}
10541052

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

lib/service_wmts.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,9 @@ void _error_report_wmts(mapcache_context *ctx, mapcache_service *service, char *
10141014
"<Exception exceptionCode=\"%s\" locator=\"%s\"/>",elts[i].key,elts[i].val),NULL);
10151015
}
10161016

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

10201022

lib/util.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,53 @@ char* mapcache_util_str_sanitize(apr_pool_t *pool, const char *str, const char*
185185
return pstr;
186186
}
187187

188+
char* mapcache_util_str_xml_escape(apr_pool_t *pool, const char *str,
189+
mapcache_util_xml_section_type xml_section_type)
190+
{
191+
int outpos = 0;
192+
char* outstr = apr_pcalloc(pool, 6 * strlen(str) + 1);
193+
for( ; *str != '\0'; str ++ ) {
194+
if( xml_section_type == MAPCACHE_UTIL_XML_SECTION_COMMENT ) {
195+
if( *str == '-' ) {
196+
memcpy(outstr + outpos, "&#45;", 5);
197+
outpos += 5;
198+
}
199+
else {
200+
outstr[outpos] = *str;
201+
outpos ++;
202+
}
203+
}
204+
else {
205+
if( *str == '&' ) {
206+
memcpy(outstr + outpos, "&amp;", 5);
207+
outpos += 5;
208+
}
209+
else if( *str == '<' ) {
210+
memcpy(outstr + outpos, "&lt;", 4);
211+
outpos += 4;
212+
}
213+
else if( *str == '>' ) {
214+
memcpy(outstr + outpos, "&gt;", 4);
215+
outpos += 4;
216+
}
217+
else if( *str == '"' ) {
218+
memcpy(outstr + outpos, "&quot;", 6);
219+
outpos += 6;
220+
}
221+
else if( *str == '\'' ) {
222+
/* See https://github.com/mapserver/mapserver/issues/1040 */
223+
memcpy(outstr + outpos, "&#39;", 5);
224+
outpos += 5;
225+
}
226+
else {
227+
outstr[outpos] = *str;
228+
outpos ++;
229+
}
230+
}
231+
}
232+
return outstr;
233+
}
234+
188235
#if APR_MAJOR_VERSION < 1 || (APR_MAJOR_VERSION < 2 && APR_MINOR_VERSION < 3)
189236
APR_DECLARE(apr_table_t *) apr_table_clone(apr_pool_t *p, const apr_table_t *t)
190237
{

0 commit comments

Comments
 (0)