Improper Input Validation in sopel-plugins.channelmgnt
Description
In sopel-channelmgnt prior to 2.0.1, an IRC bot operator could bypass kick/ban restrictions by using a comma or # to target multiple users, potentially removing the bot or users from other channels.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
In sopel-channelmgnt prior to 2.0.1, an IRC bot operator could bypass kick/ban restrictions by using a comma or # to target multiple users, potentially removing the bot or users from other channels.
Vulnerability
In the sopel-channelmgnt plugin for the Sopel IRC bot, versions prior to 2.0.1, the kick and ban commands did not properly validate user input. An attacker could include a comma (,) or a hash (#) in the target argument, causing the bot to attempt to kick or ban multiple users at once or target a different channel. This bypasses the intended restriction that prevents the bot from being removed via these commands. The issue is triggered only on IRC networks where the TARGMAX parameter is greater than 1, as stated in [1].
Exploitation
To exploit this vulnerability, an attacker must have operator privileges (flag +o) in the channel where the bot resides. The attacker issues a command such as .kick <bot_nick>,<other_nick> or .ban # to the bot. The bot's code in the vulnerable versions accepted these malformed arguments without checking for commas or hashes, and wrote the corresponding IRC KICK or BAN command to the server. This is evident from the fix commit [2], which adds checks to reject such inputs. No race condition or additional user interaction is required beyond the attacker having operator status.
Impact
Successful exploitation allows an attacker to remove the bot from the channel (e.g., by kicking itself) and potentially remove other users. The advisory [1] also notes the possibility, without a proof of concept, of removing users from other channels by including a channel name in the target. This could lead to disruption of channel management and abuse of operator privileges. Freenode IRC network was not affected [1].
Mitigation
The vulnerability is fixed in version 2.0.1 of sopel-channelmgnt, released on April 9, 2021 [1]. The fix adds input validation to reject target strings containing commas or hashes [2]. As a workaround, the plugin should not be used on IRC networks where TARGMAX > 1 [1]. The repository has since been archived [3], but users should update to the patched version or apply the workaround.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
sopel-plugins.channelmgntPyPI | < 2.0.1 | 2.0.1 |
Affected products
2- Range: < 2.0.1
Patches
27c96d4003582[SECURITY] Release 2.0.1 (#65)
3 files changed · +19 −3
dev-requirements.txt+1 −1 modified@@ -15,7 +15,7 @@ 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
setup.py+2 −2 modified@@ -10,12 +10,12 @@ 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,
sopel_channelmgnt/channelmgnt/__init__.py+16 −0 modified@@ -216,6 +216,10 @@ def kick(bot, trigger): 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: @@ -263,6 +267,10 @@ def parse_host_mask(text): @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) @@ -271,6 +279,10 @@ def ban(bot, trigger): @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) @@ -312,6 +324,10 @@ def kickban(bot, trigger): 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:])
643388365f28Merge pull request from GHSA-23c7-6444-399m
1 file changed · +12 −0
sopel_channelmgnt/channelmgnt/__init__.py+12 −0 modified@@ -216,6 +216,10 @@ def kick(bot, trigger): 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: @@ -263,6 +267,10 @@ def parse_host_mask(text): @example('.ban nick') 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(nick): + return bot.reply('Unable to ban. Banning multiple users is not allowed.') + if '#' in str(nick): + return bot.reply('Unable to ban. Use of # when banning is not expected.') makemodechange(bot, trigger, '+b', isbqmode=True) @@ -312,6 +320,10 @@ def kickban(bot, trigger): 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:])
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-23c7-6444-399mghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2021-21431ghsaADVISORY
- github.com/MirahezeBots/sopel-channelmgnt/commit/643388365f28c5cc682254ab913c401f0e53260aghsaWEB
- github.com/MirahezeBots/sopel-channelmgnt/commit/7c96d400358221e59135f0a0be0744f3fad73856ghsax_refsource_MISCWEB
- github.com/MirahezeBots/sopel-channelmgnt/security/advisories/GHSA-23c7-6444-399mghsax_refsource_CONFIRMWEB
- github.com/pypa/advisory-database/tree/main/vulns/sopel-plugins-channelmgnt/PYSEC-2021-58.yamlghsaWEB
- pypi.org/project/sopel-plugins.channelmgntghsaWEB
- pypi.org/project/sopel-plugins.channelmgnt/mitrex_refsource_MISC
News mentions
0No linked articles in our index yet.