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
| Impact | Details |
|---|---|
| Other | Scope: Other Reduce Maintainability - Inconsistent code is harder to understand and modify safely. |
| Other | Scope: Other Increase Analytical Complexity - Security analysis becomes more difficult with non-standard code. |
| Other | Scope: 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.
Related CWEs
- CWE-710: Improper Adherence to Coding Standards (parent)
- CWE-1078: Inappropriate Source Code Style or Formatting (child)
- CWE-1225: Documentation Issues (category member)
References
- MITRE Corporation. "CWE-1076: Insufficient Adherence to Expected Conventions." https://cwe.mitre.org/data/definitions/1076.html
- Google Style Guides. https://google.github.io/styleguide/
- PEP 8 - Style Guide for Python Code. https://peps.python.org/pep-0008/