Reliance on Runtime Component in Generated Code

Description

Reliance on Runtime Component in Generated Code occurs when automatically-generated code depends on a specific runtime support component to execute properly. Code generators, compilers, or development frameworks may produce code that cannot function without particular runtime libraries, frameworks, or support modules. This creates a tight coupling between the generated code and its runtime environment, making the code less portable and harder to maintain independently.

Risk

Dependency on specific runtime components in generated code has indirect security implications. Security vulnerabilities in the runtime component affect all generated code. Updates to the runtime may break generated code unexpectedly. The generated code cannot be audited independently of the runtime. Version mismatches between generated code and runtime can cause security issues. Deployment requires managing both the generated code and runtime dependencies. Security fixes in the runtime may not be applied if it breaks compatibility. The opaque nature of generated code makes security review difficult.

Solution

Minimize dependencies on runtime components in code generators. Generate self-contained code where possible. Document all runtime dependencies clearly. Use stable, well-maintained runtime components. Implement version checking between generated code and runtime. Consider generating code that uses standard library features instead of custom runtimes. Provide mechanisms to regenerate code when runtime changes. Test generated code with different runtime versions. Include runtime version requirements in generated code comments or metadata.

Common Consequences

ImpactDetails
OtherScope: Other

Reduce Maintainability - Generated code cannot be maintained without understanding runtime dependencies.
OtherScope: Other

Reduce Portability - Code cannot run without specific runtime component.
AvailabilityScope: Availability

DoS: Crash - Runtime version mismatches can cause crashes.

Example Code

Vulnerable Code

// Vulnerable: Generated ORM code tightly coupled to runtime

// GENERATED CODE - DO NOT EDIT
// This code was generated by MyORMGenerator v2.3

public class GeneratedUserRepository {

    // Vulnerable: Depends on specific runtime component
    private final MyORMRuntime runtime;
    private final MyORMSession session;

    public GeneratedUserRepository() {
        // Vulnerable: Will fail if MyORMRuntime not available
        this.runtime = MyORMRuntime.getInstance();
        this.session = runtime.openSession();
    }

    public User findById(Long id) {
        // Vulnerable: Uses runtime-specific query mechanism
        return runtime.executeQuery(
            MyORMQuery.builder()
                .entity(User.class)
                .where("id", MyORMOperator.EQUALS, id)
                .build()
        ).getSingleResult();
    }

    public List<User> findAll() {
        // Vulnerable: Runtime-specific pagination
        return runtime.createFinder(User.class)
            .withPagination(MyORMPagination.unlimited())
            .execute();
    }

    public void save(User user) {
        // Vulnerable: Runtime transaction management
        runtime.inTransaction(() -> {
            session.persist(user);
        });
    }
}

// Problem: If MyORMRuntime version changes or is unavailable,
// ALL generated repositories break
# Vulnerable: Generated API client dependent on runtime

# AUTO-GENERATED CODE - DO NOT MODIFY
# Generated by APIClientGenerator v1.5
# Requires: api_runtime >= 2.0.0

from api_runtime import (
    APIRuntimeClient,
    RequestBuilder,
    ResponseParser,
    AuthenticationHandler,
    RetryPolicy,
    CircuitBreaker
)


class GeneratedUserServiceClient:
    """Generated client for UserService API."""

    def __init__(self, base_url: str):
        # Vulnerable: Tight coupling to runtime
        self._client = APIRuntimeClient(
            base_url=base_url,
            retry_policy=RetryPolicy.default(),
            circuit_breaker=CircuitBreaker.default()
        )
        self._auth = AuthenticationHandler.oauth2()

    def get_user(self, user_id: str):
        # Vulnerable: Runtime-specific request building
        request = RequestBuilder() \
            .method('GET') \
            .path(f'/users/{user_id}') \
            .with_auth(self._auth) \
            .build()

        response = self._client.execute(request)
        return ResponseParser.parse(response, UserDTO)

    def create_user(self, user_data: dict):
        # Vulnerable: Runtime handles serialization
        request = RequestBuilder() \
            .method('POST') \
            .path('/users') \
            .body(user_data) \
            .with_auth(self._auth) \
            .content_type('application/json') \
            .build()

        response = self._client.execute(request)
        return ResponseParser.parse(response, UserDTO)


# Problem: Upgrading api_runtime may break all generated clients
# Security fixes in api_runtime require testing all generated code
// Vulnerable: Generated serialization code with runtime dependency

