☰
如何为 iniscan 添加自定义规则:从零编写你的第一个安全检测
2026/10/12 3:15:12 网站建设 项目流程
  • 应用安全
  • 开发工具

【免费下载链接】iniscan

A php.ini scanner for best security practices

项目地址:https://gitcode.com/gh_mirrors/in/iniscan
点击查看免费下载

iniscan 是一款面向 PHP 项目的 php.ini 安全扫描器,内置了会话安全、错误显示、文件上传等常见检测项。但默认的 rules.json 无法覆盖你业务里的所有风险点——本教程带你从零开始,10 分钟内为自己的项目添加一条自定义安全检测规则。

🛡️ 先搞清楚:iniscan 的规则是怎么工作的

iniscan 的核心流程很简单:

  1. 解析目标php.ini文件(若文件中没有某个配置项,会用ini_get取运行时默认值兜底);
  2. 逐条执行 rules.json 中定义的规则;
  3. 以 PASS / FAIL 输出结果,并给出对应退出码(0 通过、1 存在失败项)。

每条规则本质上就是"对某个php.ini配置项做一次判断"。添加规则只有两种姿势:

  • 姿势一:改 JSON——用内置的 5 种操作(equals、notequals、isset、greater、smaller)表达简单判断,无需写一行 PHP;
  • 姿势二:写规则类——判断逻辑复杂时,继承 Rule.php 基类,重写evaluate()方法。

规则的加载逻辑在 Scan.php:如果test字段是字符串,就当作Psecio\Iniscan\Rule\命名空间下的类名去实例化;是 JSON 对象则走内置操作。

第一步:安装 iniscan 并跑一次扫描

通过 Composer 安装(依赖仅 Symfony Console):

composer require psecio/iniscan

对任意一份 php.ini 执行首次扫描:

vendor/bin/iniscan scan --path=/path/to/php.ini

常用参数速查:

参数作用
--fail-only只显示未通过的检测项
--threshold=ERROR只显示 ERROR 及以上级别
--context=prod声明环境上下文(如 dev / prod),与规则中的context匹配
--format=json切换为 JSON / XML / HTML 输出

建议先用list-tests命令浏览一遍现有规则,心里有个底:

vendor/bin/iniscan list-tests

第二步:读懂 rules.json 的规则结构

打开 src/Psecio/Iniscan/rules.json,规则按Session、PHP、Extensions、Custom四个分区组织。每条规则只有 4 个字段:

字段说明示例
name规则名称(会展示在结果中)Disable harmful CLI functions
description检测项说明见 rules.json
level严重级别:INFO / WARNING / ERROR / FATALERROR
test判断方式:JSON 对象或自定义类名"test": "CheckSoapWsdlCacheDir"

以一条典型的内置规则为例:

{ "name": "Cookies for sessions", "description": "Accepts cookies to manage sessions", "level": "ERROR", "test": { "key": "session.use_cookies", "operation": "equals", "value": "1" } }

含义一目了然:要求session.use_cookies等于1,否则判 FAIL。test中还支持两个可选字段:

  • version:仅在 PHP 版本 ≥ 指定值时生效,低版本直接标记 N/A(见 Rule.php 的isVersion判断);
  • context:限定执行环境,例如["prod"]表示只在生产上下文检查,开发环境跳过。

第三步(方法一):3 行 JSON 写一条简单规则

如果你的需求只是"某个配置必须等于/不等于某值"或"必须已设置",改 JSON 就够了。

需求:要求生产环境关闭short_open_tag(短标签易引发编码注入风险)。在PHP分区追加:

{ "name": "Disable short_open_tag", "description": "Short tags (<?) are deprecated and error-prone, keep it Off", "level": "WARNING", "test": { "key": "short_open_tag", "operation": "equals", "value": "0", "context": ["prod"] } }

内置操作一览(实现见 Operation.php 抽象基类及其子类):

operation含义典型场景
equals当前值 == value开关项:display_errors = 0
notequals当前值 != value会话 Cookie 不应叫PHPSESSID
isset当前值存在且非空应定义open_basedir
greater当前值 > valueerror_reporting大于 0
smaller当前值 < value(自动处理 2M 等后缀)upload_max_filesize小于 2M

保存后重新执行scan,新规则即刻生效——这就是最快的自定义路径。

第四步(方法二):编写你的第一个自定义规则类

当判断逻辑超出"单个值比较",比如要解析数值、跨配置项联动(例如校验upload_tmp_dir是否位于open_basedir之内),就需要写规则类。参考项目中现成的 MaximumPostSize.php 和 CheckSessionHashFunction.php,套路固定为三步:继承 Rule → 声明检测的 key → 重写 evaluate()。

需求:检测memory_limit = -1(无限制,易被利用发起 DoS)。新建文件,例如src/Psecio/Iniscan/Rule/CheckMemoryLimit.php:

<?php namespace Psecio\Iniscan\Rule; class CheckMemoryLimit extends \Psecio\Iniscan\Rule { public function __construct($config, $section) { parent::__construct($config, $section); $this->setTest(array('key' => 'memory_limit')); } public function evaluate(array $ini) { $limit = $this->findValue('memory_limit', $ini); if ($limit === '-1') { $this->setDescription('memory_limit 不应设为 -1(无限制),易导致内存耗尽'); $this->fail(); return false; } $this->pass(); return true; } }

三个要点:

  1. 命名空间必须是Psecio\Iniscan\Rule——Scan.php 会按该前缀自动拼接类名;
  2. findValue()负责取值:ini 文件里没有该 key 时自动回退到ini_get的默认值(实现见 Rule.php),不用担心缺项报错;
  3. 状态三选一:pass()通过、fail()失败、na()不适用(N/A),并可随时用setDescription()覆盖默认描述,把失败原因写得更具体。

最后,把规则注册进 rules.json 的对应分区,test直接写类名:

{ "name": "Memory limit should not be unlimited", "description": "memory_limit = -1 表示无限制,易被用于资源耗尽攻击", "level": "WARNING", "test": "CheckMemoryLimit" }

第五步:验证你的新规则

# 1. 确认规则已加载 vendor/bin/iniscan list-tests # 2. 只看不通过项,快速验证 FAIL 分支 vendor/bin/iniscan scan --path=/path/to/php.ini --fail-only # 3. 用 JSON 输出确认状态字段 vendor/bin/iniscan scan --path=/path/to/php.ini --format=json

在测试 ini 中把memory_limit = -1和正确值各测一遍,确认规则分别报 FAIL 和 PASS,即大功告成 ✅。若只想为新规则补单元测试,可参照 tests/Psecio/Iniscan/Rule/ 下现有用例的写法。

⚡ 上手速查表

项目说明
级别权重INFO(5) < WARNING(10) < ERROR(20) < FATAL(30),数值见 Rule.php,配合--threshold过滤
版本门槛test.version低于当前 PHP 版本的规则自动 N/A
环境上下文test.context与命令行--context取交集,无交集则跳过
已废弃配置命中 rules.jsondeprecated列表的 key 会被跳过并给出提醒

📌 小结

为 iniscan 添加自定义规则的成本非常低:简单判断改 3 行 JSON,复杂逻辑写一个继承Rule的小类。掌握"key + operation + value"的三元组和evaluate()的 pass/fail/na 三态,你就能把团队的安全基线沉淀成可持续执行的自动化检测。

  • 应用安全
  • 开发工具

【免费下载链接】iniscan

A php.ini scanner for best security practices

项目地址:https://gitcode.com/gh_mirrors/in/iniscan
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询