Don't require CSRF token for POSTs if the request uses HTTP Basic auth.

See #946
This commit is contained in:
Alexey Sokolov
2015-04-16 20:57:29 +01:00
parent 7719213ea6
commit 144f7984e4
3 changed files with 9 additions and 2 deletions

View File

@@ -106,6 +106,7 @@ protected:
bool m_bLoggedIn;
bool m_bPost;
bool m_bDone;
bool m_bBasicAuth;
unsigned long m_uPostLen;
CString m_sPostData;
CString m_sURI;

View File

@@ -39,6 +39,7 @@ CHTTPSock::CHTTPSock(CModule *pMod, const CString& sURIPrefix, const CString& sH
m_bLoggedIn(false),
m_bPost(false),
m_bDone(false),
m_bBasicAuth(false),
m_uPostLen(0),
m_sPostData(""),
m_sURI(""),
@@ -136,6 +137,7 @@ void CHTTPSock::ReadLine(const CString& sData) {
sLine.Token(2).Base64Decode(sUnhashed);
m_sUser = sUnhashed.Token(0, false, ":");
m_sPass = sUnhashed.Token(1, true, ":");
m_bBasicAuth = true;
// Postpone authorization attempt until end of headers, because cookies should be read before that, otherwise session id will be overwritten in GetSession()
} else if (sName.Equals("Content-Length:")) {
m_uPostLen = sLine.Token(1).ToULong();
@@ -182,9 +184,10 @@ void CHTTPSock::ReadLine(const CString& sData) {
sLine.Token(1, true).Split(",", ssEncodings, false, "", "", false, true);
m_bAcceptGzip = (ssEncodings.find("gzip") != ssEncodings.end());
} else if (sLine.empty()) {
if (!m_sUser.empty() && !m_bLoggedIn) {
if (m_bBasicAuth && !m_bLoggedIn) {
m_bLoggedIn = OnLogin(m_sUser, m_sPass, true);
// After successful login ReadLine("") will be called again to trigger "else" block
// Failed login sends error and closes socket, so no infinite loop here
} else {
m_bGotHeader = true;

View File

@@ -601,7 +601,10 @@ CWebSock::EPageReqResult CWebSock::OnPageRequestInternal(const CString& sURI, CS
// know the "secret" CSRF check value. Don't do this for login since
// CSRF against the login form makes no sense and the login form does a
// cookies-enabled check which would break otherwise.
if (IsPost() && GetParam("_CSRF_Check") != GetCSRFCheck() && sURI != "/login") {
// Don't do this, if user authenticated using http-basic auth, because:
// 1. they obviously know the password,
// 2. it's easier to automate some tasks e.g. user creation, without need to care about cookies and csrf
if (IsPost() && !m_bBasicAuth && GetParam("_CSRF_Check") != GetCSRFCheck() && sURI != "/login") {
DEBUG("Expected _CSRF_Check: " << GetCSRFCheck());
DEBUG("Actual _CSRF_Check: " << GetParam("_CSRF_Check"));
PrintErrorPage(403, "Access denied", "POST requests need to send "