// <auto-generated>
// This code was generated by SerializerGenerator v3.1
// Requires: MySerializer.Runtime >= 3.0
// </auto-generated>

using MySerializer.Runtime;
using MySerializer.Runtime.Attributes;
using MySerializer.Runtime.Converters;

[RuntimeSerializable]
public partial class GeneratedUserDTO
{
    // Vulnerable: Runtime-specific attributes
    [RuntimeProperty("id", Required = true)]
    public long Id { get; set; }

    [RuntimeProperty("username")]
    [RuntimeValidation(MinLength = 3, MaxLength = 50)]
    public string Username { get; set; }

    [RuntimeProperty("email")]
    [RuntimeConverter(typeof(EmailConverter))]
    public string Email { get; set; }

    [RuntimeProperty("created_at")]
    [RuntimeConverter(typeof(ISO8601DateConverter))]
    public DateTime CreatedAt { get; set; }

    // Vulnerable: Runtime-generated serialization
    public string Serialize()
    {
        return RuntimeSerializer.Serialize(this);
    }

    public static GeneratedUserDTO Deserialize(string json)
    {
        return RuntimeSerializer.Deserialize<GeneratedUserDTO>(json);
    }
}

// Problem: MySerializer.Runtime changes affect all generated DTOs
// Security vulnerabilities in converters affect all generated code

Fixed Code

// Fixed: Generated code with minimal runtime dependency

// GENERATED CODE
// Generated by ImprovedORMGenerator v3.0
// Runtime dependency: Optional (falls back to standard JDBC)

public class GeneratedUserRepository implements UserRepository {

    private final DataSource dataSource;
    private final Optional<ORMRuntime> runtime;

    // Fixed: Can work with or without runtime
    public GeneratedUserRepository(DataSource dataSource) {
        this.dataSource = dataSource;
        this.runtime = ORMRuntime.tryCreate();
    }

    @Override
    public User findById(Long id) {
        // Fixed: Fallback to standard JDBC if runtime unavailable
        if (runtime.isPresent()) {
            return runtime.get().findById(User.class, id);
        }

        // Self-contained fallback implementation
        return executeQuery(
            "SELECT id, username, email, created_at FROM users WHERE id = ?",
            ps -> ps.setLong(1, id),
            this::mapUser
        );
    }

    @Override
    public List<User> findAll() {
        if (runtime.isPresent()) {
            return runtime.get().findAll(User.class);
        }

        return executeQuery(
            "SELECT id, username, email, created_at FROM users",
            ps -> {},
            this::mapUser
        );
    }

    @Override
    public void save(User user) {
        if (runtime.isPresent()) {
            runtime.get().save(user);
            return;
        }

        // Self-contained save implementation
        executeUpdate(
            "INSERT INTO users (username, email, created_at) VALUES (?, ?, ?)",
            ps -> {
                ps.setString(1, user.getUsername());
                ps.setString(2, user.getEmail());
                ps.setTimestamp(3, Timestamp.from(user.getCreatedAt()));
            }
        );
    }

    // Self-contained helper methods
    private <T> T executeQuery(String sql, PreparedStatementSetter setter,
                               ResultSetMapper<T> mapper) {
        try (Connection conn = dataSource.getConnection();
             PreparedStatement ps = conn.prepareStatement(sql)) {
            setter.set(ps);
            try (ResultSet rs = ps.executeQuery()) {
                // Map results...
                return mapper.map(rs);
            }
        } catch (SQLException e) {
            throw new DataAccessException(e);
        }
    }

    private User mapUser(ResultSet rs) throws SQLException {
        // Self-contained mapping
        User user = new User();
        user.setId(rs.getLong("id"));
        user.setUsername(rs.getString("username"));
        user.setEmail(rs.getString("email"));
        user.setCreatedAt(rs.getTimestamp("created_at").toInstant());
        return user;
    }
}
# Fixed: Generated API client with optional runtime

# AUTO-GENERATED CODE
# Generated by ImprovedAPIGenerator v2.0
# Runtime: Optional (uses standard requests library as fallback)

from typing import Optional, Any
import json

# Try to import optional runtime, fall back to standard library
try:
    from api_runtime import APIRuntimeClient
    HAS_RUNTIME = True
except ImportError:
    HAS_RUNTIME = False
    import requests


