diff --git a/HISTORY.md b/HISTORY.md index 5cdc105b..f26052b4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,11 +1,13 @@ unreleased ========== + * Properly escape file names in HTML * deps: accepts@~1.2.5 - deps: mime-types@~2.0.10 * deps: debug@~2.1.3 - Fix high intensity foreground color for bold - deps: ms@0.7.0 + * deps: escape-html@1.0.1 * deps: mime-types@~2.0.10 - Add new mime types diff --git a/LICENSE b/LICENSE index b7bc0852..d8cce679 100644 --- a/LICENSE +++ b/LICENSE @@ -3,7 +3,7 @@ Copyright (c) 2010 Sencha Inc. Copyright (c) 2011 LearnBoost Copyright (c) 2011 TJ Holowaychuk -Copyright (c) 2014 Douglas Christopher Wilson +Copyright (c) 2014-2015 Douglas Christopher Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/index.js b/index.js index 1fec6fd9..abf81a45 100644 --- a/index.js +++ b/index.js @@ -2,7 +2,7 @@ * serve-index * Copyright(c) 2011 Sencha Inc. * Copyright(c) 2011 TJ Holowaychuk - * Copyright(c) 2014 Douglas Christopher Wilson + * Copyright(c) 2014-2015 Douglas Christopher Wilson * MIT Licensed */ @@ -11,11 +11,13 @@ /** * Module dependencies. + * @private */ var accepts = require('accepts'); var createError = require('http-errors'); var debug = require('debug')('serve-index'); +var escapeHtml = require('escape-html'); var fs = require('fs') , path = require('path') , normalize = path.normalize @@ -175,7 +177,7 @@ exports.html = function(req, res, files, next, dir, showUp, icons, path, view, t str = str .replace(/\{style\}/g, style.concat(iconStyle(files, icons))) .replace(/\{files\}/g, html(files, dir, icons, view)) - .replace(/\{directory\}/g, dir) + .replace(/\{directory\}/g, escapeHtml(dir)) .replace(/\{linked-path\}/g, htmlPath(dir)); var buf = new Buffer(str, 'utf8'); @@ -227,11 +229,19 @@ function fileSort(a, b) { */ function htmlPath(dir) { - var curr = []; - return dir.split('/').map(function(part){ - curr.push(encodeURIComponent(part)); - return part ? '' + part + '' : ''; - }).join(' / '); + var parts = dir.split('/'); + var crumb = new Array(parts.length); + + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + + if (part) { + parts[i] = encodeURIComponent(part); + crumb[i] = '' + escapeHtml(part) + ''; + } + } + + return crumb.join(' / '); } /** @@ -342,7 +352,7 @@ function iconStyle (files, useIcons) { */ function html(files, dir, useIcons, view) { - return '