Lecture 7: Robust and Secure Programming
Overview
Robust and secure programming is the foundation of reliable software systems. This lecture covers essential security practices including input validation, memory management, authentication, encryption, and handling concurrency safely. With cybercrime damages expected to reach $10.5 trillion annually by 2025, understanding these concepts is critical for every developer.
Lecture Material (PDF)
Input Validation & Output Encoding
Sanitizing inputs prevents a majority of injection attacks. OWASP ranks input validation issues among the top security risks. Proper validation ensures only expected data enters your system.
Input Sanitization
Always validate and sanitize user inputs before processing. Use built-in methods like PHP's filter_var() or regex patterns to ensure data matches expected formats.
Output Encoding
Encode output data to prevent XSS attacks. Never trust user input when rendering to HTML, JavaScript, or other contexts.
Whitelist Validation
Define acceptable input patterns and reject everything else. For example, names should only contain letters and spaces: /^[a-zA-Z ]*$/
Email Validation
Use RFC 5321/5322 compliant validation methods. PHP's FILTER_VALIDATE_EMAIL follows these standards automatically.
Secure Memory Management
Memory safety errors account for 70% of all vulnerabilities in critical systems. Understanding how memory works in different languages helps prevent leaks, buffer overflows, and other memory-related security issues.
Memory Leaks
Occur when allocated memory is not properly released. In Python, avoid holding unnecessary references to large objects. Use the gc module for cleanup.
Buffer Overflows
Happen when programs write data beyond allocated memory boundaries. While Python prevents direct overflows, deeply nested structures can cause memory errors.
Garbage Collection
Automatic memory management in languages like Python and JavaScript. Use gc.collect() in Python to force cleanup of unused objects.
Memory-Efficient Patterns
Use generators instead of lists for large datasets. Generators yield one item at a time rather than storing everything in memory.
Authentication & Authorization
Authentication ensures only legitimate users can access the system. Authorization determines what authenticated users can do. Both are critical layers of application security.
Authentication
Verifies user identity through credentials like passwords, tokens, or biometrics. Ensures users are who they claim to be.
Authorization
Controls access to resources based on user roles and permissions. Determines what actions authenticated users can perform.
Multi-Factor Authentication
Combines multiple verification methods (something you know, have, or are). Blocks 99.9% of account compromise attacks.
Session Management
Securely handle user sessions with proper timeouts, secure cookies, and session invalidation on logout.
Data Protection & Encryption
Encryption and hashing protect sensitive data from unauthorized access. AES encryption is used by over 70% of secure applications worldwide.
AES Encryption
Advanced Encryption Standard - a symmetric encryption algorithm. Think of it as a super-secret blender that scrambles data using a secret key, only reversible with the same key.
Hashing
One-way transformation of data into a fixed-size string. Used for password storage - you can verify but never reverse the original.
Key Management
Securely store and rotate encryption keys. Never hardcode keys in source code or commit them to version control.
Data at Rest vs Transit
Encrypt data both when stored (at rest) and when transmitted (in transit). Use TLS/HTTPS for all network communications.
Concurrency & Multithreading
Securely managing threads avoids race conditions and data corruption. Deadlocks and race conditions cost organisations millions in downtime.
Deadlock
Two or more threads waiting for each other to release resources, resulting in a standstill. Like two friends each holding a toy the other wants, refusing to let go first.
Race Condition
Unpredictable behavior when multiple threads access shared resources simultaneously. Like two siblings racing to grab the last cookie - whoever reaches first wins.
Thread Synchronization
Use locks, mutexes, and semaphores to coordinate access to shared resources. Prevents data corruption from concurrent modifications.
Thread Safety
Design code that functions correctly when accessed by multiple threads. Avoid shared mutable state where possible.
Secure Design & Deployment
Secure design principles proactively mitigate vulnerabilities. A secure deployment ensures no sensitive data leaks into production.
Secure Design Patterns
Apply security patterns like least privilege, defense in depth, and fail-safe defaults. 'Design is not just what it looks like - design is how it works.' – Steve Jobs
Configuration Management
Misconfigurations are a leading cause of cloud breaches. Never leak secure keys or sensitive config data. Use environment variables and secrets managers.
Container Security
Tools like Docker take a 'snapshot' of a system and deploy it consistently. Containers help avoid configuration drift and environment inconsistencies.
Vulnerability Assessment
Regularly scan for vulnerabilities using automated tools. Perform penetration testing and code reviews to identify security weaknesses.
Labs & Practical Exercises
Work through hands-on activities exploring memory management issues in Python and JavaScript, garbage collection, and memory-efficient programming patterns.
Activity 1: Python Memory Leaks
Create and observe a memory leak using infinite loops. Learn to prevent leaks by managing resources and using the gc module.
Activity 2: JavaScript Memory Leaks
Identify memory leaks caused by retaining references to large objects. Practice releasing references with obj = null.
Activity 3: Garbage Collection
Use Python's gc module to simulate garbage collection. Observe memory usage before and after gc.collect().
Activity 4: Memory-Efficient Data
Refactor code to use generators instead of lists. Understand why generators are more memory-efficient.
Activity 5: Nested Structures
Explore Python's memory limits with deeply nested lists. Understand how memory usage grows with nesting depth.
Tools & Further Reading
VLE Page
Course management and resources.