class GeneratedUserServiceClient:
    """Generated client with optional runtime dependency."""

    def __init__(self, base_url: str, api_key: Optional[str] = None):
        self._base_url = base_url.rstrip('/')
        self._api_key = api_key

        # Fixed: Optional runtime
        if HAS_RUNTIME:
            self._client = APIRuntimeClient(base_url=base_url)
        else:
            self._client = None
            self._session = requests.Session()

    def get_user(self, user_id: str) -> dict:
        """Get user by ID."""
        if self._client:
            # Use runtime if available
            return self._client.get(f'/users/{user_id}')

        # Self-contained fallback
        response = self._session.get(
            f'{self._base_url}/users/{user_id}',
            headers=self._get_headers()
        )
        response.raise_for_status()
        return response.json()

    def create_user(self, user_data: dict) -> dict:
        """Create a new user."""
        if self._client:
            return self._client.post('/users', json=user_data)

        # Self-contained fallback
        response = self._session.post(
            f'{self._base_url}/users',
            headers=self._get_headers(),
            json=user_data
        )
        response.raise_for_status()
        return response.json()

    def _get_headers(self) -> dict:
        """Get request headers."""
        headers = {'Content-Type': 'application/json'}
        if self._api_key:
            headers['Authorization'] = f'Bearer {self._api_key}'
        return headers


# Alternative: Generate completely self-contained code
class SelfContainedUserClient:
    """Fully self-contained client with no runtime dependencies."""

    def __init__(self, base_url: str, api_key: Optional[str] = None):
        self._base_url = base_url.rstrip('/')
        self._api_key = api_key

    def get_user(self, user_id: str) -> dict:
        import urllib.request
        import urllib.error

        url = f'{self._base_url}/users/{user_id}'
        req = urllib.request.Request(url, headers=self._headers())

        try:
            with urllib.request.urlopen(req) as response:
                return json.loads(response.read().decode())
        except urllib.error.HTTPError as e:
            raise APIError(e.code, e.read().decode())

    def _headers(self) -> dict:
        headers = {'Content-Type': 'application/json'}
        if self._api_key:
            headers['Authorization'] = f'Bearer {self._api_key}'
        return headers
// Fixed: Generated serialization with standard library fallback

// <auto-generated>
// Generated by ImprovedSerializerGenerator v4.0
// Runtime: Optional (uses System.Text.Json as fallback)
// </auto-generated>

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

public partial class GeneratedUserDTO
{
    // Fixed: Standard library attributes work without custom runtime
    [JsonPropertyName("id")]
    public long Id { get; set; }

    [JsonPropertyName("username")]
    public string Username { get; set; }

    [JsonPropertyName("email")]
    public string Email { get; set; }

    [JsonPropertyName("created_at")]
    public DateTime CreatedAt { get; set; }

    // Fixed: Self-contained serialization using standard library
    private static readonly JsonSerializerOptions DefaultOptions = new()
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        WriteIndented = false,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
    };

    public string Serialize()
    {
        return JsonSerializer.Serialize(this, DefaultOptions);
    }

    public static GeneratedUserDTO Deserialize(string json)
    {
        return JsonSerializer.Deserialize<GeneratedUserDTO>(json, DefaultOptions);
    }

    // Fixed: Validation is self-contained
    public ValidationResult Validate()
    {
        var errors = new List<string>();

        if (string.IsNullOrEmpty(Username))
            errors.Add("Username is required");
        else if (Username.Length < 3 || Username.Length > 50)
            errors.Add("Username must be between 3 and 50 characters");

        if (string.IsNullOrEmpty(Email))
            errors.Add("Email is required");
        else if (!IsValidEmail(Email))
            errors.Add("Invalid email format");

        return new ValidationResult(errors.Count == 0, errors);
    }

    private static bool IsValidEmail(string email)
    {
        // Simple email validation without runtime dependency
        var atIndex = email.IndexOf('@');
        if (atIndex < 1) return false;
        var dotIndex = email.LastIndexOf('.');
        return dotIndex > atIndex + 1 && dotIndex < email.Length - 1;
    }
}

public record ValidationResult(bool IsValid, IReadOnlyList<string> Errors);

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-710: Improper Adherence to Coding Standards (parent)
  • CWE-1006: Bad Coding Practices (category member)
  • CWE-1104: Use of Unmaintained Third Party Components (related)

References

  1. MITRE Corporation. "CWE-1101: Reliance on Runtime Component in Generated Code." https://cwe.mitre.org/data/definitions/1101.html
  2. Code Generation Best Practices.
  3. Dependency Management Guidelines.