diff --git a/utils/bettercap_api.py b/utils/bettercap_api.py index 9161228..11dc67e 100644 --- a/utils/bettercap_api.py +++ b/utils/bettercap_api.py @@ -3,6 +3,7 @@ import secrets import string +import os from typing import Any, Dict, List, Optional import requests @@ -75,14 +76,27 @@ class BettercapAPI: return self.run(f"{module} off") def set_parameter(self, param: str, value: str) -> Dict[str, Any]: - return self.run(f"set {param} {value}") + # Validate param to prevent injection — allow alphanumeric, dots, underscores + if not re.match(r'^[a-zA-Z0-9._-]+$', param): + raise ValueError(f"Invalid parameter name: {param}") + # Quote value to prevent injection + quoted_value = repr(value) + return self.run(f"set {param} {quoted_value}") def get_hosts(self) -> List[Dict[str, Any]]: session = self.get_session() return session.get("lan", {}).get("hosts", []) def load_caplet(self, caplet_path: str) -> Dict[str, Any]: - return self.run(f"caplet.load {caplet_path}") + # Validate caplet path — must be absolute, must exist, prevent traversal + caplet_path = os.path.abspath(caplet_path) + if not os.path.isfile(caplet_path): + raise FileNotFoundError(f"Caplet not found: {caplet_path}") + if not caplet_path.endswith(('.cap', '.caplet')): + raise ValueError(f"Invalid caplet extension: {caplet_path}") + # Quote path for safety + quoted_path = repr(caplet_path) + return self.run(f"caplet.load {quoted_path}") @property def credentials(self) -> Dict[str, str]: