什么是一种简单的方法来判断一行数据是否已被更改?

时间:2013-01-10 20:07:43

标签: sql sql-server database security

如果我有一行数据,如:

1, 2, 3

我可以创建一个校验和值,它是所有列的总和,1 + 2 + 3 = 6.我们可以将此值与第4列中的行一起存储:

1, 2, 3, 6

然后,我可以编写一个程序来检查列中的任何值是否意外更改,如果列的总和与校验和值不匹配。

现在,我想更进一步。假设我有一个值表,任何人都可以读/写访问最后一列数据的位置,如前所述,前一列的总和。

1, 2, 3, 6

假设某人想偷偷摸摸并改变第三栏中的值

1, 2, 9, 6

校验和很容易重现,因此偷偷摸摸的个人可以将校验和值更改为1 + 2 + 9 = 12,以便此行看起来不会被篡改。

1, 2, 9, 12

现在我的问题是,如何在不使校验和不再有效的情况下制作更复杂的校验和值,以便偷偷摸摸的个人无法进行此类更改?也许我可以创建一个blackbox exe,因为行的前三个值可以给出一个更复杂的校验和,如:

a^2 + b^2 + c^2

但是虽然这个逻辑对于一个偷偷摸摸的用户是未知的,但他/她仍然可以将值输入到黑盒子exe中并获得有效的校验和。

关于如何确保表格中的所有行都未被遮挡的任何想法?我试图避免的方法是每次使用我创建的程序合法修改表时保存表的副本。这是可能的,但似乎是一个非常不优雅的解决方案。必须有更好的方法,对吧?

4 个答案:

答案 0 :(得分:1)

使用基本数学,校验和无效:

a^2 +b^2 +c^2  

a=0,b=0,c=2  = checksum 4
a=2,b=0,c=0  = checksum 4

如果您想为用户提供一组“只读”数据,请考虑使用物化视图。物化视图将计算一个时间段的计算,即您的有效数据并将其提供给用户,而您的程序可以在后台进行修改。

此外,这就是为什么存在权限的原因,如果您只提供无法修改数据库以进行实例只读访问的帐户,这可以减轻某人篡改数据的问题。此外,您无法完全阻止恶意用户篡改数据,只能让他们跳过几个圈,希望他们暂时感到无聊/被阻止。

安全方面没有灵丹妙药,你可以做的是使用深度思维模式,包括以下功能:

  

广泛记录,
      划分责任,
      工作轮换,
      补丁管理,
      审核日志(与日志记录一起使用,但实际上有人必须阅读它们),
      实施HIPS系统(主机入侵防御系统),
      拒绝外部与数据库的连接

该清单可以继续进行。

答案 1 :(得分:1)

您似乎在问,“我如何为运行它的用户提供一组不同的安全权限?”执行此操作的方法是确保程序在不同的安全上下文中运行给用户。这样做的方式因平台而异。

如果您有多台计算机,那么运行客户端服务器架构可能会有所帮助。您通过服务器公开受控API,它具有数据库的安全凭据。然后您的用户无法发出任意请求。

如果您是客户端计算机的管理员,而用户不是,那么您可以让单独的进程执行类似的操作。例如。 unix中的守护进程。我认为Windows中的DCOM可以让你做这样的事情。

另一种方法是通过存储过程公开您的API,并仅授予对这些API的访问权限,而不是直接访问该表。

对受限制的API进行受控访问可能还不够。例如,考虑一个在游戏中存储高分的表。如果用户可以输入任意值,则只能通过ClaimHighScore API访问它并不重要。游戏中的解决方案通常很复杂。我听说过的唯一方法是根据给出初始游戏状态的种子值来定义API,然后使用时间戳来定义一组输入。然后服务器必须基本上模拟游戏以验证分数。

答案 2 :(得分:1)

用户不应对表进行无约束的写访问。更好的是为常见的CRUD操作创建sprocs。这可以让您控制他们可以修改哪些字段,如果您坚持可以更新CRC()校验和或其他验证。

这将是一个很大的项目,所以它现在可能不实用 - 但它应该是如何完成的。

答案 3 :(得分:0)

虽然您的问题是基于数据库的恶意条目,但MOD11的使用可能会发现不准确或错位的值。

以下MySQL语句和SQLfiddle说明了这个

SELECT id, col1, col2, col3, col4, checknum,
9 - MOD(((col1*5)+(col2*4)+(col3*3)+(col4*2) ),9) 
AS Test FROM  `modtest` HAVING checknum =Test