【问题标题】:Security/Validation on c# property change N-Tierc# 属性更改 N-Tier 的安全/验证
【发布时间】:2017-02-07 22:04:47
【问题描述】:

我有一个跟踪属性变化的类

public class Property
        {
            object _OriginalValue;
            object _ProposedValue;
            DateTime _ProposedDateTime;
            List<Property> _History = new List<Property>();
            public object OriginalValue
            {
                get
                {
                    return _OriginalValue;
                }

                set
                {
                    _OriginalValue = value;
                }
            }
            public object ProposedValue
            {
                get
                {
                    return _ProposedValue;
                }

                set
                {
                    _ProposedDateTime = DateTime.Now;
                    _ProposedValue = value;
                }
            }
            public bool IsDirty
            {
                get
                {

                    if (OriginalValue != ProposedValue)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
        }

这个属性可以被类使用

 public class Customer
        {
            protected Property _FirstName = new Property();
            public string FirstName
            {
                get
                {
                    return (string)_FirstName.ProposedValue;
                }

                set
                {
                    _FirstName.ProposedValue = value;
                }
            }

            public object GetOriginalValue(Property Property)
            {
                return Property.OriginalValue;
            }

        }

问题是,在将原始值传递给 N 层架构中的客户端时,有没有办法保护原始值?

当客户端将客户传递回服务边界时 - 默认情况下您不能信任该客户端。您需要从数据库重新加载原始值或验证原始值是否未被篡改。当然,我假设我们将使用基于客户当前值的业务逻辑来拒绝或允许更新操作。

例子:

用户插入名为 Bob 的记录。

用户获取名称为 Bob 的记录并将名称更改为 Ted。原始值是 Bob,建议值是 Ted。

用户将客户发送到服务以更新客户。

一切都很好。

*现在将业务规则编码到服务中,说明如果客户的名字是 Ted - 允许更新,否则抛出“无法更新”异常。 *

用户获取名为 Ted 的记录。 用户将名称更改为 Darren。 用户将名称改回 Ted - 系统抛出异常。 用户获取 Ted。用户作弊并使用工具更改客户端上的 OriginalPropertyValue。 服务器不会从数据库中重新获取 OriginalValue,而只是读取来自客户端的 OriginalValue。

用户绕过业务规则。

【问题讨论】:

  • 您可能想看看TrackerDog (GitHub repository)。我觉得这会清理你的代码很多:)
  • 完全偏离主题。提供的代码只是为了演示这个想法,而不是实际的生产代码。谢谢。
  • 欢迎以 TrackerDog 为例发布解决方案。在客户端上进行更改,将更改传递给服务器并验证客户端没有更改数据库设置的任何原始值,或者有办法将数据库中的当前值注入原始值。
  • 我建议您使用 TrackerDog 只是为了执行对象更改跟踪,而不是直接回答您的问题。
  • TrackerDog 适用于 xamarin(ios 和 android) - 可通过 .netstandard 1.6 定位?

标签: c# security tampering


【解决方案1】:

实际上,您的方法存在更多问题,而不仅仅是检查 原始值 是否未被篡改。例如,我怀疑这是一个多用户环境,其中不止一个用户能够编辑同一个对象。也就是说,原始值可能没有被篡改,但在其他人已经在数据库中保存了新的原始值之前被更改。。 p>

我猜你已经对你的数据应用了某种乐观或悲观的锁定...

关于您真正关心的问题,可能您需要sign您的原始值,并且每当您要将这些对象存储回数据库时,您的应用程序层应该检查原始值未被篡改(来自维基百科):

数字签名是大多数密码学的标准元素 协议套件,通常用于软件分发, 金融交易、合同管理软件等 检测伪造或篡改很重要的情况。

【讨论】:

  • Matias,在写这篇文章之前,我已经阅读了两种处理方法:重新填充服务器上的值,或者当然应用一些技术来防止篡改。我真正追求的是性能 - 访问数据库的成本更高还是签署原始值的成本更高。某些并发检查会阻止这种类型的攻击(将 where 子句添加到原始值{where name=@Name}),因为如果您没有原始值,这将忽略更新。
  • @Watson 我会采用签名方法。这不是一个复杂的过程,而且今天的CPU非常强大:)我很确定查询数据库有延迟,关于总成本,我们应该进行性能测试...... SQL Server和Redis不一样!
猜你喜欢
  • 2017-08-13
  • 1970-01-01
  • 1970-01-01
  • 2021-05-27
  • 1970-01-01
  • 2011-10-20
  • 2021-10-18
  • 2013-02-14
  • 2014-04-30
相关资源
最近更新 更多