- FEATURES
- Autoload
- Class Reflection
- Magic Methods
- Exceptions
- Late Static Binding
- Type Hinting
- SPL
- PHPUNIT
- PHAR
- COMPOSER
- Carbon
- Guzzle
- Faker
- Math
- Requests
- DESIGN PATTERNS
- Singleton Pattern
- Observer Pattern
- Strategy Pattern
- Dependency Injection
- Middleware
- Registry
- SYMFONY
- Routes
- Annotations
- Flex
- Controllers
- Doctrine
- Templating
- VERSIONS
- Php7.4
- Php8.0
- SECURITY
- Filter Input
- Remote Code Injection
-
Sql Injection
- Session Fixation
- File Uploads
- Cross Site Scripting
- Spoofed Forms
- CSRF
- Session Hijacking
- MODERN PHP
- Composer
- Autoloader
- Package
- Releases
- Generators
- Dependency Injection
- Middleware
- CUSTOM FRAMEWORK
- App
- Http Foundation
- Front Controller
- Routing
- Render Controller
- Resolver
- SoC
- FRAMEWORKS
- Slim
- Symfony V5
- Laravel V8
- Laminas V3
- Codeigniter V4
INJECTION
The SQL query ignores everything after the # and returns all records!
# A malicious user experiments on a form
<form method="POST">
<input type="text" name="username" value="username' OR 1 = 1 #"/>
<input type="password" name="password" />
<input type="submit" name="btn_submit" value="Log In"/>
</form>
if (isset($_POST['btn_submit'])) {
$username = $_POST['username']; // NO database filtering!
$password = md5($_POST['password']);
$sql = "
SELECT * FROM users
WHERE username='{$username}' AND password='{$password}'
";
echo $sql;
// SELECT * FROM users
// WHERE username='username' OR 1 = 1 #' AND ...
FILTER
As a first defence you must filter the input.
if (isset($_POST['btn_submit'])) {
// driver-specific db filtering
$username = mysql_escape_string($_POST['username']);
$password = md5(mysql_escape_string($_POST['password']));
$sql = "
SELECT * FROM users
WHERE username='{$username}' AND password='{$password}'
";
echo $sql;
// Will add slashes to username quote
// resulting in SQL syntax error
}
BIND
If possible, use bound parameters.
# Use a placeholder like ? ...
# and provide the actual values using a separate API call.
#
# Two good reasons:
# - is the best way to prevent SQL injection
# - not using bind parameters is like recompiling a program every time
$stmt = $dbh->prepare("
INSERT INTO mytable (name, value) VALUES (:name, :value)
");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
Last update: 488 days ago