Security Fundamentals

Essential security practices for building secure applications

Why Security Matters

Security is not optional - it's fundamental to building trustworthy applications. Security breaches can result in data loss, financial damage, reputation harm, and legal consequences. Building security into your development process from the start is more effective and cost-efficient than adding it later.

This guide covers essential security concepts every developer should know: authentication, authorization, encryption, input validation, secure coding practices, and common vulnerabilities. For comprehensive security coverage, see our Security & Networking documentation.

Authentication and Authorization

Authentication

Authentication verifies user identity. Common methods include passwords, multi-factor authentication (MFA), OAuth 2.0, and JWT tokens. Always hash passwords using strong algorithms like bcrypt or Argon2 - never store plain text passwords.

// Password hashing example (pseudocode)
const hashedPassword = bcrypt.hash(password, saltRounds);

// Verify password
const isValid = bcrypt.compare(password, hashedPassword);

// Never do this:
// if (user.password === inputPassword) // WRONG!

Implement session management securely. Use secure, HTTP-only cookies for session tokens. Set appropriate expiration times. For API authentication, see our RESTful API Design guide.

Authorization

Authorization determines what authenticated users can do. Implement role-based access control (RBAC) or attribute-based access control (ABAC). Check permissions at every access point - don't trust client-side checks alone.

// Check authorization before operations
if (!user.hasPermission('delete_post')) {
    throw new UnauthorizedError();
}

// Use middleware for route protection
app.delete('/posts/:id', 
    authenticateUser,
    authorize('delete_post'),
    deletePost
);

Input Validation and Sanitization

All user input is potentially malicious. Validate and sanitize all inputs at multiple layers: client-side (UX), server-side (security), and database level.

SQL Injection Prevention

Use parameterized queries or prepared statements. Never concatenate user input into SQL queries.

// Good: Parameterized query
db.query('SELECT * FROM users WHERE id = ?', [userId]);

// Bad: SQL injection vulnerability
db.query('SELECT * FROM users WHERE id = ' + userId);

XSS Prevention

Escape output to prevent Cross-Site Scripting (XSS) attacks. Use framework templating that auto-escapes, or escape manually.

// Escape HTML output
const escaped = escapeHtml(userInput);

// Use Content Security Policy (CSP) headers
Content-Security-Policy: default-src 'self'

Input Validation

Validate data types, ranges, formats, and business rules. Reject invalid input rather than trying to fix it. For database security, see our Databases guide.

Encryption

Data in Transit

Always use HTTPS (TLS/SSL) for all communications. Never send sensitive data over unencrypted connections. Use TLS 1.2 or higher. Implement certificate pinning for mobile apps.

Data at Rest

Encrypt sensitive data stored in databases. Use strong encryption algorithms (AES-256). Store encryption keys securely using key management services. Never hardcode keys in source code.

// Encrypt sensitive data before storage
const encrypted = encrypt(userData, encryptionKey);

// Decrypt when needed
const decrypted = decrypt(encryptedData, encryptionKey);

// Use environment variables for keys
const key = process.env.ENCRYPTION_KEY;

Common Vulnerabilities (OWASP Top 10)

1. Broken Access Control

Users can access resources they shouldn't. Always verify authorization server-side. Don't rely on hidden fields or client-side checks.

2. Cryptographic Failures

Weak encryption, exposed keys, or improper encryption implementation. Use strong, up-to-date algorithms and secure key management.

3. Injection

SQL, NoSQL, OS command, or LDAP injection. Use parameterized queries, input validation, and least privilege principles.

4. Insecure Design

Security flaws in design phase. Perform threat modeling, security reviews, and use secure design patterns.

5. Security Misconfiguration

Default configurations, exposed debug information, or unnecessary features enabled. Harden configurations and remove defaults.

Secure Coding Practices

Principle of Least Privilege

Grant minimum necessary permissions. Run applications with least privilege accounts. Limit database user permissions. For cloud deployments, see our Cloud Computing guide on IAM.

Defense in Depth

Implement multiple security layers: network firewalls, application firewalls, input validation, authentication, authorization, encryption, and monitoring. Don't rely on a single security measure.

Secure by Default

Design systems with security as a primary consideration. Use secure defaults. Require explicit opt-in for less secure features. Fail securely - deny access by default.

Error Handling

Don't expose sensitive information in error messages. Log errors securely for debugging but don't reveal system internals to users. Use generic error messages for users, detailed logs for administrators.

Security Headers

Implement security headers to protect against various attacks:

// Essential security headers
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000
Referrer-Policy: strict-origin-when-cross-origin

Security Testing

Regularly test your applications for security vulnerabilities. Use static analysis tools, dependency scanners, penetration testing, and security audits. Keep dependencies updated to patch known vulnerabilities.

Implement security monitoring and logging. Monitor for suspicious activities, failed authentication attempts, and unusual access patterns. Set up alerts for security events. For DevOps security, see our DevOps & Infrastructure guide.

Next Steps