在页220,C#语言规范版本5.0说:
重要的是......确保查询表达式的结果永远不是源对象本身,因为这将揭示查询客户端的源的类型和标识.
为什么向查询客户端显示源的类型和标识会有问题?
例如,表单的查询表达式from c in customers select c转换为customers.Select(c => c)而不是仅仅customers.
在上面的例子中,在我看来,返回customers客户端将与返回结果一样好customers.Select(c => c).为什么不呢?
尽管Robert McKee的回答是合理的,并提出了一个有趣的观点,但实际上,在编写规范的这一部分时,它实际上并不是我们想到的主要问题.我们实际想到的问题是:
class C
{
private List<int> myList = new List<int>();
// Only the code in C can add items to the list.
public IEnumerable<int> Items
{
get
{
return from item in myList select item;
}
}
}
Run Code Online (Sandbox Code Playgroud)
假设你有一个C.你应该写这段代码吗?
((List<int>)c.Items).Add(123);
Run Code Online (Sandbox Code Playgroud)
列表上存在查询不应该授予获取查询的代码更改列表的能力!它应该授予该代码执行查询的权利,而不是更多.
现在想象一下,List<int>查询实际上是包装数据库调用而不是a .如果调用者可以从查询中获取底层数据库,那么他们可能会对该数据库进行查询或编辑,而查询的作者并不打算这样做.
当然,LINQ并不是一个安全系统,如果它是你想要攻击数据库的代码的唯一防线,你可能很容易受到攻击.但是当所有安全系统的组件使用良好的"纵深防御"时,它们的工作效果更好 永远不会泄漏查询正在查询的集合是防御策略的一部分.
有关此功能的更多信息,请参阅我关于此主题的文章:
| 归档时间: |
|
| 查看次数: |
271 次 |
| 最近记录: |