A structured lesson workspace with readable content, hands-on examples, and a clean path to completion.
Everything you learned in the previous modules exists because someone wrote code that passed user input to a shell. The fix is not a WAF rule. The fix is not a blacklist. The fix is never letting untrusted data reach a command interpreter in the first place. Here is how you actually do that.
If you need to check whether a host is alive, use a socket connection. PHP has fsockopen. Python has socket.connect. NodeJS has net.createConnection. These functions do not spawn a shell. There is no command string to inject into. The vulnerability class ceases to exist.
// VULNERABLE: passes user input to shellsystem("ping -c 1 " . $_GET['ip']);// SECURE: no shell involved$fp = fsockopen($_GET['ip'], 80, $errno, $errstr, 2);if ($fp) {echo "Host is alive";fclose($fp);} else {echo "Host is unreachable";}
When no built-in alternative exists and you genuinely need to run a system command, pass arguments as an array, not as a concatenated string. This prevents the shell from interpreting metacharacters in the user input.
Front-end validation is UX. Backend validation is security. Use built-in filter functions to verify the input matches the expected format before processing it. For IP addresses, PHP has filter_var with FILTER_VALIDATE_IP. NodeJS has the is-ip library. Python has ipaddress.ip_address().
if (filter_var($_GET['ip'], FILTER_VALIDATE_IP)) {// Safe to proceed$fp = fsockopen($_GET['ip'], 80, $errno, $errstr, 2);} else {http_response_code(400);die("Invalid IP address");}
Validation can fail. A regex might have a bug. A library might have an edge case. Defense in depth means you also strip any character that is not strictly necessary for the expected format. For an IP address, you only need digits and dots. Everything else gets removed.
$ip = preg_replace('/[^0-9.]/', '', $_GET['ip']);
const ip = userInput.replace(/[^0-9.]/g, '');
Do not rely on escapeshellcmd() or escape() as your primary defense. These functions escape special characters, but as you learned in this course, escaping can be bypassed through encoding tricks, environment variable extraction, and other techniques. Sanitization (removal) is stronger than escaping (neutralization).
Secure code is the first layer. But code lives on a server, and that server needs its own hardening. The next lesson covers the infrastructure-level controls that limit the blast radius when (not if) a vulnerability slips through.
Finish the lesson once you have worked through the material. This awards ★ 30 XP.