The failure is that the PAC processor can reuse a stack allocated ArrayBuffer allocator after its lifetime ends. When JavaScript inside FindProxyForUrl creates an ArrayBuffer, V8 follows a stale virtual pointer that has been overwritten by later stack data. That can crash the service and, with the right conditions, create a path toward code execution in a privileged Android process.
How a Long-Lived Android PAC Service Becomes Fragile Under Untrusted JavaScript
The core problem is lifetime mismatch. The PAC engine assumes the allocator and surrounding stack state remain valid while JavaScript executes, but a long-lived system service stretches that assumption across calls. Once the callback path creates a fresh allocator lifetime dependency, stale pointers can outlive the memory they reference and turn a parsing or evaluation step into memory corruption.
That is why the bug is not simply “JavaScript is dangerous”. The break occurs at the boundary between embedded script execution and native memory ownership. A PAC function that is safe in a short-lived test path can become unstable in a daemon that processes many requests, because the service preserves state and re-enters the script engine with assumptions that no longer hold.
In practice, this kind of failure is most likely when the service mixes native stack data, callback-driven script execution, and objects whose lifetime is not explicitly tied to the script invocation. Once the allocator is reclaimed, later stack activity can overwrite the memory shape V8 expects, so a benign ArrayBuffer allocation becomes a read or write through invalid state.
Why the Crash Path Can Escalate Beyond Availability
The immediate symptom is usually a crash, watchdog restart, or service instability. But the security significance comes from the fact that the corrupted state sits inside a privileged Android process that is running attacker-influenced JavaScript. If an attacker can reliably shape the overwritten stack data, the same lifetime bug can move from denial of service to a path toward code execution.
That escalation depends on more than one bug class. The exploitability hinges on whether the stale pointer can be reused in a way that gives useful control over object layout, whether the PAC service remains reachable with attacker-controlled input, and whether the process has enough privilege to make post-exploitation impact meaningful. The native memory bug is therefore the enabling condition, while the service context determines blast radius.
This is also why untrusted PAC logic is a higher-risk design than many teams first assume. PAC scripts are often treated as simple routing helpers, but they are still code running inside a sensitive runtime. If that code is attacker-controlled or exposed through a malicious configuration path, the service is effectively evaluating untrusted logic in a privileged environment.
What This Bug Teaches About Embedded Script Boundaries
The bug class is a reminder that embedded scripting needs explicit ownership and lifetime rules, especially when the host process is persistent. A safe interface must make it impossible for script-created objects to inherit references to stack-backed state that disappears after the callback returns. If the host cannot guarantee that, then the implementation should avoid reusing native allocations across invocations or should move the risky work out of the privileged service.
It also shows why memory safety bugs in “support” code matter even when the script itself is not the direct target. The JavaScript engine is only the trigger. The actual break happens because native code exposed an object lifetime assumption that the engine can violate once it allocates, retains, or reuses memory in a different order than the host expected.
Risk and Threat Considerations
Long-lived system services magnify a memory-safety flaw because repeated requests create many opportunities to hit the bad lifetime edge. If attacker-influenced PAC logic can be invoked on demand, the bug becomes both a reliability issue and a potential privilege boundary issue inside a trusted process.
Failure mechanism: A stack allocated allocator or related native object is reused after the stack frame ends, so later JavaScript execution follows a stale pointer into overwritten memory.
Impact: The service can crash immediately, and under the right memory layout and control conditions the same corruption can support code execution in a privileged Android process.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
MITRE ATT&CK addresses the attack and risk surface, while NIST SP 800-53 Rev 5, OWASP ASVS and CIS Controls v8 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| MITRE ATT&CK | T1055 — Process Injection | Privileged-process memory corruption can enable attacker-controlled code execution. |
| Recommendation — Map exploitability to ATT&CK and validate detections for suspicious memory corruption chains. | ||
| NIST SP 800-53 Rev 5 | SI-7 — Software, Firmware, and Information Integrity | The bug is a code integrity and runtime safety failure in a privileged service. |
| Recommendation — Apply SI-7-style integrity checks and harden privileged runtime paths against corruption. | ||
| OWASP ASVS | V15 — Secure Coding and Architecture | The issue comes from unsafe native lifetime handling at a script/runtime boundary. |
| Recommendation — Enforce secure architecture review for native objects exposed to embedded script engines. | ||
| CIS Controls v8 | CIS-16 — Application Software Security | The defect is an application security flaw in embedded JavaScript handling. |
| Recommendation — Prioritise code review and testing for memory-safety defects in embedded script features. | ||
Practitioner Guidance
What to verify: Treat every callback boundary in a PAC implementation as a lifetime audit point. Confirm that any allocator, buffer, or native handle referenced by script-exposed objects survives for the full execution window of the JavaScript engine, not just for the duration of the surrounding C/C++ frame.
Common mistake: Assuming that “short helper script” means “low risk”. In a system service, even small scripts inherit the privilege and stability requirements of the host, so a one-line PAC expression can still reach memory management code that must be correct under repeated, adversarially shaped inputs.
Practitioner takeaway: The real control objective is to make native lifetime rules impossible to violate from the script boundary; if the host cannot do that cleanly, isolate the PAC evaluation path so a memory-safety failure cannot become a privileged-process compromise.
Related resources from NHI Mgmt Group
Deepen Your Knowledge
Free weekly newsletter
Subscribe to the NHI & AI Identity Journal
The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.
Bonus 33% off our NHI Course when you subscribe.
Reviewed and updated by the NHIMG editorial team on September 29, 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org