bouncedcc: refuse DCC requests from IRC aimed at loopback or link-local
The address in an incoming DCC CHAT/SEND is chosen by the remote IRC user, and ZNC is the side that connects to it, relaying traffic to whoever connects to the bounce listener. Refuse requests that point at 0/8, 127/8, 169.254/16, 224/3 or values above 32 bits (which CUtils::GetIP would otherwise mask down to one of those).
This commit is contained in:
1 parent
3d96465fc0
commit
8aef9873fc
2 files changed
+26
No files matched your search
@@ -163,6 +163,17 @@ class CBounceDCCMod : public CModule {
|
||||
|
||||
bool UseClientIP() { return GetNV("UseClientIP").ToBool(); }
|
||||
|
||||
// The address in a DCC request from IRC is chosen by the remote peer, and
|
||||
// ZNC is the one connecting to it, so don't let it point at ZNC's own
|
||||
// host or at link-local services.
|
||||
static bool IsAllowedPeerIP(unsigned long uLongIP) {
|
||||
if (uLongIP > 0xFFFFFFFFUL) return false;
|
||||
const unsigned long uFirst = uLongIP >> 24;
|
||||
if (uFirst == 0 || uFirst == 127 || uFirst >= 224) return false;
|
||||
if ((uLongIP >> 16) == 0xA9FE) return false; // 169.254.0.0/16
|
||||
return true;
|
||||
}
|
||||
|
||||
EModRet OnUserCTCPMessage(CCTCPMessage& Message) override {
|
||||
CString sTarget = Message.GetTarget();
|
||||
CString sMessage = Message.GetText();
|
||||
@@ -255,6 +266,13 @@ class CBounceDCCMod : public CModule {
|
||||
unsigned long uFileSize = sMessage.Token(5, false, " ", false, "\"",
|
||||
"\"", true).ToULong();
|
||||
|
||||
if ((sType.Equals("CHAT") || sType.Equals("SEND")) &&
|
||||
!IsAllowedPeerIP(uLongIP)) {
|
||||
PutModule(t_f("DCC {1} from {2} refused: bad address {3}")(
|
||||
sType, Nick.GetNick(), CString(uLongIP)));
|
||||
return HALTCORE;
|
||||
}
|
||||
|
||||
if (sType.Equals("CHAT")) {
|
||||
CNick FromNick(Nick.GetNickMask());
|
||||
unsigned short uBNCPort = CDCCBounce::DCCRequest(
|
||||
|
||||
Reference in new issue
Block a user