From 5f8b5e1a0f23fe0f2be5b3c3e04199b57a53db5b Mon Sep 17 00:00:00 2001 From: Erik Johnson Date: Fri, 25 Aug 2017 14:15:58 -0500 Subject: [PATCH] Do not allow IDs with null bytes in decoded payloads --- salt/crypt.py | 3 +++ salt/transport/tcp.py | 11 +++++++++++ salt/transport/zeromq.py | 11 +++++++++++ 3 files changed, 25 insertions(+) diff --git a/salt/crypt.py b/salt/crypt.py index f4f65940d595..ef4e7645d23c 100644 --- a/salt/crypt.py +++ b/salt/crypt.py @@ -607,6 +607,9 @@ def sign_in(self, timeout=60, safe=True, tries=1, channel=None): raise tornado.gen.Return('retry') else: raise SaltClientError('Attempt to authenticate with the salt master failed with timeout error') + if not isinstance(payload, dict): + log.error('Sign-in attempt failed: %s', payload) + raise tornado.gen.Return(False) if 'load' in payload: if 'ret' in payload['load']: if not payload['load']['ret']: diff --git a/salt/transport/tcp.py b/salt/transport/tcp.py index a9001f03a5ce..f274240a1ebc 100644 --- a/salt/transport/tcp.py +++ b/salt/transport/tcp.py @@ -623,6 +623,17 @@ def handle_message(self, stream, header, payload): 'payload and load must be a dict', header=header)) raise tornado.gen.Return() + try: + id_ = payload['load'].get('id', '') + if '\0' in id_: + log.error('Payload contains an id with a null byte: %s', payload) + stream.send(self.serial.dumps('bad load: id contains a null byte')) + raise tornado.gen.Return() + except TypeError: + log.error('Payload contains non-string id: %s', payload) + stream.send(self.serial.dumps('bad load: id {0} is not a string'.format(id_))) + raise tornado.gen.Return() + # intercept the "_auth" commands, since the main daemon shouldn't know # anything about our key auth if payload['enc'] == 'clear' and payload.get('load', {}).get('cmd') == '_auth': diff --git a/salt/transport/zeromq.py b/salt/transport/zeromq.py index 1bb3abebe1da..2be6c829f350 100644 --- a/salt/transport/zeromq.py +++ b/salt/transport/zeromq.py @@ -596,6 +596,17 @@ def handle_message(self, stream, payload): stream.send(self.serial.dumps('payload and load must be a dict')) raise tornado.gen.Return() + try: + id_ = payload['load'].get('id', '') + if '\0' in id_: + log.error('Payload contains an id with a null byte: %s', payload) + stream.send(self.serial.dumps('bad load: id contains a null byte')) + raise tornado.gen.Return() + except TypeError: + log.error('Payload contains non-string id: %s', payload) + stream.send(self.serial.dumps('bad load: id {0} is not a string'.format(id_))) + raise tornado.gen.Return() + # intercept the "_auth" commands, since the main daemon shouldn't know # anything about our key auth if payload['enc'] == 'clear' and payload.get('load', {}).get('cmd') == '_auth':