在Ubuntu系统中,xrandr是管理屏幕显示配置的核心工具,支持调整分辨率、旋转屏幕等操作。当需要通过PHP脚本远程触发屏幕旋转时,直接调用系统命令存在命令注入等安全风险,需要采用规范的方式实现安全执行。
安全执行的核心原则
在PHP中执行系统命令时,必须遵循最小权限原则和安全过滤原则,避免直接将用户输入拼接到命令中。对于xrandr这类需要特定权限的命令,还需要合理配置用户权限,避免赋予过高的系统权限。
权限配置准备
首先确保执行PHP脚本的用户拥有调用xrandr的权限,通常Web服务器运行用户为www-data,需要将该用户加入视频组,否则可能无法访问显示设备:
# 将www-data用户加入视频组 sudo usermod -aG video www-data # 重启Web服务使权限生效 sudo systemctl restart apache2
命令安全过滤
禁止直接拼接用户输入到xrandr命令中,需要预先定义允许的旋转参数,通过白名单方式过滤输入内容。xrandr支持的旋转参数包括normal、left、right、inverted,仅允许这些参数传入。
完整实现代码示例
以下是通过PHP安全执行xrandr屏幕旋转命令的完整代码,包含参数校验、命令转义、执行结果处理等逻辑:
<?php
/**
* 安全执行xrandr屏幕旋转命令
* @param string $rotation 旋转参数,仅允许指定值
* @return array 执行结果数组
*/
function safeXrandrRotate($rotation) {
// 定义允许的旋转参数白名单
$allowedRotations = ['normal', 'left', 'right', 'inverted'];
// 校验参数是否在白名单中
if (!in_array($rotation, $allowedRotations)) {
return [
'success' => false,
'message' => '无效的旋转参数,仅支持normal、left、right、inverted'
];
}
// 拼接基础命令,使用escapeshellarg转义参数,避免命令注入
$baseCmd = 'xrandr';
// 获取当前连接的显示器名称,默认取第一个活跃显示器
$getDisplayCmd = $baseCmd . ' --query | grep " connected" | cut -d " " -f1';
$display = shell_exec($getDisplayCmd);
$display = trim($display);
if (empty($display)) {
return [
'success' => false,
'message' => '未检测到连接的显示器'
];
}
// 拼接旋转命令,对显示器名称和旋转参数都做转义处理
$rotateCmd = sprintf(
'%s --output %s --rotate %s',
$baseCmd,
escapeshellarg($display),
escapeshellarg($rotation)
);
// 执行命令并获取输出和返回码
exec($rotateCmd, $output, $returnCode);
if ($returnCode === 0) {
return [
'success' => true,
'message' => '屏幕旋转执行成功',
'output' => $output
];
} else {
return [
'success' => false,
'message' => '屏幕旋转执行失败,返回码:' . $returnCode,
'output' => $output
];
}
}
// 调用示例,仅允许传入白名单内的参数
$result = safeXrandrRotate('left');
if ($result['success']) {
echo '操作成功:' . $result['message'];
} else {
echo '操作失败:' . $result['message'];
}
?>
注意事项
- 不要将xrandr命令的执行权限赋予root用户,仅赋予必要的视频组权限即可,降低安全风险。
- 如果PHP运行在CLI模式下,需要确保当前用户有访问显示环境的权限,可能需要设置DISPLAY环境变量,例如
putenv('DISPLAY=:0');。 - 生产环境中建议对命令执行过程添加日志记录,便于排查异常问题,同时避免将命令执行的详细输出直接返回给前端用户。
- 定期更新Ubuntu系统和PHP版本,修复已知的安全漏洞,进一步提升脚本运行的安全性。