【问题标题】:Obfuscate HTTP Handler designed to return image旨在返回图像的混淆 HTTP 处理程序
【发布时间】:2013-05-21 16:07:54
【问题描述】:

我正在尝试从 HTTP 处理程序中检索图像。

我遇到的一个问题是试图让只有应用程序才能访问图像,我尝试编辑匿名 IIS 身份验证以允许应用程序池标识,但这仍然允许用户通过。

这是一个例子:

  1. ASPX 页面调用通过查询字符串传入 ID 的处理程序 (picService.ashx?id=1)
  2. HTTP 处理程序发回图像
  3. 图片来源为Services/picService.ashx?id=1

这一切都很好。现在,如果用户想要访问 picService.ashx 并输入任何旧 ID,它将返回与该 ID 相关的图像。我正在处理敏感信息,所以这是不可接受的。

我查看了 HTTP Forbidden 处理程序,但我不确定我是否走在正确的道路上。

我也尝试在 ASPX 页面中返回图像,但由于图像控件需要 URL,因此您无法执行此操作。

如何从数据库中返回图像并确保图像来源安全?

我应该以不同的方式来做这件事吗?还是我在正确的轨道上(http 被禁止)?

【问题讨论】:

  • 客户端不能直接访问服务和检索图像。这个问题是关于实现这一目标的多种方式。
  • 为什么你需要接受混淆而不是强制执行适当的安全性?
  • 适当的安全存在?用户被授权使用该资源(因为他们需要检索图像),但问题在于调用 Web 服务。查看我对 Devesh 的评论

标签: c# asp.net iis-7 webforms


【解决方案1】:

我过去使用的一种技术是让页面(第 1 步)创建一个 GUID,并注册一个由 GUID 键入的缓存项,该 GUID 具有对象中的实际图像 URL。页面使用 GUID 构造处理程序的 url 并传递给处理程序

处理程序(步骤 2)然后知道去缓存以获取实际值并返回内容。

这样你只暴露了临时的“魔法”值。它绝对是令人困惑的,不能替代适当的安全性。

举个例子(根据记忆,语法可能有点不对)

在 aspx 或调用者中

    string keyValue = Guid.NewGuid().ToString();
    int yourImageID = 5;

    Cache.Add(keyValue, yourImageID) //expire in 5 or 10 seconds
    string url = "Handler.ashx?imgID=" + HttpUtility.UrlEncode(keyValue);
    Response.Redirect(url, false);

在您的处理程序中(我主要使用 ashx,选择适合您需要的任何内容)

 string key = HttpUtility.UrlDecode(context.Request.QueryString.Get("imgID"));

 int yourImageID = (int) context.Cache.Get(key);

 //get your image from the db and return the content

同样,我使用了 guid 并不意味着您必须这样做,但如果您试图混淆 IDentity,请选择与 IDentity 无关的内容。

【讨论】:

  • 你能举个例子吗? (我不知道我很害怕)我正在考虑使用单向散列 ID(ID 是按顺序生成的 8 位值),将其存储在一个表中,然后查找实际值,但这不会如果客户端知道要查询的内容是安全的,因为所有用户都知道他们的 ID 是什么以及明显的数据库开销。
  • 这很好用。感谢所有的帮助,标记为答案,尽管胸腺嘧啶提出了同样的建议,但你是第一个,也是一个不错的例子。
【解决方案2】:

您提出问题的方式无法保证 100% 安全。那么你愿意允许哪些取舍,哪些不允许呢?

您到底想防止什么?只有一个用户没有看到另一个用户的图像?或者也阻止right-click, save image as

想到的一个想法是将用户的 ip 地址与图像的 id 相结合,对其进行哈希处理,然后将其放入缓存中(或使用 guid 作为键来查找这些值)。可能在使用该哈希后将其从缓存中删除,因此只允许 one ip per page 加载图像一次开启。

您应该可以将生成的ID和真实之间的映射扔到会话中,或者HttpRuntime.Cache.Insert(cacheName, cachedValue)数据库可能不是最好的答案,它们是少量数据,您可以将过期时间设置为小价值,所以除非你同时拥有数百万用户......

使用 Flash 控件加载图像将是安全的,因为无法右键单击将图像另存为。如果您担心有人截取图像流,也可能会加密流,或拆分图像标头或其他东西。他们仍然可以获得图像的 url,但您的 flash 控件可能会使用普通用户难以理解的特殊标题。

【讨论】:

  • 感谢您提出的所有想法和挑战。每个用户将需要在每页看到多个图像,这些图像可以一次又一次地刷新和显示。编辑:: 意外按下回车。关于会话到期的好点。那里有很多不同的事情要考虑。我对用户下载图像没有问题,因为他们应该能够首先访问它们。我担心的是任何人都可以使用 ID 查询处理程序,然后检索图像。
  • 我想我会说只生成一个随机数或 GUID,然后将该映射映射到一个 Id 一段时间。仅 ID 的单向哈希不会真正起作用,您需要一些不基于实际 ID 的东西,因此它无法在逻辑上生成。您能否更改数据库以使用 GUID 作为主键?这将解决您的许多问题,而无需额外的映射层
  • 很遗憾,数据库是由供应商提供的,因此这个问题的重要性不足以保证进行如此大的更改,ID 是最重要的唯一标识符之一。明天我将研究缓存和会话到期,以及哪一个是最好的。
  • 会话一直持续到变量被删除或会话结束(注销、超时)。缓存有一个更谨慎的过期模型。
  • 这听起来很像一个身份验证问题。您不希望未经身份验证的用户能够访问图像,并且您希望经过身份验证的用户只能访问他们应该有权访问的那些图像。
【解决方案3】:

首先,您必须知道您认为什么可以显示照片。您的身份验证参数是什么。就像如果用户在经过身份验证时允许查看图片一样,请在允许查看之前在 ashx 页面中检查相同的内容。因为在 html 中调用 src 或将其放在浏览器中对 server 没有任何影响。所以你需要检查一些验证,以防用户根本不应该以任何方式直接或直接看到

【讨论】:

  • 我明白你的意思,但在这种情况下使用经过身份验证的信息并没有帮助(除非应用程序的性能受到重大影响),每个用户可以看到相同或不同的照片,具体取决于他们做什么,每个人都有相同的角色,因此无法将一组照片分配给一个人。随着性能下降,需要进行数据库查找以查看该用户是否可以看到该人的照片。谢谢你的想法。
  • @Robbie ,为了减少性能损失,可以使用缓存来存储用户认证。
【解决方案4】:

在Session状态下存储URL和参数,在HttpHandler中访问Session。为此,您需要在处理程序中实现 IRequiresSessionState:

Problem with HttpHandler and session state

Getting Session State in HttpHandlers (ASHX files)

【讨论】:

  • 由于性能影响,通常不建议使用会话。
  • 不,性能会随着会话中存储的用户数和每个用户的对象数的增加而降低。它与图像存储无关。
  • 我猜他必须对其进行基准测试并以此为基础做出决定?
  • 两个 32 位整数之间的映射,假设每个用户 100 个图像,4bytes*2*100*2000 == 160kB
  • 一个数学例子并不意味着在这种情况下使用会话是一个好主意。我并不是说你的答案是错误的,因为它是一个合法的答案,只是不是一个更可取的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-11
  • 2021-10-14
  • 1970-01-01
相关资源
最近更新 更多