c#属性更改N层的安全/验证

c#属性更改N层的安全/验证,c#,security,tampering,C#,Security,Tampering,我有一个类可以跟踪属性的变化 public class Property { object _OriginalValue; object _ProposedValue; DateTime _ProposedDateTime; List<Property> _History = new List<Property>(); public ob

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

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;
                    }
                }
            }
        }
问题是,在N层体系结构中将原始值传递给客户机时,是否有一种方法可以保护原始值

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

例如:

用户插入名为Bob的记录

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

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

一切都很好

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

用户获取名为Ted的记录。 用户将名称更改为Darren。 用户将名称更改回Ted-系统引发异常。 用户获取Ted。用户欺骗并使用工具更改客户端上的原始属性值。 服务器不会从数据库中重新提取OriginalValue,而只是从客户端读取OriginalValue


用户绕过业务规则。

实际上,您的方法存在的问题比检查原始值是否未被篡改还要多。例如,我怀疑这是一个多用户环境,多个用户可以编辑同一个对象。也就是说,原始值可能不会被篡改,但在其他人在数据库中保存新的原始值之前,会进行更改

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

关于您实际关心的问题,您可能需要更改原始值,并且每当您要将这些对象存储回数据库时,您的应用程序层应该检查原始值是否未被篡改(来自Wikipedia):

数字签名是大多数密码技术的标准元素 协议套件,并且通常用于软件分发, 财务交易、合同管理软件和其他 发现伪造或篡改的重要案例


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

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

关于您实际关心的问题,您可能需要更改原始值,并且每当您要将这些对象存储回数据库时,您的应用程序层应该检查原始值是否未被篡改(来自Wikipedia):

数字签名是大多数密码技术的标准元素 协议套件,并且通常用于软件分发, 财务交易、合同管理软件和其他 发现伪造或篡改的重要案例


您可能想看看()。我觉得这会大大清理你的代码:)完全脱离主题。提供的代码只是为了演示这个想法,而不是实际的生产代码。谢谢。请以TrackerDog为例发布解决方案。在客户端上进行更改,将更改传递给服务器,并验证客户端是否未更改数据库设置的任何原始值,或者是否有方法将数据库中的当前值注入原始值。我建议您使用TrackerDog只是为了执行对象更改跟踪的一部分,不是直接回答您的问题。TrackerDog适用于xamarin(ios和android)-可由.netstandard 1.6作为目标?您可能想看看()。我觉得这会大大清理你的代码:)完全脱离主题。提供的代码只是为了演示这个想法,而不是实际的生产代码。谢谢。请以TrackerDog为例发布解决方案。在客户端上进行更改,将更改传递给服务器,并验证客户端是否未更改数据库设置的任何原始值,或者是否有方法将数据库中的当前值注入原始值。我建议您使用TrackerDog只是为了执行对象更改跟踪的一部分,不是为了直接回答你的问题。TrackerDog适用于xamarin(ios和android)-可由.netstandard 1.6?Matias作为目标,在写这篇文章之前,我读过两种处理方法:在服务器上重新填充值,当然也可以应用一些技术使其防篡改。我真正追求的是性能——是访问数据库的成本更高,还是签署原始值的成本更高。某些并发检查会阻止这种类型的攻击(将where子句添加到原始值{where name=@name}),因为如果您没有原始值,这将忽略更新。@Watson我会选择签名方法。这不是一个复杂的过程,今天的CPU功能非常强大:)我很确定查询数据库会有延迟,关于总成本,我们应该做一个性能测试。。。SQL Server和Redis是不一样的!Matias,在写这篇文章之前,我读过两种处理方法:在服务器上重新填充值,当然也可以应用一些技术使其防篡改。我真正追求的是性能——是访问数据库的成本更高,还是签署原始值的成本更高。某些并发检查将阻止这种类型的攻击(将where子句添加到原始值{where name=@name}),因为如果您没有ori,这将忽略更新
 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;
            }

        }