Fixes the command injection reported in #263.
Summary
/api/tools/nmap and /api/tools/gobuster built their shell command by f-string interpolation of client-supplied JSON fields (target, url, ports, wordlist), then ran it via subprocess.Popen(command, shell=True, ...). None of those fields was quoted, so a value containing shell metacharacters ran as a separate command. Combined with the server binding 0.0.0.0 with no authentication anywhere in the code, this was unauthenticated remote code execution for anyone who could reach the API port.
Fix
Added safe_shell_arg() (shlex.quote()) and applied it to the client-controlled single-value fields in both endpoints. New tests in command_injection_poc_test.py confirm the injection is blocked on both endpoints after the fix, and that a legitimate scan still runs.
Scope
The same f-string-into-shell=True pattern is present in the other /api/tools/* endpoints in this file (90 total via @app.route("/api/tools/), not just these two. This PR is scoped to the two demonstrated in #263; the rest need the same treatment with safe_shell_arg. additional_args-style fields (multiple space-separated CLI flags) need a flag allowlist instead of quoting, also not covered here. Adding authentication in front of the API is worth considering independently of this fix.