Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 65 additions & 4 deletions agent360/plugins/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,53 @@
class Plugin(plugins.BasePlugin):
__name__ = 'process'

def sanitize_command_line(self, cmdline):
# Optional config keys in [process]:
# - disable_filtering = yes to bypass all cmdline filtering/redaction.
# - additional_filter_patterns = comma-separated literal patterns with '*' wildcard
# for extra redaction (for example: mypassword*,token=*).


def _get_additional_filter_wildcards(self, config):
if config is None:
return []

try:
value = config.get(self.__name__, 'additional_filter_patterns')
except Exception:
value = ''

if not value:
return []

patterns = []
for pattern in str(value).split(','):
pattern = pattern.strip()
if pattern:
patterns.append(pattern)
return patterns

def _compile_wildcard_regexes(self, wildcard_patterns):
wildcard_regexes = []
for wildcard_pattern in wildcard_patterns:
# Treat user input as literal text; only '*' is wildcard.
# '*' expands to any characters, including spaces.
wildcard_regex = re.escape(wildcard_pattern)
wildcard_regex = wildcard_regex.replace(r'\*', r'.*')
wildcard_regexes.append(re.compile(wildcard_regex, re.IGNORECASE))
return wildcard_regexes

def _is_filtering_disabled(self, config):
if config is None:
return False

try:
value = config.get(self.__name__, 'disable_filtering')
except Exception:
value = 'no'

return str(value).strip().lower() in ('1', 'true', 'yes', 'on')

def sanitize_command_line(self, cmdline, additional_filter_wildcard_regexes=None):
# Check if cmdline starts with a file path and separate it
match = re.match(r'^(\S+)(\s+.*)?$', cmdline)
if match:
Expand All @@ -34,15 +80,26 @@ def sanitize_command_line(self, cmdline):
remaining_cmdline = re.sub(r'\b(?:https?|ftp):\/\/(?:\S+\:\S+@)?(?:[a-zA-Z0-9.-]+\.\S+)', '***', remaining_cmdline, flags=re.IGNORECASE)
remaining_cmdline = re.sub(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b', '***', remaining_cmdline, flags=re.IGNORECASE)

if additional_filter_wildcard_regexes:
for wildcard_regex in additional_filter_wildcard_regexes:
try:
# Optional user-defined wildcard rules for extra redaction.
remaining_cmdline = wildcard_regex.sub('***', remaining_cmdline)
except Exception:
pass

# Combine the initial path and the sanitized command line, then limit length
sanitized_cmdline = (initial_path + remaining_cmdline).strip()
if len(sanitized_cmdline) > 256:
sanitized_cmdline = sanitized_cmdline[:253] + '...'

return sanitized_cmdline

def run(self, *unused):
def run(self, config=None, *unused):
process = []
filtering_disabled = self._is_filtering_disabled(config)
additional_filter_wildcards = self._get_additional_filter_wildcards(config)
additional_filter_wildcard_regexes = self._compile_wildcard_regexes(additional_filter_wildcards)
for proc in psutil.process_iter():
try:
pinfo = proc.as_dict(attrs=[
Expand All @@ -51,8 +108,12 @@ def run(self, *unused):
])

try:
# Sanitize and format the command line
pinfo['cmdline'] = self.sanitize_command_line(' '.join(pinfo['cmdline']).strip())
raw_cmdline = ' '.join(pinfo['cmdline']).strip()
if filtering_disabled:
pinfo['cmdline'] = raw_cmdline
else:
# Sanitize and format the command line
pinfo['cmdline'] = self.sanitize_command_line(raw_cmdline, additional_filter_wildcard_regexes)
except:
pass
if sys.version_info < (3,):
Expand Down
Loading