@@ -928,6 +928,11 @@ def get_nmap_cmd(
928
928
}
929
929
cmd = _build_cmd (cmd , options , flags )
930
930
931
+ is_nmap_valid = is_valid_nmap_command (cmd )
932
+ if not is_nmap_valid :
933
+ logger .error (f'Invalid nmap command or potentially dangerous: { cmd } ' )
934
+ return None
935
+
931
936
if not input_file :
932
937
cmd += f" { host } " if host else ""
933
938
else :
@@ -1646,3 +1651,43 @@ def get_ips_from_cidr_range(target):
1646
1651
return [str (ip ) for ip in ipaddress .IPv4Network (target , False )]
1647
1652
except Exception as e :
1648
1653
logger .error (f'{ target } is not a valid CIDR range. Skipping.' )
1654
+
1655
+
1656
+ def is_valid_nmap_command (cmd ):
1657
+ """
1658
+ Check if the nmap command is valid or not
1659
+ This is to check the nmap command before executing it so as to avoid
1660
+ command injection attacks
1661
+ Args:
1662
+ cmd: str: nmap command
1663
+ Returns:
1664
+ bool: True if valid, False otherwise
1665
+
1666
+ Allowing user input in nmap command is by design
1667
+ as user can provide custom nmap command to run
1668
+ but we need to make sure that the command is safe
1669
+ and doesn't contain any malicious commands
1670
+ We do this by checking if the command starts with nmap
1671
+ and doesn't contain any dangerous characters, in the most basic form
1672
+ """
1673
+ # if this is not a valid command nmap command at all, dont even run it
1674
+ if not cmd .strip ().startswith ('nmap' ):
1675
+ return False
1676
+
1677
+ # check for dangerous chars
1678
+ dangerous_chars = {';' , '&' , '|' , '>' , '<' , '`' , '$' , '(' , ')' , '#' , '\\ ' }
1679
+ if any (char in cmd for char in dangerous_chars ):
1680
+ return False
1681
+
1682
+ # but we also need to check for flags and options, for example - and -- are allowed
1683
+ parts = cmd .split ()
1684
+ for part in parts [1 :]: # ignoring nmap the first part of command
1685
+ if part .startswith ('-' ) or part .startswith ('--' ):
1686
+ continue
1687
+
1688
+ # check for valid characters, . - etc are allowed in valid nmap command
1689
+ if all (c .isalnum () or c in '.,/-_' for c in part ):
1690
+ continue
1691
+ return False
1692
+
1693
+ return True
0 commit comments