Runtime Resource Management Control Element in a Component Built to Run on Application Servers
Description
Runtime Resource Management Control Element in a Component Built to Run on Application Servers occurs when an application component that is designed to run on an application server (J2EE, ASP.NET, etc.) directly manages runtime resources such as threads, sockets, database connections, or file handles. Application servers provide managed resource pools and lifecycle management precisely because unmanaged resource creation can lead to resource exhaustion, thread safety issues, and conflicts with the container's resource management. Components should use container-managed resources through JNDI lookups, dependency injection, or other container-provided mechanisms.
Risk
Directly managing resources bypasses the application server's resource pooling and monitoring. This can lead to connection pool exhaustion when components create their own connections. Thread creation outside the container can cause thread leaks and resource exhaustion. Security contexts may not be properly propagated to manually created threads. The container cannot enforce security policies on unmanaged resources. Resource leaks become likely as the container cannot clean up resources it doesn't manage. Denial of service becomes easier when resource limits are not enforced. Debug and monitoring tools lose visibility into unmanaged resources.
Solution
Use container-managed resources through dependency injection or JNDI lookups. For database connections, use DataSource from JNDI rather than creating direct JDBC connections. Use container-managed thread pools (ManagedExecutorService in Java EE) instead of creating threads directly. Let the container manage connection pooling and lifecycle. Use container-provided APIs for asynchronous operations. Configure resource pools in the application server rather than in application code. Follow the application server's best practices for resource management. Use @Resource annotation for injection of container-managed resources.
Common Consequences
| Impact | Details |
|---|---|
| Availability | Scope: Availability DoS: Resource Consumption - Unmanaged resources can exhaust system resources and cause denial of service. |
| Other | Scope: Other Reduce Reliability - Resources not managed by the container may not be properly cleaned up. |
| Access Control | Scope: Access Control Bypass Protection Mechanism - Security contexts may not be properly propagated to unmanaged threads. |
Example Code
Vulnerable Code
// Vulnerable: Creating threads directly in J2EE component
@WebServlet("/process")
public class VulnerableProcessingServlet extends HttpServlet {
// Vulnerable: Creating thread pool directly
private ExecutorService executor = Executors.newFixedThreadPool(10);
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String data = req.getParameter("data");
// Vulnerable: Submitting to unmanaged thread pool
executor.submit(() -> {
// Security context not propagated!
// Container cannot monitor this thread
processData(data);
});
// Vulnerable: Creating raw thread
Thread worker = new Thread(() -> {
// This thread is invisible to container
// No resource limits enforced
heavyProcessing();
});
worker.start(); // Thread leak potential!
resp.getWriter().write("Processing started");
}
// Vulnerable: Thread pool never properly shut down
}
// Vulnerable: Direct JDBC connection management in EJB
@Stateless
public class VulnerableUserRepository {
// Vulnerable: Hardcoded connection parameters
private static final String JDBC_URL = "jdbc:mysql://localhost:3306/users";
private static final String USERNAME = "app_user";
private static final String PASSWORD = "secret123";
public User findById(Long id) {
Connection conn = null;
try {
// Vulnerable: Creating connection directly
// Bypasses container's connection pool!
conn = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD);
PreparedStatement stmt = conn.prepareStatement(
"SELECT * FROM users WHERE id = ?"
);
stmt.setLong(1, id);
ResultSet rs = stmt.executeQuery();
// ... process result
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
// May not be called if exception occurs differently
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// Connection leak!
}
}
}
return null;
}
}
// Vulnerable: Direct socket management in web component
@WebServlet("/notify")
public class VulnerableNotificationServlet extends HttpServlet {
// Vulnerable: Managing sockets directly
private ServerSocket serverSocket;
private List<Socket> clientSockets = new ArrayList<>();
@Override
public void init() throws ServletException {
try {
// Vulnerable: Creating server socket in servlet
// Container cannot manage this resource!
serverSocket = new ServerSocket(9999);
// Vulnerable: Starting acceptor thread directly
new Thread(() -> {
while (!serverSocket.isClosed()) {
try {
Socket client = serverSocket.accept();
clientSockets.add(client); // Not thread-safe!
} catch (IOException e) {
// Silently failing
}
}
}).start();
} catch (IOException e) {
throw new ServletException("Failed to start socket", e);
}
}
@Override
public void destroy() {
// May not be called, leaving resources leaked
try {
serverSocket.close();
for (Socket s : clientSockets) {
s.close();
}
} catch (IOException e) {
// Resources leaked
}
}
}
// Vulnerable: Direct resource management in ASP.NET
public class VulnerableDataController : ApiController
{
// Vulnerable: Creating SqlConnection directly
public async Task<IHttpActionResult> GetData(int id)
{
// Vulnerable: Hardcoded connection string
string connStr = "Server=localhost;Database=mydb;User=sa;Password=secret;";
// Vulnerable: Not using connection pooling properly
using (var connection = new SqlConnection(connStr))
{
await connection.OpenAsync();
// Vulnerable: Starting background thread
Task.Run(() => {
// No HttpContext available
// No request cancellation token
// Security context lost
LogAnalytics(id);
});
// ... rest of processing
}
return Ok();
}
// Vulnerable: Creating background threads directly
private static Thread backgroundWorker;
static VulnerableDataController()
{
// Vulnerable: Static thread creation
backgroundWorker = new Thread(BackgroundProcess);
backgroundWorker.IsBackground = true;
backgroundWorker.Start(); // Thread leak on app domain unload
}
}
Fixed Code
// Fixed: Using container-managed resources in J2EE
@WebServlet("/process")
public class FixedProcessingServlet extends HttpServlet {
// Fixed: Inject container-managed executor service
@Resource
private ManagedExecutorService executorService;
// Fixed: Alternative - lookup from JNDI
// @Resource(lookup = "java:comp/DefaultManagedExecutorService")
// private ManagedExecutorService executorService;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String data = req.getParameter("data");
// Fixed: Use container-managed executor
// Security context is propagated automatically
executorService.submit(() -> {
// Container manages thread lifecycle
// Security context available
processData(data);
});
// Fixed: For scheduled tasks, use ManagedScheduledExecutorService
// @Resource
// private ManagedScheduledExecutorService scheduledExecutor;
resp.getWriter().write("Processing started");
}
// No cleanup needed - container manages resources
}
// Fixed: Using container-managed DataSource in EJB
@Stateless
public class FixedUserRepository {
// Fixed: Inject container-managed DataSource
@Resource(lookup = "java:jboss/datasources/UsersDS")
private DataSource dataSource;
// Alternative: Use JPA with container-managed EntityManager
@PersistenceContext
private EntityManager entityManager;
public User findById(Long id) {
// Fixed: Using JPA - cleanest approach
return entityManager.find(User.class, id);
}
public User findByIdJdbc(Long id) {
// Fixed: If JDBC needed, use container-managed DataSource
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(
"SELECT * FROM users WHERE id = ?")) {
stmt.setLong(1, id);
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
return mapUser(rs);
}
}
} catch (SQLException e) {
throw new EJBException("Database error", e);
}
return null;
}
private User mapUser(ResultSet rs) throws SQLException {
User user = new User();
user.setId(rs.getLong("id"));
user.setUsername(rs.getString("username"));
return user;
}
}
// Fixed: Using JMS for messaging instead of raw sockets
@Stateless
public class FixedNotificationService {
// Fixed: Use container-managed JMS resources
@Resource(lookup = "java:/jms/NotificationConnectionFactory")
private ConnectionFactory connectionFactory;
@Resource(lookup = "java:/jms/NotificationQueue")
private Queue notificationQueue;
// Fixed: Or use injected JMSContext (Java EE 7+)
@Inject
@JMSConnectionFactory("java:/jms/NotificationConnectionFactory")
private JMSContext jmsContext;
public void sendNotification(String message) {
// Fixed: Container manages JMS resources
jmsContext.createProducer()
.send(notificationQueue, message);
}
}
// Fixed: Message-driven bean for async processing
@MessageDriven(activationConfig = {
@ActivationConfigProperty(
propertyName = "destinationType",
propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(
propertyName = "destination",
propertyValue = "java:/jms/NotificationQueue")
})
public class NotificationProcessor implements MessageListener {
@Override
public void onMessage(Message message) {
// Container manages thread pool for MDBs
// Security context properly established
try {
TextMessage textMessage = (TextMessage) message;
processNotification(textMessage.getText());
} catch (JMSException e) {
throw new EJBException(e);
}
}
}
// Fixed: Using dependency injection in ASP.NET Core
public class FixedDataController : ControllerBase
{
private readonly IDbConnection _connection;
private readonly IBackgroundTaskQueue _taskQueue;
private readonly ILogger<FixedDataController> _logger;
// Fixed: Dependencies injected by container
public FixedDataController(
IDbConnection connection,
IBackgroundTaskQueue taskQueue,
ILogger<FixedDataController> logger)
{
_connection = connection;
_taskQueue = taskQueue;
_logger = logger;
}
[HttpGet("{id}")]
public async Task<IActionResult> GetData(int id, CancellationToken cancellationToken)
{
// Fixed: Use injected connection (from pool)
var data = await _connection.QueryFirstOrDefaultAsync<DataModel>(
"SELECT * FROM Data WHERE Id = @Id",
new { Id = id }
);
// Fixed: Queue background work properly
_taskQueue.QueueBackgroundWorkItem(async token =>
{
// CancellationToken propagated
await LogAnalyticsAsync(id, token);
});
return Ok(data);
}
}
// Fixed: Configure services in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// Fixed: Connection pool managed by DI container
services.AddScoped<IDbConnection>(sp =>
{
var conn = new SqlConnection(Configuration.GetConnectionString("Default"));
conn.Open();
return conn;
});
// Fixed: Background task queue with hosted service
services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
services.AddHostedService<QueuedHostedService>();
}
// Fixed: Background service managed by host
public class QueuedHostedService : BackgroundService
{
private readonly IBackgroundTaskQueue _taskQueue;
private readonly ILogger<QueuedHostedService> _logger;
public QueuedHostedService(
IBackgroundTaskQueue taskQueue,
ILogger<QueuedHostedService> logger)
{
_taskQueue = taskQueue;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
var workItem = await _taskQueue.DequeueAsync(stoppingToken);
try
{
await workItem(stoppingToken);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error executing background work");
}
}
}
}
CVE Examples
This CWE is marked as PROHIBITED for direct CVE mapping as it represents a code quality/design concern rather than a direct security vulnerability.
Related CWEs
- CWE-710: Improper Adherence to Coding Standards (parent)
- CWE-400: Uncontrolled Resource Consumption (can lead to)
- CWE-404: Improper Resource Shutdown or Release (related)
- CWE-1058: Invokable Control Element in Multi-Thread Context (related)
References
- MITRE Corporation. "CWE-1065: Runtime Resource Management Control Element in a Component Built to Run on Application Servers." https://cwe.mitre.org/data/definitions/1065.html
- Oracle. "Java EE Tutorial - Concurrency Utilities."
- Microsoft. "Background tasks with hosted services in ASP.NET Core."