diff --git a/src/umbraco.cms/helpers/url.cs b/src/umbraco.cms/helpers/url.cs
index 8426486ce0..3fdc380785 100644
--- a/src/umbraco.cms/helpers/url.cs
+++ b/src/umbraco.cms/helpers/url.cs
@@ -1,30 +1,31 @@
using System;
using System.Xml;
using System.Text.RegularExpressions;
+using umbraco.IO;
namespace umbraco.cms.helpers
{
- ///
- /// Summary description for url.
- ///
- public class url
- {
- public url()
- {
- //
- // TODO: Add constructor logic here
- //
- }
+ ///
+ /// Summary description for url.
+ ///
+ public class url
+ {
+ public url()
+ {
+ //
+ // TODO: Add constructor logic here
+ //
+ }
- public static string FormatUrl(string url)
- {
- string _newUrl = url;
- XmlNode replaceChars = UmbracoSettings.UrlReplaceCharacters;
- foreach (XmlNode n in replaceChars.SelectNodes("char"))
- {
- if (n.Attributes.GetNamedItem("org") != null && n.Attributes.GetNamedItem("org").Value != "")
- _newUrl = _newUrl.Replace(n.Attributes.GetNamedItem("org").Value,xmlHelper.GetNodeValue(n));
- }
+ public static string FormatUrl(string url)
+ {
+ string _newUrl = url;
+ XmlNode replaceChars = UmbracoSettings.UrlReplaceCharacters;
+ foreach (XmlNode n in replaceChars.SelectNodes("char"))
+ {
+ if (n.Attributes.GetNamedItem("org") != null && n.Attributes.GetNamedItem("org").Value != "")
+ _newUrl = _newUrl.Replace(n.Attributes.GetNamedItem("org").Value, xmlHelper.GetNodeValue(n));
+ }
// check for double dashes
if (UmbracoSettings.RemoveDoubleDashesFromUrlReplacing)
@@ -32,8 +33,49 @@ namespace umbraco.cms.helpers
_newUrl = Regex.Replace(_newUrl, @"[-]{2,}", "-");
}
- return _newUrl;
- }
+ return _newUrl;
+ }
- }
+ ///
+ /// Utility method for checking for valid proxy urls or redirect urls to prevent Open Redirect security issues
+ ///
+ /// The url to validate
+ /// The url of the current local domain (to ensure we can validate if the requested url is local without dependency on the request)
+ /// True if it's an allowed url
+ public static bool ValidateProxyUrl(string url, string callerUrl)
+ {
+ Uri requestUri;
+ Uri localUri;
+ if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out requestUri))
+ {
+ if (!String.IsNullOrEmpty(callerUrl))
+ {
+ if (Uri.TryCreate(callerUrl, UriKind.RelativeOrAbsolute, out localUri))
+ {
+ // check for local urls
+ if (!requestUri.IsAbsoluteUri || requestUri.Host == localUri.Host)
+ {
+ return true;
+ }
+ }
+ else
+ {
+ throw new ArgumentException("CallerUrl is in a wrong format that couldn't be parsed as a valid URI. If you don't want to evaluate for local urls, but just proxy urls then leave callerUrl empty", "callerUrl");
+ }
+ }
+ // check for valid proxy urls
+ var feedProxyXml = xmlHelper.OpenAsXmlDocument(IOHelper.MapPath(SystemFiles.FeedProxyConfig));
+ if (feedProxyXml != null &&
+ feedProxyXml.SelectSingleNode(string.Concat("//allow[@host = '", requestUri.Host, "']")) != null)
+ {
+ return true;
+ }
+ } else
+ {
+ throw new ArgumentException("url is in a wrong format that couldn't be parsed as a valid URI", "url");
+
+ }
+ return false;
+ }
+ }
}