klebann/moodle-psalm-plugin

一个用于检测使用 SQL 的 $DB 方法不安全的 Psalm 插件

v2.2 2021-01-13 13:57 UTC

This package is auto-updated.

Last update: 2024-09-14 21:15:41 UTC


README

Moodle Psalm-Plugin (MPP) 是一个 Psalm 插件,可以找出所有易受 SQL 注入攻击的 $DB->methods 并显示 SQL 查询的内容。

该脚本仅用于查找和展示您应审查的代码。

安装

$ composer require --dev klebann/moodle-psalm-plugin
$ vendor/bin/psalm-plugin enable klebann/moodle-psalm-plugin

使用

psalm-plugin.xmlissueHandlers.xml 复制到 Psalm 根目录,并根据您的特定需求进行修改。

从 /path/to/moodle/local/psalm 运行 Psalm 并扫描 /path/to/moodle/mod/checklist 插件

$ ./vendor/bin/psalm --config=psalm-plugin.xml --no-diff --show-info=true ../../mod/checklist

从 /path/to/moodle/local/psalm 运行 Psalm 并扫描 /path/to/moodle/mod/checklist/lib.php 文件

$ ./vendor/bin/psalm --config=psalm-plugin.xml --no-diff --show-info=true ../../mod/checklist/lib.php

在 psalm/vendor/klebann/moodle-psalm-plugin 中为 测试 运行 Psalm

$ ../../bin/psalm --config=psalm.xml --no-diff --show-info=true

说明

创建用于自动为 moodle 插件进行以安全性为重点的代码审查

"为了防止 SQL 注入,始终在查询中使用数据占位符(? 或 :named)将用户数据传递到查询中。" ~ 数据操作 API - 占位符

示例

PHP

if ($checklist->teacheredit == CHECKLIST_MARKING_STUDENT) {
    $date = ', MAX(c.usertimestamp) AS datesubmitted';
    $where = 'c.usertimestamp > 0';
} else {
    $date = ', MAX(c.teachertimestamp) AS dategraded';
    $where = 'c.teachermark = '.CHECKLIST_TEACHERMARK_YES;
}

$total = count($items);

list($usql, $uparams) = $DB->get_in_or_equal($users);
list($isql, $iparams) = $DB->get_in_or_equal(array_keys($items));

$namefields = get_all_user_name_fields(true, 'u');

$sql = 'SELECT u.id AS userid, (SUM(CASE WHEN '.$where.' THEN 1 ELSE 0 END) * ? / ? ) AS rawgrade'.$date;
$sql .= ' , '.$namefields;
$sql .= ' FROM {user} u LEFT JOIN {checklist_check} c ON u.id = c.userid';
$sql .= " WHERE u.id $usql";
$sql .= " AND c.item $isql";
$sql .= ' GROUP BY u.id, '.$namefields;

$params = array_merge($uparams, $iparams);
$params = array_merge(array($checklist->maxgrade, $total), $params);

$grades = $DB->get_records_sql($sql, $params);

输出(此示例将在下一个版本中跳过,因为它安全)

INFO: PossibleSqlInjection - ../../mod/checklist/lib.php:342:24 - Calling unsafe sql method $DB->get_records_sql
Description:
    Safe variable $namefields: created by get_all_user_name_fields()
    Safe variable $usql: created by get_in_or_equal()
    Safe variable $isql: created by get_in_or_equal()
SQL:
    SELECT u.id AS userid, (SUM(CASE WHEN $namefields([c.usertimestamp > 0][c.teachermark = CHECKLIST_TEACHERMARK_YES]) THEN 1 ELSE 0 END) * ? / ? ) AS rawgrade $date([, MAX(c.usertimestamp) AS datesubmitted][, MAX(c.teachertimestamp) AS dategraded]) , $namefields FROM {user} u LEFT JOIN {checklist_check} c ON u.id = c.userid WHERE u.id $usql AND c.item $isql GROUP BY u.id, $namefields
Documentation -
        $grades = $DB->get_records_sql($sql, $params);