Aka: Proper mitigation of expansion bomb.

This commit is contained in:
Valentin Lorentz 2017-04-17 11:05:04 +02:00
parent 3075a41a3b
commit 7f43727835
2 changed files with 15 additions and 7 deletions

View File

@ -448,8 +448,13 @@ class Aka(callbacks.Plugin):
if biggestDollar or biggestAt:
args = getArgs(args, required=biggestDollar, optional=biggestAt,
wildcard=wildcard)
max_len = conf.supybot.reply.maximumLength()
args = list([x[:max_len] for x in args])
remaining_len = conf.supybot.reply.maximumLength()
for (i, arg) in enumerate(args):
if remaining_len < len(arg):
arg = arg[0:remaining_len]
args[i+1:] = []
break
remaining_len -= len(arg)
def regexpReplace(m):
idx = int(m.group(1))
return args[idx-1]
@ -462,7 +467,6 @@ class Aka(callbacks.Plugin):
replace(tokens, lambda s: dollarRe.sub(regexpReplace, s))
if biggestAt:
assert not wildcard
args = args[biggestDollar:]
replace(tokens, lambda s: atRe.sub(regexpReplace, s))
if wildcard:
assert not biggestAt
@ -488,7 +492,7 @@ class Aka(callbacks.Plugin):
if maxNesting and irc.nested+1 > maxNesting:
irc.error(_('You\'ve attempted more nesting than is '
'currently allowed on this bot.'), Raise=True)
self.Proxy(irc, msg, tokens)
self.Proxy(irc, msg, tokens, nested=irc.nested+1)
if biggestDollar and (wildcard or biggestAt):
flexargs = _(' at least')
else:
@ -520,9 +524,6 @@ class Aka(callbacks.Plugin):
wildcard = '$*' in alias
if biggestAt and wildcard:
raise AkaError(_('Can\'t mix $* and optional args (@1, etc.)'))
if alias.count('$*') > 3:
# mitigate huge expansions
raise AkaError(_('There can be only three $* in an alias.'))
self._db.add_aka(channel, name, alias)
def _remove_aka(self, channel, name, evenIfLocked=False):

View File

@ -108,6 +108,13 @@ class AkaChannelTestCase(ChannelPluginTestCase):
self.assertResponse('doublespam egg', 'egg egg')
self.assertResponse('doublespam egg bacon', 'egg bacon egg bacon')
def testExpansionBomb(self):
self.assertNotError('aka add bomb "bomb $* $* $* $* $*"')
# if the mitigation doesn't work, this test will eat all memory on the
# system.
self.assertResponse('bomb foo', "Error: You've attempted more nesting "
"than is currently allowed on this bot.")
def testChannel(self):
self.assertNotError('aka add channel echo $channel')
self.assertResponse('aka channel', self.channel)