Allow modules to override CSRF protection.

Useful for Web APIs and all other kinds of things.

API changes:
	- Added public CHTTPSock::GetURI() method
	- Added public CModule::ValidateWebRequestCSRFCheck() method
	- Made CWebSock::GetCSRFCheck() method public so it can be accessed
	  from CModule
	- Added public CWebSock::ValidateCSRFCheck() method

Other changes:
	- Added a Sample Web API module (modules/samplewebapi.cpp) and a
	  simple web form with no CSRF check.

Implements feature request #1180.
This commit is contained in:
Latchezar Tzvetkoff
2016-07-15 18:01:41 +03:00
committed by lol768
parent 222ae86fcc
commit a9a7f17910
8 changed files with 111 additions and 3 deletions

View File

@@ -655,8 +655,8 @@ CWebSock::EPageReqResult CWebSock::OnPageRequestInternal(const CString& sURI,
// 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") {
if (IsPost() && !m_bBasicAuth && !sURI.StartsWith("/mods/") &&
!ValidateCSRFCheck(sURI)) {
DEBUG("Expected _CSRF_Check: " << GetCSRFCheck());
DEBUG("Actual _CSRF_Check: " << GetParam("_CSRF_Check"));
PrintErrorPage(
@@ -803,6 +803,18 @@ CWebSock::EPageReqResult CWebSock::OnPageRequestInternal(const CString& sURI,
if (!pModule) return PAGE_NOTFOUND;
// Pass CSRF check to module.
if (IsPost() && !m_bBasicAuth &&
!pModule->ValidateWebRequestCSRFCheck(*this, m_sPage)) {
DEBUG("Expected _CSRF_Check: " << GetCSRFCheck());
DEBUG("Actual _CSRF_Check: " << GetParam("_CSRF_Check"));
PrintErrorPage(
403, "Access denied",
"POST requests need to send "
"a secret token to prevent cross-site request forgery attacks.");
return PAGE_DONE;
}
m_Template["ModPath"] = pModule->GetWebPath();
m_Template["ModFilesPath"] = pModule->GetWebFilesPath();
@@ -969,6 +981,10 @@ CString CWebSock::GetCSRFCheck() {
return pSession->GetId().MD5();
}
bool CWebSock::ValidateCSRFCheck(const CString& sURI) {
return sURI == "/login" || GetParam("_CSRF_Check") == GetCSRFCheck();
}
bool CWebSock::OnLogin(const CString& sUser, const CString& sPass,
bool bBasic) {
DEBUG("=================== CWebSock::OnLogin(), basic auth? "