Introduction: Why Your PHP Site Could Be Hacked Right Now?
\nImagine this: you've written a cool PHP site, a feedback form, comments, a personal account. Everything works. But one day you log into the admin panel, and it's empty. Or even worse: casino ads appear on your site, and Google has blocked your resource. Sound familiar? The root of the evil is improper handling of user input.
\nThe question "How can I sanitize user input with PHP?" is one of the most popular on Stack Overflow. Thousands of developers stumble over the same rake. In this article, we'll break down the top errors that even experienced programmers make and show you how to avoid them. You'll learn how to protect against XSS, SQL injections, and other attacks. Let's go!
\n\nMistake #1: Using mysql_real_escape_string() for Everything
\nOld school: many developers still think that wrapping all data in mysql_real_escape_string() solves the problem. This is a gross mistake. This function is only intended for escaping strings in SQL queries, and even then, for the deprecated mysql_* extension that was removed back in PHP 7.
Example of incorrect code:
\n<?php\n$name = mysql_real_escape_string($_POST['name']);\n$query = "INSERT INTO users (name) VALUES ('$name')";\n$result = mysql_query($query);\n?>\nWhy this is bad:
\n- \n
- The function does not protect against XSS attacks (e.g., inserting JavaScript). \n
- The
mysql_*extension is deprecated and insecure. \n - You are mixing escaping logic with business logic. \n
How to fix: use prepared statements via PDO or MySQLi. And for displaying data on the screen, use separate sanitization.
\n\nMistake #2: Ignoring XSS Attacks When Outputting Data
\nThe most popular mistake. You receive data, save it to the database, and simply output it via echo or print. Voila — an attacker can insert a script that steals cookies, redirects the user, or ruins the layout.
Example of vulnerable code:
\n<?php\necho "<p>Hello, " . $_GET['name'] . "!</p>";\n?>\nIf you pass ?name=<script>alert('XSS')</script> in the URL, the script will execute.
Solution: use the htmlspecialchars() function with the ENT_QUOTES parameter:
<?php\n$name = htmlspecialchars($_GET['name'], ENT_QUOTES, 'UTF-8');\necho "<p>Hello, " . $name . "!</p>";\n?>\nImportant: sanitization should be done exactly at the time of output, not during saving. If you replace characters in the database, you will lose the original data.
\n\nMistake #3: Blind Filtering with strip_tags()
\nMany think: "Oh, I'll just remove all HTML tags — and that's it." But strip_tags() is not a panacea. First, it only removes tags but leaves attributes (e.g., onclick). Second, if you need to allow some tags (e.g., <b> or <i>), strip_tags() becomes inconvenient.
Example:
\n<?php\n$comment = strip_tags($_POST['comment']);\necho $comment; // Will remove <script>, but leave <a onclick="...">\n?>\nSolution: use htmlspecialchars() for plain text or libraries like HTML Purifier if you need to allow certain tags. HTML Purifier checks not only tags but also attributes, styles, and even CSS.
Mistake #4: Lack of Validation for Email, URLs, and Numbers
\nSanitization is not just about XSS. If you expect an email but receive the string "123", it can cause errors. Or if you save a URL without checking, an attacker can insert javascript:alert(1).