【问题标题】:How can I update a specific record without SELECT permission?如何在没有 SELECT 权限的情况下更新特定记录?
【发布时间】:2012-01-11 23:19:38
【问题描述】:

我想执行这样的事情:

  UPDATE grades SET status="pass" WHERE recno=123;

但是,我希望执行更新的用户帐户对数据库具有只写访问权限,这意味着它没有 SELECT 访问权限。这会导致 WHERE 子句失败。

如果有必要,我实际上可以重写整个记录,但是recno是主键,这会导致写入失败。有什么办法吗

INSERT INTO grades (recno,name,status,...) VALUES (123, 'chemistry', 'pass',...)
  ON DUPLICATE KEY UPDATE <everything>;

或者这是错误的方法?此外,这也不是“更新特定记录中的特定字段”问题的通用解决方案。

【问题讨论】:

  • 更多信息:我有一个将日志写入远程服务器的应用程序。该应用程序将在程序开始时写入一条新记录,状态为“未完成”。此步骤将从 Mysql 服务器接收自动生成的 recno 值。该过程完成后,我想用新值修改该记录的状态字段。由于任何人都可以在应用程序上运行字符串并获取其登录凭据,因此我需要授予该帐户对数据库的只写访问权限。
  • “每个人都可以在数据库上运行字符串”是什么意思?您授予每个人对您的数据库写入的访问权限?这听起来很危险。
  • 我的意思是任何人都可以在应用程序上运行字符串。例如。任何人都可以对应用程序进行逆向工程并找出它的登录凭据是什么。因此,我想将该登录限制为仅对其运行所必需的那些操作。
  • 您意识到有人可以只做UPDATE grades SET status=NULL 并且您数据库中的所有记录都会被破坏。您所以需要创建一个您的应用程序可以查询的 API。
  • 正如我在下面的回答中提到的,正确的方法是创建一个 API,您的用户可以通过该 API 与您的数据库进行通信。

标签: mysql


【解决方案1】:

这是保护桌子的一种特殊方式。在某些情况下,这可能是有意义的,但通常您希望提供一些可见性窗口,以便用户不会对他们对数据的影响视而不见。

要完全实现只写数据库,请使用存储过程。这些过程可以拥有对数据库的完全访问权限,而用户只能被授予对存储过程的访问权限。

【讨论】:

  • 我认为这是最好的答案。现在学习如何编写存储过程。
  • 好吧,这很有效,尽管攻击者仍然可以通过猜测 recno 值来破坏数据库。我想出了一个安全协议来防止这种情况。感谢大家的帮助。
【解决方案2】:

创建一个VIEW 并授予用户对其的完全访问权限。此视图应仅包含您希望用户能够编辑的行。

另一种可能更合适的方法是将这种机制从 DBMS 中完全抽象出来,而是创建一个允许用户查询的 API。

【讨论】:

    【解决方案3】:

    这很容易通过授予正确的访问级别来实现:

    REVOKE ALL ON TABLE GRADES FROM USER1; -- to clear out all privileges
    GRANT INSERT, UPDATE, DELETE ON TABLE GRADES TO USER1;
    

    这将允许 USER1 从成绩表中插入、更新和删除,但不能选择。

    根据需要将USER1 更改为PUBLIC 或某个组或其他任何内容。
    根据需要更改权限列表。


    您的情况是我曾经教过的 IBM 数据库课程中经典示例的一个版本: 财务人员可以加薪百分比,但不能查看员工的薪酬水平,所以

    GRANT UPDATE ON TABLE EMPLOYEE TO ACCT_STAFF; -- an no other privileges
    

    这使他们可以通过执行以下方式获得 15% 的加薪:

    UPDATE EMPLOYEE SET PAY = PAY * 1.15 WHERE EMPLOYEE_ID = 666;
    

    【讨论】:

    • 这基本上是我已经做过的,但是“WHERE recno=123”子句需要 SELECT 权限。例如。 "ERROR 1143 (42000): SELECT 命令拒绝用户 'ACCT_STAFF' 用于表 'EMPLOYEE' 中的列 'EMPLOYEE_ID'
    • @EdwardFalk 您可以在更新语句中使用WHERE recno=123 没有对表的选择访问权限。我不明白你在说什么。
    • 我刚刚在 5.1.41-3ubuntu12.10 下尝试使用您提供的确切命令并收到此错误:“ERROR 1143 (42000): SELECT command denied to user 'ACCT_STAFF'@'foo.com ' 用于表 'EMPLOYEE' 中的列 'EMPLOYEE_ID'”。也许更新版本的服务器允许这样做。我当然同意它应该有效,但它没有。
    • 这里与10.1.37-MariaDB-0+deb9u1 相同,而UPDATEWHERE 也需要SELECT 权限。
    【解决方案4】:

    哦!我懂了。我将为我的用户仅授予 recno 列的 SELECT 权限。

    但请保持问题开放,以防万一有人提出更好的答案。

    【讨论】:

      猜你喜欢
      • 2013-07-15
      • 2021-01-05
      • 2017-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-21
      • 2010-09-17
      • 1970-01-01
      相关资源
      最近更新 更多