Callable with Insufficient Behavioral Summary

Description

Callable with Insufficient Behavioral Summary occurs when code contains a function or method whose signature and/or associated inline documentation does not sufficiently describe the callable's inputs, outputs, side effects, assumptions, or return codes. Without adequate behavioral documentation, developers using the function may misuse it, leading to bugs, security vulnerabilities, or unexpected behavior. This is especially critical for security-sensitive functions where callers need to understand preconditions, postconditions, and error handling requirements.

Risk

Insufficient behavioral summaries have indirect security implications. Callers may not properly validate inputs if requirements aren't documented. Return codes indicating errors or security issues may be ignored. Side effects affecting security state may not be anticipated. Assumptions about thread safety or reentrancy may be violated. Resource cleanup requirements may not be understood. Security-critical preconditions may not be met. Error handling paths may be incorrectly implemented. Functions may be called in insecure contexts due to missing usage guidance.

Solution

Document all function parameters with types, valid ranges, and constraints. Document return values including all possible return codes and their meanings. Explicitly state side effects (file system, network, global state modifications). Document preconditions that must be met before calling. Document postconditions that are guaranteed after the call. Specify thread safety characteristics. Document exceptions that may be thrown and when. Include security-relevant warnings. Provide usage examples. Keep documentation synchronized with implementation. Use documentation generation tools (Javadoc, Doxygen, Sphinx).

Common Consequences

ImpactDetails
OtherScope: Other

Reduce Maintainability - Makes it more difficult to maintain the product, which indirectly affects security by making it more difficult or time-consuming to find and fix vulnerabilities.
IntegrityScope: Integrity

Improper Use - Without clear behavioral documentation, callers may misuse functions in ways that compromise security.

Example Code

Vulnerable Code

// Vulnerable: Function with insufficient behavioral summary

public class UserService {

    // What does this return on failure? null? throws?
    // What inputs are valid?
    // What side effects does it have?
    public User authenticate(String u, String p) {
        // ...
    }

    // What happens if user is null?
    // What permissions are required?
    // What does the int return mean?
    public int updateUser(User user) {
        // ...
    }

    // Does this throw on error or return null?
    // What if the user doesn't exist?
    // Is this thread-safe?
    public User findById(long id) {
        // ...
    }

    // What are "options"? What are valid values?
    // What happens with invalid options?
    public void process(Map<String, Object> options) {
        // ...
    }

    // What errors can occur? How are they reported?
    // What happens if connection fails partway through?
    public void syncToRemote() {
        // ...
    }
}
# Vulnerable: Python functions without proper documentation

def validate(data, rules):
    # What format is data? dict? string? object?
    # What format are rules? How are they applied?
    # What does it return? True/False? Validated data? Errors?
    pass


def encrypt(text, key):
    # What algorithm is used?
    # What format is the key? bytes? string? length requirements?
    # What encoding does it return?
    # What errors can occur?
    pass


def connect(host, opts=None):
    # What are valid opts? What's the default behavior?
    # What does it return? A connection object? Nothing?
    # How do you close the connection?
    # What exceptions might be raised?
    pass


def process_payment(amount, card):
    # What's the format of amount? cents? dollars? Decimal?
    # What's the format of card? dict? object? string?
    # What happens on failure?
    # Is the charge atomic?
    pass
// Vulnerable: C functions without behavioral documentation

// What is max length? What happens on overflow?
// Does this null-terminate? Who owns the memory?
char* copy_string(char* dest, char* src);

// Return values: -1 error? 0 success? Or opposite?
// What errors are possible? How to get error details?
int process_data(void* data, int len);

// Does this free the pointer? Set it to NULL?
// Can you call this multiple times safely?
void cleanup(void* resource);

// What happens with NULL callback?
// When is callback invoked? What thread?
// What's the lifetime of user_data?
void register_callback(void (*cb)(int), void* user_data);
// Vulnerable: JavaScript with insufficient documentation

// What is config? What properties are expected?
// What does it return? Promise? Value? undefined?
function initialize(config) {
    // ...
}

// Does this sanitize? Encode? Validate?
// What inputs are considered "safe"?
function processUserInput(input) {
    // ...
}

// How should errors be handled?
// What format is the response?
// Are there rate limits?
async function fetchData(url, options) {
    // ...
}

// What are the valid operations?
// What's the return type?
// Does this modify global state?
function execute(operation, params) {
    // ...
}

Fixed Code

// Fixed: Complete behavioral documentation

public class UserService {

    /**
     * Authenticate a user with username and password.
     *
     * <p>Validates the provided credentials against the user store
     * and returns the authenticated user if successful.
     *
     * <p><strong>Security:</strong> Failed attempts are logged and
     * rate-limited. Passwords are compared using constant-time comparison.
     *
     * @param username The username, must be non-null and 1-50 characters.
     *                 Case-insensitive comparison is used.
     * @param password The plaintext password, must be non-null.
     *                 Not logged or stored.
     * @return The authenticated User object with session token populated
     * @throws IllegalArgumentException if username or password is null
     * @throws AuthenticationException if credentials are invalid
     * @throws AccountLockedException if account is locked due to failed attempts
     * @throws RateLimitException if too many attempts in short period
     *
     * @see #logout(User) to end the session
     * @see User#getSessionToken() for the generated token
     */
    public User authenticate(String username, String password)
            throws AuthenticationException, AccountLockedException, RateLimitException {
        // ...
    }

