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
| Impact | Details |
|---|---|
| Other | Scope: Other Reduce Maintainability - Generated code cannot be maintained without understanding runtime dependencies. |
| Other | Scope: Other Reduce Portability - Code cannot run without specific runtime component. |
| Availability | Scope: 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.
Related CWEs
- 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
- MITRE Corporation. "CWE-1101: Reliance on Runtime Component in Generated Code." https://cwe.mitre.org/data/definitions/1101.html
- Code Generation Best Practices.
- Dependency Management Guidelines.