← All projects

State-Sensitive System Call Filtering for PHP

An HTTP request moves through dispatch and PHP script states, each paired with its syscall allow-list; conventional seccomp uses one shared allow-list.
Conventional filtering (left) uses a single process-wide allow-list containing system calls that may be needed anywhere during PHP execution, leaving those calls available throughout the process. State-sensitive filtering (right) tracks PHP execution and updates the kernel-enforced allow-list as execution moves between states, allowing only the system calls needed in the current context.

System-call filtering is an important building block for sandboxing. It can reduce the damage an attacker can cause after gaining code-execution capability, but its effectiveness depends on how precisely the allowed behavior is defined.

Conventional approaches often apply a single syscall allow-list to an entire process or request. For PHP applications such as WordPress, that scope can cover many scripts and functions executing through the PHP runtime. To support legitimate execution, the policy must allow system calls needed anywhere within that scope. Consequently, a syscall required by one part of the application remains available in other parts that do not need it. An attacker who compromises those parts can use these unnecessary permissions without violating the filter.

Our approach makes syscall filtering aware of where the PHP application is currently executing. Rather than applying one allow-list throughout execution, the system associates different execution states with different syscall policies. As the application moves between states, user-space instrumentation signals the Linux kernel to update the active state and enforce its corresponding policy.

This narrows the operations available to an attacker: a syscall is no longer permitted simply because it is needed somewhere in the application—it must also be allowed in the current execution state.

Project resources: Paper