Fixes csrf issue

This commit is contained in:
Shannon
2013-11-29 11:10:25 +11:00
parent 226e35d65a
commit af29f61478
11 changed files with 65 additions and 38 deletions

View File

@@ -10,7 +10,7 @@ NOTES:
* Compression/Combination/Minification is not enabled unless debug="false" is specified on the 'compiliation' element in the web.config
* A new version will invalidate both client and server cache and create new persisted files
-->
<clientDependency version="8" fileDependencyExtensions=".js,.css" loggerType="Umbraco.Web.UI.CdfLogger, umbraco">
<clientDependency version="9" fileDependencyExtensions=".js,.css" loggerType="Umbraco.Web.UI.CdfLogger, umbraco">
<!--
This section is used for Web Forms only, the enableCompositeFiles="true" is optional and by default is set to true.

View File

@@ -67,7 +67,9 @@ namespace Umbraco.Web.UI.Install
if (result == ValidateRequestAttempt.FailedTimedOut || result == ValidateRequestAttempt.FailedNoPrivileges)
{
Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?redir=" + Server.UrlEncode(Request.RawUrl));
Response.Redirect(
//We must add the token to prevent CSRF attacks since the logout occurs on a GET not a POST
SystemDirectories.Umbraco + "/logout.aspx?redir=" + Server.UrlEncode(Request.RawUrl) + "&t=" + Security.UmbracoUserContextId);
}
}

View File

@@ -1,21 +1,10 @@
<%@ Page language="c#" Codebehind="logout.aspx.cs" AutoEventWireup="True" Inherits="umbraco.logout" %>
<%@ Page language="c#" AutoEventWireup="True" Inherits="umbraco.logout" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<html>
<head>
<title>logout</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name=vs_defaultClientScript content="JavaScript">
<meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
<title>Logout</title>
</head>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<script>
window.top.location.href='login.aspx?redir=<%=Server.UrlEncode(Request["redir"]) %>';
</script>
</form>
<body>
</body>
</html>

View File

