-
-
Notifications
You must be signed in to change notification settings - Fork 69.1k
[Bug]: Session manager cache checks TTL but never deletes expired entries #6761
Copy link
Copy link
Closed as not planned
Closed as not planned
Copy link
Labels
bugSomething isn't workingSomething isn't workingstaleMarked as stale due to inactivityMarked as stale due to inactivity
Description
CVSS Assessment
| Metric | Value |
|---|---|
| Score | 6.5 / 10.0 |
| Severity | Medium |
| Vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H |
Summary
The SESSION_MANAGER_CACHE checks TTL on read but never deletes expired entries, causing a slow memory leak where stale cache entries accumulate indefinitely.
Affected Code
File: src/agents/pi-embedded-runner/session-manager-cache.ts:10
const SESSION_MANAGER_CACHE = new Map<string, SessionManagerCacheEntry>();
function isSessionManagerCached(sessionFile: string): boolean {
// ...
const entry = SESSION_MANAGER_CACHE.get(sessionFile);
if (!entry) {
return false;
}
const now = Date.now();
const ttl = getSessionManagerTtl();
return now - entry.loadedAt <= ttl; // Checks TTL but doesn't delete!
}
export function trackSessionManagerAccess(sessionFile: string): void {
// ...
SESSION_MANAGER_CACHE.set(sessionFile, {
sessionFile,
loadedAt: now,
});
// No pruning of expired entries anywhere
}Attack Surface
How is this reached?
- Network (HTTP/WebSocket endpoint, API call)
- Adjacent Network (same LAN, requires network proximity)
- Local (local file, CLI argument, environment variable)
- Physical (requires physical access to machine)
Authentication required?
- None (unauthenticated/public access)
- Low (any authenticated user)
- High (admin/privileged user only)
Entry point: Agent session creation and access tracking.
Exploit Conditions
Complexity:
- Low (no special conditions, works reliably)
- High (requires race condition, specific config, or timing)
User interaction:
- None (automatic, no victim action needed)
- Required (victim must click, visit, or perform action)
Prerequisites: Gateway must be running embedded agents with session tracking.
Impact Assessment
Scope:
- Unchanged (impact limited to vulnerable component)
- Changed (can affect other components, escape sandbox)
What can an attacker do?
| Impact Type | Level | Description |
|---|---|---|
| Confidentiality | None | No data disclosure |
| Integrity | None | No data modification |
| Availability | High | Slow memory leak causes eventual OOM |
Steps to Reproduce
- Run gateway with embedded agent sessions
- Create many unique session files over time
- Each session file path adds an entry to
SESSION_MANAGER_CACHE - TTL expires, but entries remain in the Map
isSessionManagerCachedreturns false for expired entries, but doesn't delete them- Map grows monotonically over gateway lifetime
- Eventually OOM occurs
Recommended Fix
Delete expired entries when checking TTL:
function isSessionManagerCached(sessionFile: string): boolean {
const entry = SESSION_MANAGER_CACHE.get(sessionFile);
if (!entry) {
return false;
}
const now = Date.now();
const ttl = getSessionManagerTtl();
if (now - entry.loadedAt > ttl) {
SESSION_MANAGER_CACHE.delete(sessionFile); // Delete expired entry
return false;
}
return true;
}Or add periodic pruning:
function pruneExpiredEntries(): void {
const now = Date.now();
const ttl = getSessionManagerTtl();
for (const [sessionFile, entry] of SESSION_MANAGER_CACHE) {
if (now - entry.loadedAt > ttl) {
SESSION_MANAGER_CACHE.delete(sessionFile);
}
}
}References
- CWE: CWE-401 - Missing Release of Memory after Effective Lifetime
- Related (CWE-401): [Bug]: Browser bridge server has optional authentication #6609, [Bug]: Browser control server vulnerable to DNS rebinding attacks #4949, [Bug]: Timing Attack Vulnerability in Token Comparisons #6021, [Bug]: Timing Attack Vulnerability in Token Comparisons #6022
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingstaleMarked as stale due to inactivityMarked as stale due to inactivity
Type
Fields
Give feedbackNo fields configured for issues without a type.