- Principle of Least Privilege: Grant the minimal set of permissions necessary for a component to function. For example, a database user should only have SELECT access on required tables, not full schema modification rights.
- Defense in Depth: Layer multiple security controls so that if one fails, others still protect. Combine input validation, authentication, encryption, and monitoring to reduce risk.
- Fail Securely: When an error occurs, the system should deny access by default. A database connection failure should reject the request rather than exposing a stack trace or defaulting to an open state.
- Secure by Default: Default configurations should be secure. Disable debug modes, unused services, and default credentials in production environments from the start.
- Input Validation: All external input must be validated for type, length, format, and range before processing. Reject invalid data early rather than sanitizing later.
- Output Encoding: Encode data before rendering it in different contexts (HTML, JavaScript, SQL) to prevent injection attacks. Context-specific encoding is critical.
- Separation of Duties: Different roles should have different responsibilities. The person who writes code should not also deploy it to production without a review process.
- Security by Design: Security considerations must be integrated from the initial design phase, not added as an afterthought. Use threat modeling early in the SDLC.
- Complete Mediation: Every access to every object must be checked for authorization. Do not rely on cached or previously granted permissions. For example, revalidate the user’s rights on each file read operation even if the file was opened moments before.
- Avoid Security by Obscurity: Relying on hidden implementation details or secret algorithms is not a trustworthy defense. Assume attackers know the system architecture. Instead, use proven cryptographic standards and well tested security controls that remain secure even when fully disclosed.
- Secure Coding Standards: Adhere to established secure coding guidelines such as OWASP or CERT recommendations. Enforce these rules through peer reviews and automated static analysis tools to identify vulnerabilities like buffer overflows or injection flaws before deployment.
- Logging and Monitoring: Record security relevant events including authentication attempts, access denials, and input validation failures. Protect logs from unauthorized modification and ensure they contain enough detail (timestamps, user IDs, source IPs) to support incident investigation.
def validate_input(user_input): if not isinstance(user_input, str): return False if len(user_input) > 100: return False if not user_input.isalnum(): return False return TrueThis function validates that input is a string of alphanumeric characters up to 100 characters. Rejection of invalid input follows the secure default of treating unvalidated data as dangerous.
- Least privilege minimizes the attack surface by granting only necessary permissions.
- Defense in depth uses multiple layers of security controls.
- Failing securely denies access on errors to avoid information leakage.
- Secure defaults ensure out-of-the-box protection.
- Input validation and output encoding are fundamental prevention techniques.