Command Injection Prevention
Avoid system command functions
Prefer built-in language functions over system command execution. For example, in PHP, use fsockopen() to test connectivity instead of executing ping via system().
When system commands are unavoidable:
- Never pass raw user input directly to them
- Validate and sanitize on the back-end before use
- Minimize their use — only when no built-in alternative exists
Front-end validation alone is insufficient; it is trivially bypassed by sending raw HTTP requests.
Input validation
Validate that input matches its expected format before processing. Implement on both front-end and back-end.
PHP — built-in IP filter:
if (filter_var($_GET['ip'], FILTER_VALIDATE_IP)) {
// call function
} else {
// deny request
}
PHP — custom regex:
preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_GET['ip'])
NodeJS — regex:
if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(...)$/.test(ip)) {
// call function
} else {
// deny request
}
NodeJS — library: is-ip (npm install is-ip, use isIp(ip))
PHP’s filter_var has built-in validators for emails, URLs, IPs, and other standard formats. Consult the docs for .NET, Java, and other platforms for their equivalents.
Input sanitization
Sanitize after validation: remove all characters not required for the expected format. Allowlists (“allow only known good”) are stronger than blacklists (“block known bad”).
PHP — allowlist regex:
$ip = preg_replace('/[^A-Za-z0-9.]/', '', $_GET['ip']);
JavaScript:
var ip = ip.replace(/[^A-Za-z0-9.]/g, '');
NodeJS — DOMPurify:
import DOMPurify from 'dompurify';
var ip = DOMPurify.sanitize(ip);
For inputs that must allow special characters (e.g., free-text comments), use escapeshellcmd (PHP) or escape() (Node) to escape them — though escaping is weaker than allowlist sanitization and can often be bypassed.
Server configuration
Reduce blast radius if the server is compromised:
- Enable the web server’s built-in WAF (e.g., Apache
mod_security) plus an external WAF (Cloudflare, Fortinet, Imperva) - Run the web server as a low-privilege user (Principle of Least Privilege — e.g.,
www-data) - Disable dangerous PHP functions:
disable_functions=system,exec,shell_exec,passthru,... - Restrict web app filesystem scope:
open_basedir = '/var/www/html' - Reject double-encoded requests and non-ASCII characters in URLs
- Avoid sensitive or outdated modules (e.g., PHP CGI)
Secure configuration complements secure coding — neither alone is sufficient. Pair both with ongoing penetration testing, since any single mistake in a large codebase can reintroduce a vulnerability.