Insufficient Adherence to Expected Conventions

Description

Insufficient Adherence to Expected Conventions occurs when a product's architecture, source code, design, documentation, or other artifacts do not follow required conventions. Conventions include coding standards, naming conventions, API contracts, documentation requirements, and architectural patterns that are established for a project, language, or framework. When conventions are not followed, the resulting code becomes harder to understand, maintain, and audit for security issues.

Risk

Violating conventions has indirect security implications. Code that doesn't follow conventions is harder to review for security vulnerabilities. Unexpected behavior from convention violations may create exploitable conditions. Security tools and static analyzers may miss vulnerabilities in non-conventional code. Other developers may make incorrect assumptions based on conventions, introducing bugs. Framework security features may not work correctly if conventions aren't followed. Inconsistent code increases the likelihood of copy-paste errors that duplicate vulnerabilities.

Solution

Establish and document coding conventions for the project. Use linters and static analysis tools to enforce conventions automatically. Include convention compliance in code review checklists. Use IDE configurations that format code according to conventions. Apply automated formatting on commit hooks. Follow language and framework conventions (PEP 8 for Python, Google Java Style, etc.). Document exceptions to conventions and their rationale. Train developers on project conventions. Use pair programming to share convention knowledge.

Common Consequences

ImpactDetails
OtherScope: Other

Reduce Maintainability - Inconsistent code is harder to understand and modify safely.
OtherScope: Other

Increase Analytical Complexity - Security analysis becomes more difficult with non-standard code.
OtherScope: Other

Quality Degradation - Convention violations often correlate with other quality issues.

Example Code

Vulnerable Code

// Vulnerable: Multiple convention violations
public class userAccount {  // Violation: class should be PascalCase (UserAccount)

    // Violation: constants should be UPPER_SNAKE_CASE
    private static final int maxRetries = 3;

    // Violation: inconsistent naming - some camelCase, some not
    private String UserName;  // Should be userName
    private String password_hash;  // Should be passwordHash

    // Violation: public field instead of private with getter
    public boolean isactive;

    // Violation: method names should be camelCase verbs
    private void DoSomething() {  // Should be doSomething
    }

    // Violation: violates JavaBean convention
    public String GetUserName() {  // Should be getUserName
        return UserName;
    }

    // Violation: inconsistent brace style
    public void authenticate(String password)
    {
        if(password == null){
            return;
        }  // Inconsistent spacing around keywords
    }

    // Violation: magic numbers instead of constants
    public void setRetryLimit(int limit) {
        if (limit > 10) {  // What is 10? Should be MAX_RETRY_LIMIT
            limit = 10;
        }
    }
}
# Vulnerable: PEP 8 violations
import os,sys  # Violation: imports should be on separate lines
from typing import *  # Violation: wildcard imports

class userAccount:  # Violation: class names should be PascalCase
    MaxRetries = 3  # Violation: should be MAX_RETRIES for constant

    def __init__(self,userName,Password):  # Violation: no spaces after commas
        self.UserName = userName  # Violation: should be user_name
        self.__password = Password  # Violation: should be _password (single underscore)

    def GetUser(self):  # Violation: should be get_user (snake_case)
        return self.UserName

    def check_Password(self, pwd):  # Violation: inconsistent naming
        if pwd==self.__password:  # Violation: no spaces around operators
            return True
        else:
            return False

    # Violation: using bare except
    def LoadData(self):
        try:
            data = readfile()
        except:  # Catches everything including SystemExit!
            pass

    # Violation: mutable default argument
    def add_permissions(self, perms=[]):
        self._permissions = perms
// Vulnerable: .NET convention violations
public class user_manager  // Violation: should be UserManager
{
    // Violation: public fields instead of properties
    public string userName;
    public string Password;  // Also: sensitive data should be private

    // Violation: method naming inconsistency
    public void get_user() { }  // Should be GetUser
    public void UpdateUser() { }  // Correct, but inconsistent with above

    // Violation: not following IDisposable pattern correctly
    public class FileHandler : IDisposable
    {
        private FileStream _file;

        public void Dispose()
        {
            _file.Close();  // Should use Dispose pattern properly
        }
        // Missing: virtual Dispose(bool), finalizer consideration
    }

    // Violation: async method naming
    public async Task loadDataAsync()  // Should be LoadDataAsync (capital L)
    {
        await Task.Delay(100);
    }

    // Violation: inconsistent parameter naming
    public void ProcessOrder(int OrderId, string customerName)  // Should be orderId
    {
    }
}
// Vulnerable: JavaScript convention violations
// Violation: var instead of const/let
var USER_TIMEOUT = 1000;

// Violation: inconsistent casing
function GetUserData(userId) {  // Should be getUserData
    // Violation: == instead of === for comparison
    if (userId == null) {
        return;
    }
}

class userService {  // Violation: should be UserService
    // Violation: no semicolons (if project convention requires them)
    constructor() {
        this.Users = []  // Violation: should be this.users
    }

    // Violation: inconsistent method naming
    async FetchUser(id) {  // Should be fetchUser
        // Violation: using callback instead of modern async/await
        return new Promise((resolve,reject) => {  // Spacing issues
            setTimeout(() => {
                resolve({id: id})
            },100)  // Spacing issues
        })
    }

    // Violation: modifying function parameters
    processUsers(users) {
        users.push({id: 0});  // Mutating input parameter
        return users;
    }
}

