X-Forwarded-For: verify the whole chain, from the end

This commit is contained in:
Alexey Sokolov
2013-11-14 22:22:32 +04:00
parent ccbc469168
commit 3e56f093f2
6 changed files with 59 additions and 36 deletions

View File

@@ -128,7 +128,37 @@ void CHTTPSock::ReadLine(const CString& sData) {
if (m_uPostLen > MAX_POST_SIZE)
PrintErrorPage(413, "Request Entity Too Large", "The request you sent was too large.");
} else if (sName.Equals("X-Forwarded-For:")) {
m_sForwardedIP = sLine.Token(1).TrimRight_n(",");
// X-Forwarded-For: client, proxy1, proxy2
if (m_sForwardedIP.empty()) {
const VCString& vsTrustedProxies = CZNC::Get().GetTrustedProxies();
CString sIP = GetRemoteIP();
VCString vsIPs;
sLine.Token(1, true).Split(",", vsIPs, false, "", "", false, true);
while (!vsIPs.empty()) {
// sIP told us that it got connection from vsIPs.back()
// check if sIP is trusted proxy
bool bTrusted = false;
for (VCString::const_iterator it = vsTrustedProxies.begin(); it != vsTrustedProxies.end(); ++it) {
if (sIP.WildCmp(*it)) {
bTrusted = true;
break;
}
}
if (bTrusted) {
// sIP is trusted proxy, so use vsIPs.back() as new sIP
sIP = vsIPs.back();
vsIPs.pop_back();
} else {
break;
}
}
// either sIP is not trusted proxy, or it's in the beginning of the X-Forwarded-For list
// in both cases use it as the endpoind
m_sForwardedIP = sIP;
}
} else if (sName.Equals("If-None-Match:")) {
// this is for proper client cache support (HTTP 304) on static files:
m_sIfNoneMatch = sLine.Token(1, true);
@@ -151,6 +181,14 @@ void CHTTPSock::ReadLine(const CString& sData) {
}
}
CString CHTTPSock::GetRemoteIP() {
if (!m_sForwardedIP.empty()) {
return m_sForwardedIP;
}
return CSocket::GetRemoteIP();
}
CString CHTTPSock::GetDate(time_t stamp) {
struct tm tm;
std::stringstream stream;