From fc887b95f1ea898af369f6d092ced8d03d9e5001 Mon Sep 17 00:00:00 2001 From: hartvig Date: Fri, 3 Feb 2012 05:08:04 -0100 Subject: [PATCH] Work items: 30702 --- umbraco/presentation/umbraco/login.aspx.cs | 52 ++++++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/umbraco/presentation/umbraco/login.aspx.cs b/umbraco/presentation/umbraco/login.aspx.cs index 8e00a68a08..426316d421 100644 --- a/umbraco/presentation/umbraco/login.aspx.cs +++ b/umbraco/presentation/umbraco/login.aspx.cs @@ -3,6 +3,7 @@ using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; +using System.Security; using System.Web; using System.Web.SessionState; using System.Web.UI; @@ -27,6 +28,13 @@ namespace umbraco.cms.presentation { base.OnLoad(e); ClientLoader.DataBind(); + + // validate redirect url + string redirUrl = Request["redir"]; + if (!String.IsNullOrEmpty(redirUrl)) + { + validateRedirectUrl(redirUrl); + } } @@ -108,16 +116,54 @@ namespace umbraco.cms.presentation Session["windowWidth"] = hf_width.Value; } - if (string.IsNullOrEmpty(Request["redir"])) + string redirUrl = Request["redir"]; + + if (string.IsNullOrEmpty(redirUrl)) Response.Redirect("umbraco.aspx"); - else - Response.Redirect(Request["redir"]); + else if (validateRedirectUrl(redirUrl)) + { + Response.Redirect(redirUrl, true); + } } else { loginError.Visible = true; } } + private bool validateRedirectUrl(string url) + { + if (!isUrlLocalToHost(url)) + { + Log.Add(LogTypes.Error, -1, String.Format("Security warning: Login redirect was attempted to a site at another domain: '{0}'", url)); + throw new SecurityException( + String.Format(@"There was attempt to redirect to '{0}' which is another domain than where you've logged in. If you clicked a link to reach this login + screen, please double check that the link came from someone you trust. You *might* have been exposed to an *attempt* to breach the security of your website. Nothing + have been compromised, though!", url)); + } + + return true; + } + + private bool isUrlLocalToHost(string url) + { + if (String.IsNullOrEmpty(url)) + { + return false; + } + + Uri absoluteUri; + if (Uri.TryCreate(url, UriKind.Absolute, out absoluteUri)) + { + return String.Equals(HttpContext.Current.Request.Url.Host, absoluteUri.Host, + StringComparison.OrdinalIgnoreCase); + } + + bool isLocal = !url.StartsWith("http:", StringComparison.OrdinalIgnoreCase) + && !url.StartsWith("https:", StringComparison.OrdinalIgnoreCase) + && Uri.IsWellFormedUriString(url, UriKind.Relative); + return isLocal; + } + /// /// Maps active directory account to umbraco user account ///