CVE-2016-6903: Permissions, Privileges, and Access Controls (CWE-264)
value: lshell 0.9.16 allows remote authenticated users to break out of a limited shell and execute arbitrary commands.
CWE description: Weaknesses in this category are related to the management of permissions, privileges, and other security features that are used to perform access control.
CVSS v3 base score: 9.9
Published: 2017-04-24T19:59Z
Repository: https://github.com/ghantoos/lshell
Language: Python
Files changed: lshell/sec.py, test/test_functional.py
Commit date: 2016-08-21 22:01:52 -0400
Commit message: [security] MAJOR issue: catch ctrl escapes (Closes #149)

The was a major security issue with lshell that allows any user to
escape from lshell into bash (or any other available shell. This
was done by typing <CTRL-V><CTRL-J>bash after any allowed command.
For example:
~$ echo<CTRL-V><CTRL-J>bash

Thanks Vladislav Yarmak (@Snawoot) for reporting this major issue!

Diff: diff --git a/lshell/sec.py b/lshell/sec.py
index a6c317f..ea3561f 100644
--- a/lshell/sec.py
+++ b/lshell/sec.py
@@ -154,11 +154,11 @@ def check_secure(line, conf, strict=None, ssh=None):
 
     # store original string
     oline = line
 
     # strip all spaces/tabs
-    line = " ".join(line.split())
+    line = line.strip()
 
     # init return code
     returncode = 0
 
     # This logic is kept crudely simple on purpose.
diff --git a/test/test_functional.py b/test/test_functional.py
index f1135e1..d139e7e 100644
--- a/test/test_functional.py
+++ b/test/test_functional.py
@@ -382,8 +382,25 @@ class TestFunctions(unittest.TestCase):
         self.child.expect('%s:~\$' % self.user)
         result = self.child.before.decode('utf8').split('\n')[1].strip()
 
         self.assertEqual(expected, result)
 
+    def test_28_catch_lnext_terminal_ctrl(self):
+        """ F25 | test ctrl-v ctrl-j then command, forbidden/security """
+        self.child = pexpect.spawn('%s/bin/lshell '
+                                   '--config %s/etc/lshell.conf '
+                                   % (TOPDIR, TOPDIR))
+        self.child.expect('%s:~\$' % self.user)
+
+        expected = u'*** forbidden syntax: echo\r'
+        self.child.send('echo')
+        self.child.sendcontrol('v')
+        self.child.sendcontrol('j')
+        self.child.sendline('bash')
+        self.child.expect('%s:~\$' % self.user)
+
+        result = self.child.before.decode('utf8').split('\n')
+
+        self.assertIn(expected, result)
 
 if __name__ == '__main__':
     unittest.main()

Vulnerable code:     line = " ".join(line.split())
Fixed code:     line = line.strip()
    def test_28_catch_lnext_terminal_ctrl(self):
        """ F25 | test ctrl-v ctrl-j then command, forbidden/security """
        self.child = pexpect.spawn('%s/bin/lshell '
                                   '--config %s/etc/lshell.conf '
                                   % (TOPDIR, TOPDIR))
        self.child.expect('%s:~\$' % self.user)

        expected = u'*** forbidden syntax: echo\r'
        self.child.send('echo')
        self.child.sendcontrol('v')
        self.child.sendcontrol('j')
        self.child.sendline('bash')
        self.child.expect('%s:~\$' % self.user)

        result = self.child.before.decode('utf8').split('\n')

        self.assertIn(expected, result)