4.2. Security Practices
PHP
1. Input Validation and Sanitization
-
Best Practices:
- Validate input data to ensure it meets expected formats (e.g., email, date, integer).
- Sanitize input to remove or escape harmful characters.
-
Techniques:
- Use
filter_var()for individual inputs:$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL); - Use
filter_input():$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); - Use
filter_input_array()for multiple inputs:$inputs = filter_input_array(INPUT_POST, [ 'email' => FILTER_VALIDATE_EMAIL, 'age' => FILTER_VALIDATE_INT ]);
- Use
2. SQL Injection Protection
-
Best Practices:
- Always use prepared statements and parameterized queries.
-
Examples:
- Using PDO:
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email"); $stmt->execute(['email' => $email]); $user = $stmt->fetch(); - Using MySQLi:
$stmt = $mysqli->prepare("SELECT * FROM users WHERE email = ?"); $stmt->bind_param('s', $email); $stmt->execute(); $result = $stmt->get_result(); $user = $result->fetch_assoc();
- Using PDO:
3. Cross-Site Scripting (XSS) Prevention
-
Best Practices:
- Sanitize output by escaping HTML characters.
- Use CSP headers to control the sources of scripts and other content.
-
Examples:
echo htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');- Setting CSP headers:
header("Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self';");
- Setting CSP headers:
4. Cross-Site Request Forgery (CSRF) Protection
-
Best Practices:
- Use CSRF tokens in forms and validate them on the server side.
-
Examples:
- Generating a CSRF token:
session_start(); $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); - Including the token in a form:
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"> - Validating the token:
if (hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) { // Process form } else { // Invalid CSRF token }
- Generating a CSRF token:
5. Session Management
-
Best Practices:
- Configure session settings for security.
-
Examples:
ini_set('session.use_strict_mode', 1); ini_set('session.cookie_httponly', 1); ini_set('session.cookie_secure', 1); session_start(); session_regenerate_id(true);
6. Error Handling and Logging
-
Best Practices:
- Disable error display in production and log errors securely.
-
Examples:
ini_set('display_errors', 0); ini_set('log_errors', 1); ini_set('error_log', '/path/to/error.log');
7. File Upload Security
-
Best Practices:
- Validate and sanitize file names.
- Check MIME types and file extensions.
- Store uploaded files outside the web root.
-
Examples:
$allowed_types = ['image/jpeg', 'image/png', 'application/pdf']; $file_type = mime_content_type($_FILES['file']['tmp_name']); if (in_array($file_type, $allowed_types)) { // Process file } else { // Invalid file type }
8. Password Management
-
Best Practices:
- Use strong password hashing algorithms.
- Implement multi-factor authentication (MFA).
-
Examples:
$hashed_password = password_hash($password, PASSWORD_DEFAULT); if (password_verify($password, $hashed_password)) { // Password is correct }
9. Configuration and Deployment
-
Best Practices:
- Disable unnecessary PHP functions.
- Keep PHP up-to-date.
- Use HTTPS for all communications.
-
Examples:
- Disabling functions:
disable_functions = exec,passthru,shell_exec,system - Forcing HTTPS:
if ($_SERVER['HTTPS'] !== 'on') { header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); exit(); }
- Disabling functions:
Node.js
1. Input Validation and Sanitization
-
Best Practices:
- Validate all user inputs to ensure they meet expected formats.
- Sanitize inputs to remove harmful characters.
-
Techniques:
- Use libraries like
validatorfor input validation:const validator = require('validator'); if (validator.isEmail(req.body.email)) { // Proceed with email }
- Use libraries like
2. Avoiding NoSQL Injection
-
Best Practices:
- Use ORM/ODM libraries that provide query parameterization (e.g., Mongoose for MongoDB).
-
Examples:
// Using Mongoose const user = await User.findOne({ email: req.body.email });
3. Preventing SQL Injection
-
Best Practices:
- Use parameterized queries or ORM libraries.
-
Examples:
- Using
mysqlmodule with parameterized queries:const mysql = require('mysql'); const connection = mysql.createConnection({ /* config */ }); connection.query('SELECT * FROM users WHERE email = ?', [req.body.email], (error, results) => { if (error) throw error; // Process results });
- Using
4. Cross-Site Scripting (XSS) Prevention
-
Best Practices:
- Escape HTML characters in output.
- Use CSP headers to control content sources.
-
Examples:
const escape = require('escape-html'); res.send(escape(userInput));- Setting CSP headers:
app.use((req, res, next) => { res.setHeader("Content-Security-Policy", "default-src 'self'; script-src 'self'; style-src 'self';"); next(); });
- Setting CSP headers:
5. Cross-Site Request Forgery (CSRF) Protection
-
Best Practices:
- Use CSRF tokens in forms and validate them on the server side.
- Use libraries like
csurf.
-
Examples:
const csurf = require('csurf'); const csrfProtection = csurf({ cookie: true }); app.use(csrfProtection); app.get('/form', (req, res) => { res.render('send', { csrfToken: req.csrfToken() }); }); app.post('/process', (req, res) => { // Process form });
6. Session Management
-
Best Practices:
- Use secure session configurations.
- Use libraries like
express-sessionwith secure settings.
-
Examples:
const session = require('express-session'); app.use(session({ secret: 'yourSecret', resave: false, saveUninitialized: true, cookie: { secure: true, httpOnly: true } }));
7. Error Handling and Logging
-
Best Practices:
- Handle errors gracefully without exposing sensitive information.
- Use centralized logging solutions.
-
Examples:
app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('Something broke!'); });
8. Secure Configuration and Deployment
-
Best Practices:
- Disable X-Powered-By header.
- Use environment variables for configuration.
- Keep dependencies up-to-date.
-
Examples:
- Disabling X-Powered-By header:
app.disable('x-powered-by'); - Using environment variables:
const config = { db: process.env.DB_CONNECTION_STRING, port: process.env.PORT || 3000 };
- Disabling X-Powered-By header:
9. Dependency Management
-
Best Practices:
- Regularly update dependencies.
- Use tools like
npm auditto find and fix vulnerabilities. - Avoid using deprecated or unmaintained packages.
-
Examples:
npm audit
10. Secure File Uploads
-
Best Practices:
- Validate file types and sizes.
- Store files securely outside the web root.
-
Examples:
- Using
multerfor file uploads:const multer = require('multer'); const upload = multer({ dest: 'uploads/', fileFilter: (req, file, cb) => { if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') { cb(null, true); } else { cb(new Error('Invalid file type'), false); } } }); app.post('/upload', upload.single('avatar'), (req, res) => { res.send('File uploaded!'); });
- Using
11. Using HTTPS
-
Best Practices:
- Always use HTTPS for communication.
- Redirect HTTP to HTTPS.
-
Examples:
const fs = require('fs'); const https = require('https'); const express = require('express'); const app = express(); https.createServer({ key: fs.readFileSync('server.key'), cert: fs.readFileSync('server.cert') }, app).listen(443, () => { console.log('HTTPS server running on port 443'); }); app.use((req, res, next) => { if (req.headers['x-forwarded-proto'] !== 'https') { return res.redirect('https://' + req.headers.host + req.url); } next(); });