    /**
     * Update user profile information.
     *
     * <p>Updates the user's profile in the database. Only non-null fields
     * in the provided User object are updated (partial update).
     *
     * <p><strong>Thread Safety:</strong> This method is thread-safe.
     * Concurrent updates to the same user are serialized.
     *
     * <p><strong>Permissions:</strong> Caller must have UPDATE_USER permission
     * or be updating their own profile.
     *
     * @param user The user with updated fields. Must not be null.
     *             The user.id must correspond to an existing user.
     * @return Number of fields that were modified:
     *         <ul>
     *           <li>0 = No changes made (values same as existing)</li>
     *           <li>1+ = Number of fields updated</li>
     *           <li>-1 = User not found</li>
     *         </ul>
     * @throws IllegalArgumentException if user is null or user.id is null
     * @throws PermissionDeniedException if caller lacks required permissions
     * @throws ValidationException if any field values are invalid
     */
    public int updateUser(User user)
            throws PermissionDeniedException, ValidationException {
        // ...
    }

    /**
     * Find a user by their unique ID.
     *
     * <p><strong>Thread Safety:</strong> Thread-safe for concurrent reads.
     *
     * @param id The user's unique ID. Must be positive.
     * @return The User if found, or null if no user exists with that ID.
     *         The returned User is a detached copy; modifications do not
     *         affect the stored user.
     * @throws IllegalArgumentException if id is less than 1
     */
    public User findById(long id) {
        // ...
    }
}
# Fixed: Python with comprehensive documentation

def validate(data: dict, rules: list[ValidationRule]) -> ValidationResult:
    """
    Validate data dictionary against a set of validation rules.

    Applies each rule to the data and collects validation errors.
    Rules are applied in order; all rules are evaluated even if
    early rules fail.

    Args:
        data: Dictionary of field names to values to validate.
              All values must be JSON-serializable types.
        rules: List of ValidationRule objects defining constraints.
               Empty list is valid (returns success with no checks).

    Returns:
        ValidationResult containing:
        - is_valid: True if all rules passed, False otherwise
        - errors: List of ValidationError for each failed rule
        - validated_data: Copy of data with type coercions applied

    Raises:
        TypeError: If data is not a dict or rules is not a list
        ValueError: If any rule is malformed

    Example:
        >>> rules = [Required('name'), MaxLength('name', 50)]
        >>> result = validate({'name': 'John'}, rules)
        >>> result.is_valid
        True

    Security Note:
        This function does NOT sanitize data for SQL or HTML.
        Use SqlParameterizer or HtmlEscaper after validation.

    Thread Safety:
        This function is thread-safe and has no side effects.
    """
    pass


def encrypt(
    plaintext: bytes,
    key: bytes,
    algorithm: str = 'AES-256-GCM'
) -> tuple[bytes, bytes, bytes]:
    """
    Encrypt data using authenticated encryption.

    Uses the specified algorithm with a random IV/nonce.
    The authentication tag is included for integrity verification.

    Args:
        plaintext: Data to encrypt. Maximum size: 64MB.
        key: Encryption key. Must be:
             - 32 bytes for AES-256-GCM (default)
             - 32 bytes for ChaCha20-Poly1305
        algorithm: Encryption algorithm. Supported values:
                   - 'AES-256-GCM' (default, recommended)
                   - 'ChaCha20-Poly1305'

    Returns:
        Tuple of (ciphertext, nonce, auth_tag):
        - ciphertext: Encrypted data (same length as plaintext for GCM)
        - nonce: Random 12-byte nonce (must be stored with ciphertext)
        - auth_tag: 16-byte authentication tag

    Raises:
        ValueError: If key length doesn't match algorithm requirements
        ValueError: If algorithm is not supported
        ValueError: If plaintext exceeds 64MB
        CryptoError: If encryption fails (rare, usually system issue)

    Example:
        >>> key = secrets.token_bytes(32)
        >>> ciphertext, nonce, tag = encrypt(b'secret', key)
        >>> decrypt(ciphertext, key, nonce, tag)
        b'secret'

    Security Notes:
        - Never reuse a (key, nonce) pair
        - Store nonce and auth_tag with ciphertext; they're not secret
        - Key must be kept secret and generated securely
    """
    pass

CVE Examples

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


  • CWE-1078: Inappropriate Source Code Style or Formatting (parent)
  • CWE-1006: Bad Coding Practices (category member)
  • CWE-1111: Incomplete I/O Documentation (related)
  • CWE-1116: Inaccurate Comments (related)

References

  1. MITRE Corporation. "CWE-1117: Callable with Insufficient Behavioral Summary." https://cwe.mitre.org/data/definitions/1117.html
  2. Javadoc Documentation Guidelines
  3. Python PEP 257 - Docstring Conventions
  4. "Clean Code" by Robert C. Martin