首页 > 解决方案 > 保护操作数据库的发布请求

问题描述

我正在开发一个反应应用程序,它应该是 WooCommerce 商店管理区域的一部分。为了在我的反应应用程序中拥有更多自由,创建了一些 ajax 端点,它们调用操作数据库的函数:

因为它是一个响应式应用程序,所以访问 JS 代码的每个人都能看到 JS 函数发出了一个 post 请求。这显然是非常不安全的,并且可以被滥用。为了避免这种情况,我集成了以下安全方法:

JS函数

const insertDb = async (table, columns, values) => {
    const data = {
        action: 'insertDb',
        table: table,
        columns: columns,
        values: values
    }

    const rsp = await axios.post("/wp-admin/admin-ajax.php", qs.stringify(data))
    return rsp.data
}

PHP 函数

function insertDb($table, $columns, $values) {
    if (current_user_can('administrator') && substr($table, 0, 6) === "mytable") {
        global $wpdb;
        $table = $wpdb->prefix . $table;
        $values = str_replace("\\", "", $values);

        $sql = "INSERT INTO $table ($columns) VALUES ($values);";
        $wpdb->query($sql);
        $id = $wpdb->insert_id;

        return $id;

    } else {
        return false;
    }
}

这仍然不安全吗?我怎样才能改进它?最佳做法是什么?

谢谢!!

标签: phpreactjsajaxdatabaserest

解决方案


最好在服务器代码中定义您希望允许的突变,而不是允许客户端(如果以适当的权限登录)将任意行插入到您的数据库中。

至少:

  • 添加允许列表$table以检查它是否是应该更新的表

最好:

  • 将有效负载更改为例如 JSON,这样您将获得更丰富的类型,然后
  • $columns从字符串数组中解析
  • $values从数组中解析,然后使用准备好的查询和占位符

甚至更优选地,如所述:

  • 将查询限制为已知良好的集合(例如“添加带有标题和文本的页面”、“添加其他内容”)——这样你基本上会得到一个(REST)API 的东西

推荐阅读