diff --git a/HTTPSock.cpp b/HTTPSock.cpp index 4c83ab41..43fa5c34 100644 --- a/HTTPSock.cpp +++ b/HTTPSock.cpp @@ -361,6 +361,10 @@ const map& CHTTPSock::GetParams() const { return m_msvsParams; } +bool CHTTPSock::IsPost() const { + return m_bPost; +} + bool CHTTPSock::PrintNotFound() { return PrintErrorPage(404, "Not Found", "The requested URL was not found on this server."); } diff --git a/HTTPSock.h b/HTTPSock.h index 97664ef2..3dcfd213 100644 --- a/HTTPSock.h +++ b/HTTPSock.h @@ -76,6 +76,7 @@ public: unsigned int GetParamValues(const CString& sName, VCString& vsRet, const CString& sFilter = "\r\n") const; unsigned int GetParamValues(const CString& sName, set& ssRet, const CString& sFilter = "\r\n") const; const map& GetParams() const; + bool IsPost() const; // !Getters private: protected: diff --git a/WebModules.cpp b/WebModules.cpp index 0d5906ff..7ea73271 100644 --- a/WebModules.cpp +++ b/WebModules.cpp @@ -518,6 +518,16 @@ void CWebSock::OnPageRequest(const CString& sURI) { } CWebSock::EPageReqResult CWebSock::OnPageRequestInternal(const CString& sURI, CString& sPageRet) { + // Check that they really POSTed from one our forms by checking if they + // 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") { + sPageRet = GetErrorPage(403, "Access denied", "POST requests need to send " + "a secret token to prevent cross-site request forgery attacks."); + return PAGE_PRINT; + } + SendCookie("SessionId", GetSession()->GetId()); if (GetSession()->IsLoggedIn()) { @@ -714,6 +724,11 @@ CSmartPtr CWebSock::GetSession() { return spSession; } +CString CWebSock::GetCSRFCheck() { + CSmartPtr pSession = GetSession(); + return pSession->GetId().MD5(); +} + bool CWebSock::OnLogin(const CString& sUser, const CString& sPass) { DEBUG("=================== CWebSock::OnLogin()"); m_spAuth = new CWebAuth(this, sUser, sPass); diff --git a/WebModules.h b/WebModules.h index 59f44939..c7876c06 100644 --- a/WebModules.h +++ b/WebModules.h @@ -147,6 +147,7 @@ public: void PrintErrorPage(const CString& sMessage); CSmartPtr GetSession(); + CString GetCSRFCheck(); virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort); CString GetModWebPath(const CString& sModName) const;