@@ -91,14 +91,19 @@
</div>
</asp:Panel>
<div class="topBarButtons">
<button onclick="UmbClientMgr.appActions().launchAbout();" class="topBarButton">
<img src="images/aboutNew.png" alt="about" /><span><%=umbraco.ui.Text("general", "about")%></span></button>
<button onclick="UmbClientMgr.appActions().launchHelp('<%=UmbracoUser.Language%>', '<%=UmbracoUser.UserType.Name%>');"
class="topBarButton">
<img src="images/help.png" alt="Help" /><span><%=umbraco.ui.Text("general", "help")%></span></button>
<button onclick="UmbClientMgr.appActions().logout();" class="topBarButton">
<img src="images/logout.png" alt="Log out" /><span><%=umbraco.ui.Text("general", "logout")%>:
<%=UmbracoUser.Name%></span></button>
<form action="logout.aspx" method="get" style="display: inline;" >
<button class="topBarButton" type="submit">
<img src="images/logout.png" alt="Log out" />
<span><%=umbraco.ui.Text("general", "logout")%>:<%=UmbracoUser.Name%></span>
</button>
<input type="hidden" value="<%=Security.UmbracoUserContextId %>" name="t" id="t"/>
</form>
</div>
</div>
</div>
@@ -341,7 +346,7 @@
function umbracoSessionLogout() {
//alert('Session has expired on server - can\'t renew. Logging out!');
top.document.location.href = 'logout.aspx';
top.document.location.href = 'logout.aspx?t=<%=Security.UmbracoUserContextId%>';
}
function blink($target) {

View File

@@ -10,7 +10,7 @@ Umbraco.Application.Actions = function () {
/// <summary>
/// Application actions actions for the context menu, help dialogs, logout, etc...
/// This class supports an event listener model. Currently the available events are:
/// "nodeDeleting","nodeDeleted","nodeRefresh","beforeLogout"
/// "nodeDeleting","nodeDeleted","nodeRefresh"
/// </summary>
return {
@@ -75,13 +75,17 @@ Umbraco.Application.Actions = function () {
alert('Not supported - please create by right clicking the parentnode and choose new...');
},
logout: function () {
/// <summary>Logs the user out</summary>
logout: function (t) {
if (!t) {
throw "The security token must be set in order to log a user out using this method";
}
if (confirm(UmbClientMgr.uiKeys()["defaultdialogs_confirmlogout"])) {
//raise beforeLogout event
jQuery(window.top).trigger("beforeLogout", []);
document.location.href = 'logout.aspx';
document.location.href = 'logout.aspx?t=' + t;
}
return false;
},
@@ -240,11 +244,14 @@ Umbraco.Application.Actions = function () {
}
},
actionQuit: function () {
/// <summary></summary>
actionQuit: function (t) {
if (!t) {
throw "The security token must be set in order to log a user out using this method";
}
if (confirm(uiKeys['defaultdialogs_confirmlogout'] + '\n\n'))
document.location.href = 'logout.aspx';
document.location.href = 'logout.aspx?t=' + t;
},
actionRePublish: function () {

View File

@@ -46,9 +46,9 @@ namespace Umbraco.Web.UI.Pages
// Some umbraco pages should not be loaded on timeout, but instead reload the main application in the top window. Like the treeview for instance
if (RedirectToUmbraco)
Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?", true);
Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?t=" + Security.UmbracoUserContextId, true);
else
Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?redir=" + Server.UrlEncode(Request.RawUrl), true);
Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?redir=" + Server.UrlEncode(Request.RawUrl) + "&t=" + Security.UmbracoUserContextId, true);
}
}

View File

@@ -113,7 +113,7 @@ namespace umbraco.presentation.install
}
catch (Exception)
{
Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?redir=" + Server.UrlEncode(Request.RawUrl));
Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?redir=" + Server.UrlEncode(Request.RawUrl) + "&t=" + umbracoUserContextID);
}
//set the first step to upgrade.

View File

@@ -8,21 +8,32 @@ using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Umbraco.Web;
using Umbraco.Core;
namespace umbraco
{
/// <summary>
/// Summary description for logout.
/// </summary>
public partial class logout : BasePages.BasePage
public class logout : BasePages.BasePage
{
protected void Page_Load(object sender, System.EventArgs e)
protected override void OnInit(EventArgs e)
{
// Put user code to initialize the page here
if (umbracoUserContextID != "")
base.ClearLogin();
base.OnInit(e);
//We need to check the token in the URL to ensure it is correct otherwise malicious GET requests using CSRF attacks
// can easily just log the user out.
var token = Request["t"];
//only perform the logout if the token matches
if (token.IsNullOrWhiteSpace() == false && token == umbracoUserContextID)
{
ClearLogin();
}
//redirect home
Response.Redirect("Login.aspx?redir=" + Server.UrlEncode(Request["redir"]));
}
protected System.Web.UI.HtmlControls.HtmlForm Form1;
}
}

View File

@@ -441,6 +441,18 @@ namespace umbraco.BasePages
warning
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
//This must be set on each page to mitigate CSRF attacks which ensures that this unique token
// is added to the viewstate of each request
if (umbracoUserContextID.IsNullOrWhiteSpace() == false)
{
ViewStateUserKey = umbracoUserContextID;
}
}
/// <summary>
/// Raises the <see cref="E:System.Web.UI.Control.Load"></see> event.
/// </summary>

View File

@@ -104,9 +104,9 @@ namespace umbraco.BasePages
// Some umbraco pages should not be loaded on timeout, but instead reload the main application in the top window. Like the treeview for instance
if (RedirectToUmbraco)
Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?", true);
Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?t=" + umbracoUserContextID, true);
else
Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?redir=" + Server.UrlEncode(Request.RawUrl), true);
Response.Redirect(SystemDirectories.Umbraco + "/logout.aspx?redir=" + Server.UrlEncode(Request.RawUrl) + "&t=" + umbracoUserContextID, true);
}
}
}

View File

@@ -7,6 +7,7 @@ namespace umbraco.BusinessLogic.Actions
/// <summary>
/// This action is invoked when a user logs out
/// </summary>
[Obsolete("This should not be used and will be removed from the codebase in future versions")]
public class ActionQuit : IAction
{
//create singleton