Fixed Code

// Fixed: Following Java conventions
public class UserAccount {  // PascalCase for class names

    // Constants in UPPER_SNAKE_CASE
    private static final int MAX_RETRIES = 3;
    private static final int MAX_RETRY_LIMIT = 10;

    // Private fields in camelCase
    private String userName;
    private String passwordHash;
    private boolean isActive;

    // Constructor
    public UserAccount(String userName) {
        this.userName = userName;
        this.isActive = true;
    }

    // Getter methods following JavaBean convention
    public String getUserName() {
        return userName;
    }

    public boolean isActive() {
        return isActive;
    }

    // Setter methods
    public void setActive(boolean active) {
        this.isActive = active;
    }

    // Methods in camelCase with verb prefixes
    public void authenticate(String password) {
        if (password == null) {
            return;
        }
        // Authentication logic
    }

    // Using named constants
    public void setRetryLimit(int limit) {
        if (limit > MAX_RETRY_LIMIT) {
            limit = MAX_RETRY_LIMIT;
        }
        // Set limit
    }

    // Consistent brace style and spacing
    public boolean validateCredentials(String password) {
        if (password == null || password.isEmpty()) {
            return false;
        }
        return verifyPasswordHash(password);
    }
}
# Fixed: Following PEP 8 conventions
import os
import sys
from typing import List, Optional


class UserAccount:
    """User account management following PEP 8 conventions."""

    MAX_RETRIES = 3  # Class constant

    def __init__(self, user_name: str, password: str) -> None:
        """Initialize user account.

        Args:
            user_name: The user's name
            password: The user's password
        """
        self.user_name = user_name  # snake_case for attributes
        self._password = password  # Single underscore for protected

    def get_user(self) -> str:
        """Get the username."""
        return self.user_name

    def check_password(self, pwd: str) -> bool:
        """Check if password matches.

        Args:
            pwd: Password to check

        Returns:
            True if password matches, False otherwise
        """
        return pwd == self._password

    def load_data(self) -> Optional[dict]:
        """Load user data from file.

        Returns:
            User data dict or None if loading fails
        """
        try:
            data = self._read_file()
            return data
        except FileNotFoundError:
            # Specific exception handling
            return None
        except PermissionError:
            # Handle permission issues
            return None

    def add_permissions(
        self,
        perms: Optional[List[str]] = None
    ) -> None:
        """Add permissions to user.

        Args:
            perms: List of permission strings
        """
        # Fixed: Avoid mutable default argument
        if perms is None:
            perms = []
        self._permissions = list(perms)  # Create copy
// Fixed: Following .NET conventions
public class UserManager : IDisposable
{
    // Private fields with underscore prefix (common convention)
    private readonly string _connectionString;
    private bool _disposed;

    // Properties instead of public fields
    public string UserName { get; private set; }

    // Constructor
    public UserManager(string connectionString)
    {
        _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
    }

    // PascalCase for public methods
    public User GetUser(int userId)
    {
        // Implementation
        return null;
    }

    public void UpdateUser(User user)
    {
        // Implementation
    }

    // Async methods end with Async
    public async Task<Data> LoadDataAsync(CancellationToken cancellationToken = default)
    {
        await Task.Delay(100, cancellationToken);
        return new Data();
    }

    // Consistent parameter naming (camelCase)
    public void ProcessOrder(int orderId, string customerName)
    {
        // Implementation
    }

    // Proper IDisposable implementation
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                // Dispose managed resources
            }
            _disposed = true;
        }
    }
}
// Fixed: Following JavaScript/ES6 conventions
const USER_TIMEOUT = 1000;

// Function names in camelCase
function getUserData(userId) {
    // Strict equality comparison
    if (userId === null || userId === undefined) {
        return null;
    }
    return fetchUser(userId);
}

// Class names in PascalCase
class UserService {
    constructor() {
        // Property names in camelCase
        this.users = [];
        this.isInitialized = false;
    }

    // Method names in camelCase
    async fetchUser(id) {
        // Modern async/await
        await this.ensureInitialized();

        const response = await fetch(`/api/users/${id}`);
        if (!response.ok) {
            throw new Error(`Failed to fetch user: ${response.status}`);
        }

        return response.json();
    }

    // Don't mutate input parameters
    processUsers(users) {
        // Create new array instead of mutating
        return [...users, { id: 0 }];
    }

    // Private method convention (or use # for true private)
    async _ensureInitialized() {
        if (!this.isInitialized) {
            await this.initialize();
        }
    }

    // Consistent semicolons and spacing
    initialize() {
        this.isInitialized = true;
        return Promise.resolve();
    }
}

export { UserService, getUserData };

CVE Examples

This CWE is marked as PROHIBITED for direct CVE mapping as it represents a code quality/convention concern rather than a direct security vulnerability.


  • CWE-710: Improper Adherence to Coding Standards (parent)
  • CWE-1078: Inappropriate Source Code Style or Formatting (child)
  • CWE-1225: Documentation Issues (category member)

References

  1. MITRE Corporation. "CWE-1076: Insufficient Adherence to Expected Conventions." https://cwe.mitre.org/data/definitions/1076.html
  2. Google Style Guides. https://google.github.io/styleguide/
  3. PEP 8 - Style Guide for Python Code. https://peps.python.org/pep-0008/