From: <ps...@us...> - 2009-02-24 16:00:14
|
Revision: 1395 http://znc.svn.sourceforge.net/znc/?rev=1395&view=rev Author: psychon Date: 2009-02-24 16:00:11 +0000 (Tue, 24 Feb 2009) Log Message: ----------- Handle newlines in CHTTPSock::GetParam() and strip them out. There was a bug in webadmin which allowed any users to write arbitrary strings to znc.conf by setting e.g. their quit message to: Some quit message Admin = true LoadModule = shell </User> ISpoofFile = /home/<user>/.ssh/authorited_keys ISpoofFormat = <some ssh key> <User a> (The newlines must be sent as newlines to webadmin) This commit fixes this by stripping all newlines from all the data fields by default. Since some fields (e.g. CTCPReplies and Servers) do need newlines, there is a new function CHTTPSock::GetRawParam() which doesn't do the stripping. Thanks to cnu for finding and reporting this bug. Thanks to kroimon for patch review. Modified Paths: -------------- trunk/HTTPSock.cpp trunk/HTTPSock.h trunk/modules/webadmin.cpp Modified: trunk/HTTPSock.cpp =================================================================== --- trunk/HTTPSock.cpp 2009-02-24 15:52:43 UTC (rev 1394) +++ trunk/HTTPSock.cpp 2009-02-24 16:00:11 UTC (rev 1395) @@ -259,38 +259,61 @@ return (m_msvsParams.find(sName) != m_msvsParams.end()); } -CString CHTTPSock::GetParam(const CString& sName) const { +CString CHTTPSock::GetRawParam(const CString& sName) const { CString sRet; - VCString vsParams; - if (GetParamValues(sName, vsParams)) { - sRet = vsParams[0]; + map<CString, VCString>::const_iterator it = m_msvsParams.find(sName); + + if (it != m_msvsParams.end() && it->second.size() > 0) { + sRet = it->second[0]; } return sRet; } -unsigned int CHTTPSock::GetParamValues(const CString& sName, set<CString>& ssRet) const { +CString CHTTPSock::GetParam(const CString& sName, const CString& sFilter) const { + CString sRet = GetRawParam(sName); + + for (size_t i = 0; i < sFilter.length(); i++) { + sRet.Replace(CString(sFilter.at(i)), ""); + } + + return sRet; +} + +unsigned int CHTTPSock::GetParamValues(const CString& sName, set<CString>& ssRet, const CString& sFilter) const { ssRet.clear(); map<CString, VCString>::const_iterator it = m_msvsParams.find(sName); if (it != m_msvsParams.end()) { for (unsigned int a = 0; a < it->second.size(); a++) { - ssRet.insert(it->second[a]); + CString sParam = it->second[a]; + + for (size_t i = 0; i < sFilter.length(); i++) { + sParam.Replace(CString(sFilter.at(i)), ""); + } + ssRet.insert(sParam); } } return ssRet.size(); } -unsigned int CHTTPSock::GetParamValues(const CString& sName, VCString& vsRet) const { +unsigned int CHTTPSock::GetParamValues(const CString& sName, VCString& vsRet, const CString& sFilter) const { vsRet.clear(); map<CString, VCString>::const_iterator it = m_msvsParams.find(sName); if (it != m_msvsParams.end()) { - vsRet = it->second; + for (unsigned int a = 0; a < it->second.size(); a++) { + CString sParam = it->second[a]; + + for (size_t i = 0; i < sFilter.length(); i++) { + sParam.Replace(CString(sFilter.at(i)), ""); + } + vsRet.push_back(sParam); + } } return vsRet.size(); Modified: trunk/HTTPSock.h =================================================================== --- trunk/HTTPSock.h 2009-02-24 15:52:43 UTC (rev 1394) +++ trunk/HTTPSock.h 2009-02-24 16:00:11 UTC (rev 1395) @@ -58,15 +58,16 @@ // Getters bool HasParam(const CString& sName) const; - CString GetParam(const CString& sName) const; + CString GetRawParam(const CString& sName) const; + CString GetParam(const CString& sName, const CString& sFilter = "\r\n") const; bool IsLoggedIn() const { return m_bLoggedIn; } const CString& GetDocRoot() const; const CString& GetUser() const; const CString& GetPass() const; const CString& GetParamString() const; const CString& GetContentType() const; - unsigned int GetParamValues(const CString& sName, VCString& vsRet) const; - unsigned int GetParamValues(const CString& sName, set<CString>& ssRet) const; + unsigned int GetParamValues(const CString& sName, VCString& vsRet, const CString& sFilter = "\r\n") const; + unsigned int GetParamValues(const CString& sName, set<CString>& ssRet, const CString& sFilter = "\r\n") const; const map<CString, VCString>& GetParams() const; // !Getters private: Modified: trunk/modules/webadmin.cpp =================================================================== --- trunk/modules/webadmin.cpp 2009-02-24 15:52:43 UTC (rev 1394) +++ trunk/modules/webadmin.cpp 2009-02-24 16:00:11 UTC (rev 1395) @@ -614,7 +614,7 @@ //sArg = GetParam(""); if (!sArg.empty()) { CZNC::Get().Set(sArg); } VCString vsArgs; - GetParam("motd").Split("\n", vsArgs); + GetRawParam("motd").Split("\n", vsArgs); CZNC::Get().ClearMotd(); unsigned int a = 0; @@ -622,7 +622,7 @@ CZNC::Get().AddMotd(vsArgs[a].TrimRight_n()); } - GetParam("vhosts").Split("\n", vsArgs); + GetRawParam("vhosts").Split("\n", vsArgs); CZNC::Get().ClearVHosts(); for (a = 0; a < vsArgs.size(); a++) { @@ -1044,14 +1044,14 @@ } VCString vsArgs; - GetParam("servers").Split("\n", vsArgs); + GetRawParam("servers").Split("\n", vsArgs); unsigned int a = 0; for (a = 0; a < vsArgs.size(); a++) { pNewUser->AddServer(vsArgs[a].Trim_n()); } - GetParam("allowedips").Split("\n", vsArgs); + GetRawParam("allowedips").Split("\n", vsArgs); if (vsArgs.size()) { for (a = 0; a < vsArgs.size(); a++) { pNewUser->AddAllowedHost(vsArgs[a].Trim_n()); @@ -1064,7 +1064,7 @@ pNewUser->AddAllowedHost(GetParam("ownip")); } - GetParam("ctcpreplies").Split("\n", vsArgs); + GetRawParam("ctcpreplies").Split("\n", vsArgs); for (a = 0; a < vsArgs.size(); a++) { CString sReply = vsArgs[a].TrimRight_n("\r"); pNewUser->AddCTCPReply(sReply.Token(0).Trim_n(), sReply.Token(1, true).Trim_n()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |