Security is not optional — it must be built in from the start. The OWASP Top 10 covers the most critical web application vulnerabilities. Linux hardening, least privilege, and defense-in-depth are core principles for every system administrator.
| Item | Syntax / Value | Description |
|---|---|---|
| OWASP Top 10 | Broken Access Control, Cryptographic Failures, Injection, Insecure Design, Security Misconfiguration, Vulnerable Components, Auth Failures, Software Integrity, Logging Failures, SSRF | Critical web app vulnerability categories |
| SQL Injection | ' OR 1=1-- / ; DROP TABLE users;-- | Malicious SQL in user input — use parameterized queries! |
| XSS | <script>alert(document.cookie)</script> | Cross-Site Scripting — escape output, use CSP |
| CSRF | Forged requests using victim's session | Use CSRF tokens + SameSite cookies |
| SSRF | Fetch internal services via server | Validate/whitelist URLs, block 169.254.169.254 (metadata) |
| Path traversal | ../../etc/passwd | Access files outside intended directory |
| Command injection | ; rm -rf / or $(malicious) | Never pass user input to shell — use subprocess list form |
| Broken access control | Horizontal privilege escalation — access other user's data | Check authorization on EVERY request, not just login |
| Cryptographic failures | MD5/SHA1 passwords, HTTP, weak ciphers | Use bcrypt/argon2, TLS 1.2+, AES-256-GCM |
| Security misconfiguration | Default passwords, debug mode in prod, open S3 buckets | Principle of least privilege, CIS benchmarks |
| RBAC | Role-Based Access Control — least privilege | Only grant permissions actually needed |
| Defense in depth | Multiple layers of security controls | Firewall + WAF + auth + encryption + monitoring |
| Principle of least privilege | Grant minimum permissions needed | Users, processes, services — restrict by default |
| nmap | nmap -sV -p 1-65535 target | Network port scanner — discover open services |
| nmap OS detect | nmap -O target | Guess target OS from TCP/IP fingerprint |
| netstat / ss | ss -tlnp / netstat -tulnp | List listening ports and their processes |
| fail2ban | sudo apt install fail2ban | Auto-ban IPs with too many failed login attempts |
| ufw | ufw allow 22/tcp && ufw enable | Ubuntu Uncomplicated Firewall |
| iptables | iptables -A INPUT -p tcp --dport 22 -j ACCEPT | Linux netfilter firewall rules |
| auditd | auditctl -w /etc/passwd -p wa -k passwd_changes | Linux audit daemon — track file/system changes |
| SELinux | setenforce Enforcing / getenforce | Mandatory Access Control — limits process permissions |
| AppArmor | aa-status / aa-enforce /etc/apparmor.d/ | Ubuntu MAC — profile-based app restrictions |
| Lynis | lynis audit system | System security auditing tool |
| ClamAV | clamscan -r /home | Open source antivirus for Linux |
| openssl rand | openssl rand -hex 32 | Generate cryptographically secure random bytes |
| bcrypt | import bcrypt; bcrypt.hashpw(pw, bcrypt.gensalt(12)) | Hash passwords — never MD5/SHA for passwords |
# ── Secure Coding Patterns (Python) ──────────────────────────
# BAD: SQL injection vulnerable
import sqlite3
def get_user_bad(username):
conn = sqlite3.connect('users.db')
# NEVER DO THIS:
query = f"SELECT * FROM users WHERE username = '{username}'"
return conn.execute(query).fetchone()
# Attack: get_user_bad("admin' OR '1'='1") -- returns ALL users!
# GOOD: Parameterized query
def get_user_good(username):
conn = sqlite3.connect('users.db')
return conn.execute(
"SELECT * FROM users WHERE username = ?", (username,)
).fetchone()
# ── Password hashing (bcrypt) ─────────────────────────────────
# pip install bcrypt
import bcrypt
def hash_password(plain: str) -> bytes:
return bcrypt.hashpw(plain.encode(), bcrypt.gensalt(rounds=12))
def verify_password(plain: str, hashed: bytes) -> bool:
return bcrypt.checkpw(plain.encode(), hashed)
pw_hash = hash_password("MySecurePass123!")
print(f"Hash: {pw_hash[:30]}...")
print(f"Valid: {verify_password('MySecurePass123!', pw_hash)}")
print(f"Wrong: {verify_password('wrongpassword', pw_hash)}")
# ── Input validation & sanitization ──────────────────────────
import re, html as html_lib
def validate_email(email: str) -> bool:
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return bool(re.match(pattern, email)) and len(email) <= 254
def sanitize_html(user_input: str) -> str:
return html_lib.escape(user_input) # converts < > & " ' to entities
def safe_path(base_dir: str, user_filename: str) -> str:
import os
safe = os.path.realpath(os.path.join(base_dir, user_filename))
if not safe.startswith(os.path.realpath(base_dir)):
raise ValueError("Path traversal attempt detected!")
return safe
# BAD: subprocess with shell=True
import subprocess
def run_bad(filename):
subprocess.run(f"cat {filename}", shell=True) # command injection!
# GOOD: subprocess with list (no shell)
def run_good(filename):
subprocess.run(["cat", filename], check=True) # safe
# ── Security headers (Flask example) ─────────────────────────
from flask import Flask, make_response
app = Flask(__name__)
@app.after_request
def add_security_headers(resp):
resp.headers['Strict-Transport-Security'] = 'max-age=63072000; includeSubDomains; preload'
resp.headers['X-Content-Type-Options'] = 'nosniff'
resp.headers['X-Frame-Options'] = 'DENY'
resp.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
resp.headers['Content-Security-Policy'] = (
"default-src 'self'; "
"script-src 'self' https://cdnjs.cloudflare.com; "
"style-src 'self' https://fonts.googleapis.com; "
"img-src 'self' data: https:; "
"object-src 'none'; "
"base-uri 'self'"
)
resp.headers['Permissions-Policy'] = 'geolocation=(), microphone=(), camera=()'
return resp
# ── Linux system hardening ────────────────────────────────────
# Disable root SSH login
sudo sed -i 's/^PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sudo sed -i 's/^PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl reload sshd
# Enable automatic security updates
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
# Install and configure fail2ban
sudo apt install fail2ban
sudo tee /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
EOF
sudo systemctl enable fail2ban && sudo systemctl start fail2ban
# Firewall with ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable
sudo ufw status verbose
# Run Lynis security audit
sudo apt install lynis
sudo lynis audit system