You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP API结构安全增强咨询:如何防范远程代码执行风险

How to Fix Remote Code Execution Risk in PHP API Routing

Great question—your colleague is 100% correct to flag this critical security flaw. Directly executing a user-controlled function name like $endpoint[1]() gives attackers free rein to call any global function on your server, from phpinfo() (which exposes sensitive system details) to dangerous execution functions like exec() or shell_exec(). Here’s how to lock down your API properly:

1. Implement Strict Function Whitelisting (Non-Negotiable)

The most effective fix is to define exactly which functions are allowed for each controller, and reject any request that falls outside this list. This ensures only your intended functions can be called.

For example, in your controller file (e.g., ../controllers/User.php), add a whitelist at the top:

// Define allowed functions for this controller
$allowedFunctions = ['getProfile', 'updateSettings', 'listOrders'];

// Check if the requested function is in the whitelist
if (!in_array($endpoint[1], $allowedFunctions)) {
    echo json_encode(StatusCodes["invalid_function"]);
    die();
}

Then, in your routing logic, after including the controller file, run this check before executing the function. Even if an attacker tries to call phpinfo() or a malicious custom function, it’ll be blocked immediately.

2. Switch to Object-Oriented Controllers (More Secure & Maintainable)

Instead of using global functions, wrap your controller logic in classes. This adds an extra layer of control—you can restrict calls to public methods only, and avoid exposing global scope functions entirely.

Example Controller Class:

// ../controllers/UserController.php
class UserController {
    public function getProfile() {
        // Your logic here
        return ['status' => 'success', 'data' => $userData];
    }

    public function updateSettings() {
        // Your logic here
        return ['status' => 'success'];
    }
}

Updated Routing Logic:

// Build controller class name (e.g., "User" becomes "UserController")
$controllerClassName = ucfirst($endpoint[0]) . 'Controller';
$controllerFile = '../controllers/' . $controllerClassName . '.php';

// Validate controller file exists
if (!file_exists($controllerFile)) {
    echo json_encode(StatusCodes["no_endpoint"]);
    die();
}
include_once($controllerFile);

// Validate class exists
if (!class_exists($controllerClassName)) {
    echo json_encode(StatusCodes["no_endpoint"]);
    die();
}

$controller = new $controllerClassName();
$requestedMethod = $endpoint[1];

// Define allowed methods for this controller
$allowedMethods = ['getProfile', 'updateSettings'];

// Check: method exists, is public, and is in the whitelist
if (!method_exists($controller, $requestedMethod) || 
    !is_callable([$controller, $requestedMethod]) ||
    !in_array($requestedMethod, $allowedMethods)) {
    echo json_encode(StatusCodes["no_function"]);
    die();
}

// Execute the allowed method
echo json_encode($controller->$requestedMethod());

This approach limits attackers to only the public methods you explicitly allow, and prevents them from accessing global functions or sensitive class methods.

3. Validate & Sanitize All User-Controlled Input

Never trust the request_uri segments—validate that they only contain safe characters to prevent path traversal or injection attacks. Use regex to enforce strict rules:

// Validate controller name: only letters, numbers, underscores (no slashes, dots, etc.)
if (!preg_match('/^[a-zA-Z0-9_]+$/', $endpoint[0])) {
    echo json_encode(StatusCodes["invalid_endpoint"]);
    die();
}

// Validate function/method name: same safe character rules
if (!preg_match('/^[a-zA-Z0-9_]+$/', $endpoint[1])) {
    echo json_encode(StatusCodes["invalid_function"]);
    die();
}

This blocks attempts to use paths like ../includes/ApiSettings.php as a controller name, which could expose sensitive files or execute unintended code.

4. Disable Dangerous Global Functions (As a Safety Net)

While this isn’t a replacement for whitelisting, you can disable high-risk PHP functions in your php.ini file to add an extra layer of protection:

disable_functions = phpinfo,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

This prevents attackers from calling these functions even if they bypass your other checks. Note that this is a fallback, not a primary defense—always rely on whitelisting first.

Key Takeaway

The root problem here is trusting unfiltered user input to execute code. The only reliable way to fix this is to explicitly allow only the functions/methods you intend to expose, rather than trying to block every possible bad function. Whitelisting combined with OOP controllers and input validation will eliminate the remote code execution risk.

内容的提问来源于stack exchange,提问作者Harvey Fletcher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:00:55