SQL Injection
The Vulnerability
SQL injection occurs when user input is concatenated directly into SQL queries:
// DANGEROUS: Direct string interpolation
$username = $_GET['user'];
$query = "SELECT * FROM users WHERE username = '{$username}'";
// If user sends: ' OR '1'='1
// Query becomes: SELECT * FROM users WHERE username = '' OR '1'='1'
// Returns ALL users
Prevention: Prepared Statements
// SAFE: Parameterized query with PDO
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :username');
$stmt->execute(['username' => $inputUsername]);
$user = $stmt->fetch();
// SAFE: Magento's query builder
$connection = $this->resource->getConnection();
$select = $connection->select()->from(
'customer_entity',
['entity_id', 'email']
)->where(
'email = ?',
$email // Automatically parameterized
);
$connection->fetchRow($select);
// SAFE: Magento's update with parameter binding
$connection->update(
'catalog_product',
['name' => $newName],
['entity_id = ?' => $productId] // Parameterized
);
Magento's Protection
Magento's ORM and query builder automatically use prepared statements. Never use Zend_Db_Expr with user input:
// NEVER do this with user input
$where = new \Zend_Db_Expr("name = '{$userInput}'"); // SQL injection!
// Always use parameter binding
->where('name = ?', $userInput) // Safe
Cross-Site Scripting (XSS)
The Vulnerability
XSS occurs when unescaped user input is rendered in HTML:
// DANGEROUS: Unescaped output
echo '<div>' . $_GET['name'] . '</div>';
// If user sends: <script>steal(document.cookie)</script>
// Script executes in victim's browser
Three Types of XSS
| Type | Where | Example |
|---|---|---|
| Stored | Database → page | Comment field: <script>...</script> |
| Reflected | URL parameter | Search: ?q=<script>...</script> |
| DOM-based | Client-side JS | document.getElementById('output').innerHTML = location.hash |
Prevention: Output Escaping
// PHP built-in escaping
echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8');
// Magento template escaping
// In .phtml templates:
<?= $block->escapeHtml($product->getName()) ?> // HTML escaped
<?= $block->escapeHtmlAttr($product->getSku()) ?> // Attribute escaped
<?= $block->escapeUrl($product->getUrl()) ?> // URL escaped
<?= $block->escapeNotHtml($product->getDescription()) ?> // No escaping
// In JavaScript contexts:
<script>
var data = <?= $block->escapeJson($jsonData) ?>;
</script>
Content Security Policy (CSP)
// Magento CSP headers
// app/code/Vendor/Module/etc/module.xml
<config>
<module name="Vendor_Module">
<sequence>
<module name="Magento_Csp"/>
</sequence>
</module>
</config>
CSP restricts which scripts, styles, and resources can load, mitigating XSS impact.
CSRF, File Inclusion & Session Security
CSRF (Cross-Site Request Forgery)
Forged requests from authenticated users:
// Protection: CSRF tokens in forms
// Magento automatically adds form keys
// In .phtml templates:
<form method="post" action="<?= $block->getUrl('*/*/save') ?>">
<?= $block->getBlockHtml('formkey') ?> <!-- CSRF token -->
<input type="text" name="name">
<button type="submit">Save</button>
</form>
// Validate in controller:
public function execute()
{
if (!$this->_validateFormKey()) {
throw new \Magento\Framework\Exception\LocalizedException(
__('Invalid form key')
);
}
// Process form...
}
File Inclusion Vulnerabilities
// DANGEROUS: User input in file path
$page = $_GET['page'];
include('/templates/' . $page . '.php');
// Attacker sends: page=../../etc/passwd%00
// SAFE: Whitelist approach
$allowedPages = ['home', 'about', 'contact'];
$page = $_GET['page'];
if (!in_array($page, $allowedPages, true)) {
throw new \Exception('Invalid page');
}
include(__DIR__ . '/templates/' . $page . '.php');
Session Security
// Secure session configuration
ini_set('session.cookie_httponly', 1); // No JS access to cookie
ini_set('session.cookie_secure', 1); // HTTPS only
ini_set('session.use_strict_mode', 1); // Reject uninitialized sessions
ini_set('session.cookie_samesite', 'Strict'); // CSRF protection
// Regenerate session ID after login (prevent fixation)
session_regenerate_id(true);
// Magento session security:
// - Form keys for CSRF
// - Session-based admin authentication
// - Secure cookie configuration
Magento Security Checklist
- ✅ Prepared statements via query builder
- ✅ Output escaping via
escapeHtml() - ✅ CSRF tokens via form key
- ✅ Content Security Policy (CSP)
- ✅ Secure session configuration
- ✅ Input validation on controllers
- ✅ Rate limiting on login
Quiz
1. How do you prevent SQL injection in PHP?
2. What does htmlspecialchars() protect against?
3. CSRF tokens in Magento are generated via:
Flashcards
Question
How to prevent SQL injection?
Click to reveal answer
Answer
Use prepared statements / parameterized queries
Question
How to prevent XSS?
Click to reveal answer
Answer
Escape output with htmlspecialchars() or Magento's escapeHtml()
Question
What is CSRF?
Click to reveal answer
Answer
Cross-Site Request Forgery - forged requests from authenticated users
Question
Magento CSRF protection?
Click to reveal answer
Answer
Form keys (formkey) validated server-side
Question
What does htmlspecialchars() do?
Click to reveal answer
Answer
Escapes < > & " ' to prevent HTML/JS injection
Revision Notes
Key Takeaways
- 1. SQL injection: use prepared statements, never concatenate user input into queries
- 2. XSS: escape all output with htmlspecialchars() or Magento's escapeHtml()
- 3. CSRF: use CSRF tokens (form keys) in all state-changing forms
- 4. File inclusion: whitelist allowed files, never use user input in paths
- 5. Sessions: use httponly, secure, strict cookies; regenerate ID after login
Interview Tips
- • Explain each vulnerability with a concrete attack example
- • Give the PHP function to prevent each: PDO::prepare, htmlspecialchars(), CSRF tokens
- • Discuss Magento-specific protections (form keys, escapeHtml, CSP)
Cheat Sheet
SQL Injection → PDO::prepare() + bindParam()
XSS → htmlspecialchars($input, ENT_QUOTES, 'UTF-8')
CSRF → Form key validation (_validateFormKey())
File Inclusion → Whitelist allowed files
Session → httponly + secure + strict_mode + regenerate_id
Magento:
SQL: Query builder where() automatically parameterized
XSS: $block->escapeHtml($var)
CSRF: $block->getBlockHtml('formkey')
CSP: Magento_Csp module