From 0a99a9f404cd33145930451de3bf185100274606 Mon Sep 17 00:00:00 2001 From: psychon Date: Sun, 25 Apr 2010 14:09:23 +0000 Subject: [PATCH] HTTPSock: Split up parameter access Every function on CHTTPSock which works with request parameters now has a new flag bool bPost which decides whether only POST or GET parameters should be used. This breaks everything which tries to access GET parameters, but once this is fixed we should be pretty safe against CSRF. git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@1935 726aef4b-f618-498e-8847-2d620e286838 --- HTTPSock.cpp | 68 ++++++++++++++++++++++++++++++++++++---------------- HTTPSock.h | 25 ++++++++++++------- 2 files changed, 65 insertions(+), 28 deletions(-) diff --git a/HTTPSock.cpp b/HTTPSock.cpp index 43fa5c34..575fafd1 100644 --- a/HTTPSock.cpp +++ b/HTTPSock.cpp @@ -66,7 +66,7 @@ CString CHTTPSock::GetRequestCookie(const CString& sKey) const { void CHTTPSock::CheckPost() { if (m_sPostData.size() >= m_uPostLen) { - ParseParams(m_sPostData.Left(m_uPostLen)); + ParseParams(m_sPostData.Left(m_uPostLen), m_msvsPOSTParams); GetPage(); m_sPostData.clear(); m_bDone = true; @@ -245,7 +245,7 @@ bool CHTTPSock::PrintFile(const CString& sFileName, CString sContentType) { } void CHTTPSock::ParseURI() { - ParseParams(m_sURI.Token(1, true, "?")); + ParseParams(m_sURI.Token(1, true, "?"), m_msvsGETParams); m_sURI = m_sURI.Token(0, false, "?"); } @@ -253,8 +253,8 @@ CString CHTTPSock::GetPath() const { return m_sURI.Token(0, false, "?"); } -void CHTTPSock::ParseParams(const CString& sParams) { - m_msvsParams.clear(); +void CHTTPSock::ParseParams(const CString& sParams, map &msvsParams) { + msvsParams.clear(); VCString vsPairs; sParams.Split("&", vsPairs, true); @@ -264,7 +264,7 @@ void CHTTPSock::ParseParams(const CString& sParams) { CString sName = sPair.Token(0, false, "=").Escape_n(CString::EURL, CString::EASCII); CString sValue = sPair.Token(1, true, "=").Escape_n(CString::EURL, CString::EASCII); - m_msvsParams[sName].push_back(sValue); + msvsParams[sName].push_back(sValue); } } @@ -293,24 +293,38 @@ const CString& CHTTPSock::GetParamString() const { return m_sPostData; } -bool CHTTPSock::HasParam(const CString& sName) const { - return (m_msvsParams.find(sName) != m_msvsParams.end()); +bool CHTTPSock::HasParam(const CString& sName, bool bPost) const { + if (bPost) + return (m_msvsPOSTParams.find(sName) != m_msvsPOSTParams.end()); + return (m_msvsGETParams.find(sName) != m_msvsGETParams.end()); } -CString CHTTPSock::GetRawParam(const CString& sName) const { +CString CHTTPSock::GetRawParam(const CString& sName, bool bPost) const { + if (bPost) + return GetRawParam(sName, m_msvsPOSTParams); + return GetRawParam(sName, m_msvsGETParams); +} + +CString CHTTPSock::GetRawParam(const CString& sName, const map& msvsParams) { CString sRet; - map::const_iterator it = m_msvsParams.find(sName); + map::const_iterator it = msvsParams.find(sName); - if (it != m_msvsParams.end() && it->second.size() > 0) { + if (it != msvsParams.end() && it->second.size() > 0) { sRet = it->second[0]; } return sRet; } -CString CHTTPSock::GetParam(const CString& sName, const CString& sFilter) const { - CString sRet = GetRawParam(sName); +CString CHTTPSock::GetParam(const CString& sName, bool bPost, const CString& sFilter) const { + if (bPost) + return GetParam(sName, m_msvsPOSTParams, sFilter); + return GetParam(sName, m_msvsGETParams, sFilter); +} + +CString CHTTPSock::GetParam(const CString& sName, const map& msvsParams, const CString& sFilter) { + CString sRet = GetRawParam(sName, msvsParams); for (size_t i = 0; i < sFilter.length(); i++) { sRet.Replace(CString(sFilter.at(i)), ""); @@ -319,12 +333,18 @@ CString CHTTPSock::GetParam(const CString& sName, const CString& sFilter) const return sRet; } -unsigned int CHTTPSock::GetParamValues(const CString& sName, set& ssRet, const CString& sFilter) const { +unsigned int CHTTPSock::GetParamValues(const CString& sName, set& ssRet, bool bPost, const CString& sFilter) const { + if (bPost) + return GetParamValues(sName, ssRet, m_msvsPOSTParams, sFilter); + return GetParamValues(sName, ssRet, m_msvsGETParams, sFilter); +} + +unsigned int CHTTPSock::GetParamValues(const CString& sName, set& ssRet, const map& msvsParams, const CString& sFilter) { ssRet.clear(); - map::const_iterator it = m_msvsParams.find(sName); + map::const_iterator it = msvsParams.find(sName); - if (it != m_msvsParams.end()) { + if (it != msvsParams.end()) { for (unsigned int a = 0; a < it->second.size(); a++) { CString sParam = it->second[a]; @@ -338,12 +358,18 @@ unsigned int CHTTPSock::GetParamValues(const CString& sName, set& ssRet return ssRet.size(); } -unsigned int CHTTPSock::GetParamValues(const CString& sName, VCString& vsRet, const CString& sFilter) const { +unsigned int CHTTPSock::GetParamValues(const CString& sName, VCString& vsRet, bool bPost, const CString& sFilter) const { + if (bPost) + return GetParamValues(sName, vsRet, m_msvsPOSTParams, sFilter); + return GetParamValues(sName, vsRet, m_msvsGETParams, sFilter); +} + +unsigned int CHTTPSock::GetParamValues(const CString& sName, VCString& vsRet, const map& msvsParams, const CString& sFilter) { vsRet.clear(); - map::const_iterator it = m_msvsParams.find(sName); + map::const_iterator it = msvsParams.find(sName); - if (it != m_msvsParams.end()) { + if (it != msvsParams.end()) { for (unsigned int a = 0; a < it->second.size(); a++) { CString sParam = it->second[a]; @@ -357,8 +383,10 @@ unsigned int CHTTPSock::GetParamValues(const CString& sName, VCString& vsRet, co return vsRet.size(); } -const map& CHTTPSock::GetParams() const { - return m_msvsParams; +const map& CHTTPSock::GetParams(bool bPost) const { + if (bPost) + return m_msvsPOSTParams; + return m_msvsGETParams; } bool CHTTPSock::IsPost() const { diff --git a/HTTPSock.h b/HTTPSock.h index 3dcfd213..fc6325f7 100644 --- a/HTTPSock.h +++ b/HTTPSock.h @@ -47,7 +47,7 @@ public: bool Redirect(const CString& sURL); CString GetErrorPage(unsigned int uStatusId, const CString& sStatusMsg, const CString& sMessage); bool PrintErrorPage(unsigned int uStatusId, const CString& sStatusMsg, const CString& sMessage); - void ParseParams(const CString& sParams); + static void ParseParams(const CString& sParams, map& msvsParams); void ParseURI(); void GetPage(); @@ -63,9 +63,6 @@ public: // !Setters // Getters - bool HasParam(const CString& sName) const; - CString GetRawParam(const CString& sName) const; - CString GetParam(const CString& sName, const CString& sFilter = "\r\n") const; CString GetPath() const; bool IsLoggedIn() const { return m_bLoggedIn; } const CString& GetDocRoot() const; @@ -73,12 +70,23 @@ public: const CString& GetPass() const; const CString& GetParamString() const; const CString& GetContentType() const; - 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 + + // Parameter access + CString GetParam(const CString& sName, bool bPost = true, const CString& sFilter = "\r\n") const; + CString GetRawParam(const CString& sName, bool bPost = true) const; + bool HasParam(const CString& sName, bool bPost = true) const; + const map& GetParams(bool bPost = true) const; + unsigned int GetParamValues(const CString& sName, VCString& vsRet, bool bPost = true, const CString& sFilter = "\r\n") const; + unsigned int GetParamValues(const CString& sName, set& ssRet, bool bPost = true, const CString& sFilter = "\r\n") const; + // !Parameter access private: + static CString GetRawParam(const CString& sName, const map& msvsParams); + static CString GetParam(const CString& sName, const map& msvsParams, const CString& sFilter); + static unsigned int GetParamValues(const CString& sName, VCString& vsRet, const map& msvsParams, const CString& sFilter); + static unsigned int GetParamValues(const CString& sName, set& ssRet, const map& msvsParams, const CString& sFilter); + protected: void PrintPage(const CString& sPage); void Init(); @@ -95,7 +103,8 @@ protected: CString m_sPass; CString m_sContentType; CString m_sDocRoot; - map m_msvsParams; + map m_msvsPOSTParams; + map m_msvsGETParams; MCString m_msHeaders; bool m_bHTTP10Client; CString m_sIfNoneMatch;