def test_check_ssh_injection(self):
cmd_list = ['ssh', '-D', 'my_name@name_of_remote_computer']
self.assertIsNone(utils.check_ssh_injection(cmd_list))
+ cmd_list = ['echo', '"quoted arg with space"']
+ self.assertIsNone(utils.check_ssh_injection(cmd_list))
+ cmd_list = ['echo', "'quoted arg with space'"]
+ self.assertIsNone(utils.check_ssh_injection(cmd_list))
def test_check_ssh_injection_on_error(self):
- with_space = ['shh', 'my_name@ name_of_remote_computer']
- with_danger_char = ['||', 'my_name@name_of_remote_computer']
+ with_unquoted_space = ['shh', 'my_name@ name_of_remote_computer']
self.assertRaises(exception.SSHInjectionThreat,
utils.check_ssh_injection,
- with_space)
+ with_unquoted_space)
+ with_danger_char = ['||', 'my_name@name_of_remote_computer']
self.assertRaises(exception.SSHInjectionThreat,
utils.check_ssh_injection,
with_danger_char)
+ with_special = ['cmd', 'virus;ls']
+ self.assertRaises(exception.SSHInjectionThreat,
+ utils.check_ssh_injection,
+ with_special)
+ quoted_with_unescaped = ['cmd', '"arg\"withunescaped"']
+ self.assertRaises(exception.SSHInjectionThreat,
+ utils.check_ssh_injection,
+ quoted_with_unescaped)
+ bad_before_quotes = ['cmd', 'virus;"quoted argument"']
+ self.assertRaises(exception.SSHInjectionThreat,
+ utils.check_ssh_injection,
+ bad_before_quotes)
+ bad_after_quotes = ['echo', '"quoted argument";rm -rf']
+ self.assertRaises(exception.SSHInjectionThreat,
+ utils.check_ssh_injection,
+ bad_after_quotes)
+ bad_within_quotes = ['echo', "'quoted argument `rm -rf`'"]
+ self.assertRaises(exception.SSHInjectionThreat,
+ utils.check_ssh_injection,
+ bad_within_quotes)
+ with_multiple_quotes = ['echo', '"quoted";virus;"quoted"']
+ self.assertRaises(exception.SSHInjectionThreat,
+ utils.check_ssh_injection,
+ with_multiple_quotes)
+ with_multiple_quotes = ['echo', '"quoted";virus;\'quoted\'']
+ self.assertRaises(exception.SSHInjectionThreat,
+ utils.check_ssh_injection,
+ with_multiple_quotes)
def test_create_channel(self):
client = paramiko.SSHClient()
# Check whether injection attacks exist
for arg in cmd_list:
arg = arg.strip()
- # First, check no space in the middle of arg
- arg_len = len(arg.split())
- if arg_len > 1:
- raise exception.SSHInjectionThreat(command=str(cmd_list))
+
+ # Check for matching quotes on the ends
+ is_quoted = re.match('^(?P<quote>[\'"])(?P<quoted>.*)(?P=quote)$', arg)
+ if is_quoted:
+ # Check for unescaped quotes within the quoted argument
+ quoted = is_quoted.group('quoted')
+ if quoted:
+ if (re.match('[\'"]', quoted) or
+ re.search('[^\\\\][\'"]', quoted)):
+ raise exception.SSHInjectionThreat(command=str(cmd_list))
+ else:
+ # We only allow spaces within quoted arguments, and that
+ # is the only special character allowed within quotes
+ if len(arg.split()) > 1:
+ raise exception.SSHInjectionThreat(command=str(cmd_list))
# Second, check whether danger character in command. So the shell
# special operator must be a single argument.