CVE-2021-21431: Other (NVD-CWE-Other)
value: sopel-channelmgnt is a channelmgnt plugin for sopel. In versions prior to 2.0.1, on some IRC servers, restrictions around the removal of the bot using the kick/kickban command could be bypassed when kicking multiple users at once. We also believe it may have been possible to remove users from other channels but due to the wonder that is IRC and following RfCs, We have no POC for that. Freenode is not affected. This is fixed in version 2.0.1. As a workaround, do not use this plugin on networks where TARGMAX > 1.
CWE description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
CVSS v3 base score: 8.1
Published: 2021-04-09T16:15Z
Repository: https://github.com/MirahezeBots/sopel-channelmgnt
Language: Python
Files changed: dev-requirements.txt, setup.py, sopel_channelmgnt/channelmgnt/__init__.py
Commit date: 2021-04-08 18:21:42 +0100
Commit message: [SECURITY] Release 2.0.1 (#65)

Fixes CVE-2021-21431
Diff: diff --git a/dev-requirements.txt b/dev-requirements.txt
index 586ff0a..2afd463 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -13,11 +13,11 @@ flake8-comprehensions==3.3.1
 flake8-eradicate==1.0.0
 flake8-fixme==1.1.1
 flake8-multiline-containers==0.0.17
 flake8-print==4.0.0
 flake8-pytest-style==1.3.0
-flake8-return==1.1.2
+#flake8-return==1.1.2
 flake8-quotes==3.2.0
 flake8-simplify==0.13.0
 flake8-pytest==1.3
 pipdeptree==2.0.0
 packaging>=20.8
diff --git a/setup.py b/setup.py
index 9b8eb35..c94a255 100644
--- a/setup.py
+++ b/setup.py
@@ -8,16 +8,16 @@ with open('requirements.txt') as requirements_file:
     requirements = list(requirements_file.readlines())
 
 
 setup(
     name='sopel_plugins.channelmgnt',
-    version='2.0',
+    version='2.0.1',
     description='Channelmgnt plugin for Sopel',
     long_description=readme,
     long_description_content_type='text/markdown',  # This is important!
     author='MirahezeBot Contributors',
-    author_email='bots@miraheze.org',
+    author_email='staff@mirahezebots.org',
     url='https://github.com/MirahezeBots/sopel-channelmgnt',
     packages=find_packages('.'),
     include_package_data=True,
     install_requires=requirements,
     license='Eiffel Forum License, version 2',
diff --git a/sopel_channelmgnt/channelmgnt/__init__.py b/sopel_channelmgnt/channelmgnt/__init__.py
index 2ff180f..35d3553 100644
--- a/sopel_channelmgnt/channelmgnt/__init__.py
+++ b/sopel_channelmgnt/channelmgnt/__init__.py
@@ -214,10 +214,14 @@ def kick(bot, trigger):
         argc = len(text)
         if argc < 2:
             return
         nick = Identifier(text[1])
         reason = ' '.join(text[2:])
+        if ',' in str(nick):
+            return bot.reply('Unable to kick. Kicking multiple users is not allowed.')
+        if '#' in str(nick):
+            return bot.reply('Unable to kick. Use of # when kicking is not expected.')
         if nick != bot.config.core.nick and trigger.account in chanops:
             bot.write(['KICK', trigger.sender, nick, ':' + reason])
             if dodeop:
                 deopbot(trigger.sender, bot)
         else:
@@ -261,18 +265,26 @@ def parse_host_mask(text):
 @commands('ban')
 @priority('high')
 @example('.ban Zppix')
 def ban(bot, trigger):
     """Ban a user from the channel. The bot must be a channel operator for this command to work."""
+    if ',' in str(parse_host_mask(trigger.group().split())):
+        return bot.reply('Unable to ban. Banning multiple users is not allowed.')
+    if '#' in str(parse_host_mask(trigger.group().split())):
+        return bot.reply('Unable to ban. Use of # when banning is not expected.')
     makemodechange(bot, trigger, '+b', isbqmode=True)
 
 
 @require_chanmsg
 @commands('unban')
 @example('.unban Zppix')
 def unban(bot, trigger):
     """Unban a user from the channel. The bot must be a channel operator for this command to work."""
+    if ',' in str(parse_host_mask(trigger.group().split())):
+        return bot.reply('Unable to ban. Banning multiple users is not allowed.')
+    if '#' in str(parse_host_mask(trigger.group().split())):
+        return bot.reply('Unable to ban. Use of # when banning is not expected.')
     makemodechange(bot, trigger, '-b', isbqmode=True)
 
 
 @require_chanmsg
 @commands('quiet')
@@ -310,10 +322,14 @@ def kickban(bot, trigger):
             bot.reply('Syntax is: .kickban <nick> <reason>')
             if dodeop:
                 deopbot(trigger.sender, bot)
             return
         nick = Identifier(text[1])
+        if ',' in str(nick):
+            return bot.reply('Unable to kickban. Kickbanning multiple users is not allowed.')
+        if '#' in str(nick):
+            return bot.reply('Unable to kickban. Use of # when kickbanning is not expected.')
         mask = text[2] if any(s in text[2] for s in '!@*') else ''
         reasonidx = 3 if mask != '' else 2
         reason = ' '.join(text[reasonidx:])
         mask = parse_host_mask(trigger.group().split())
         if mask == '':

Vulnerable code: flake8-return==1.1.2
    version='2.0',
    author_email='bots@miraheze.org',
Fixed code: #flake8-return==1.1.2
    version='2.0.1',
    author_email='staff@mirahezebots.org',
        if ',' in str(nick):
            return bot.reply('Unable to kick. Kicking multiple users is not allowed.')
        if '#' in str(nick):
            return bot.reply('Unable to kick. Use of # when kicking is not expected.')
    if ',' in str(parse_host_mask(trigger.group().split())):
        return bot.reply('Unable to ban. Banning multiple users is not allowed.')
    if '#' in str(parse_host_mask(trigger.group().split())):
        return bot.reply('Unable to ban. Use of # when banning is not expected.')
    if ',' in str(parse_host_mask(trigger.group().split())):
        return bot.reply('Unable to ban. Banning multiple users is not allowed.')
    if '#' in str(parse_host_mask(trigger.group().split())):
        return bot.reply('Unable to ban. Use of # when banning is not expected.')
        if ',' in str(nick):
            return bot.reply('Unable to kickban. Kickbanning multiple users is not allowed.')
        if '#' in str(nick):
            return bot.reply('Unable to kickban. Use of # when kickbanning is not expected.')