mirror of
https://github.com/znc/znc.git
synced 2026-05-06 21:42:28 +02:00
Don't require CSRF token for POSTs if the request uses HTTP Basic auth.
See #946
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 "
|
||||
|
||||
Reference in New Issue
Block a user