我们目前正在开发一个非常简单的 Web 应用程序,我们希望 “混淆” (什么是正确的术语?)或以某种方式对请求参数进行编码,这样我们就可以减少空闲用户发送任意数据的机会。

例如,网址看起来像 /webapp?user=Oscar&count=3

我们想要这样的东西: /webapp?data=EDZhjgzzkjhGZKJHGZIUYZT 并在服务器中使用真实的请求信息对该值进行解码。

在我们自己实施这样的事情(并且可能做错了)之前,我想知道是否已经有一些事情可以做到这一点?

我们在服务器上有 Java,在客户端上有 JavaScript。

有帮助吗?

解决方案

不,不要这样做。如果您可以在客户端代码中构建一些内容来混淆传输回服务器的数据,那么故意的黑客也可以。无论您的官方客户端做什么,您都无法信任发送到您服务器的数据。 坚持转义客户端数据并根据服务器端的白名单进行验证. 。使用 SSL,如果可以的话,将请求参数放在 POST 中而不是 GET 中。

扩展编辑

您的困惑源于阻止用户篡改请求数据的目标,以及需要实施标准安全措施。Web 应用程序的标准安全措施涉及使用身份验证、权限和会话管理、审计跟踪、数据验证和安全通信通道的组合。

使用 SSL 并不能防止客户端篡改数据,但可以防止中间人查看或篡改数据。它还指示行为良好的浏览器不要在 URL 历史记录中缓存敏感数据。

看起来你有某种简单的 Web 应用程序,没有身份验证,并在 GET 中传递控制它的请求参数,因此一些不懂技术的人可能会发现这一点 user=WorkerBee 可以简单地改为 user=Boss 在他们的浏览器栏中,因此他们可以访问他们不应该看到的数据,或者做他们不应该做的事情。 您(或您的客户)混淆这些参数的愿望是幼稚的,因为它只会挫败最不懂技术的人。这是一个不成熟的措施,您没有找到现有解决方案的原因是它不是一个好方法. 。您最好花时间实施一个体面的身份验证系统,并通过审计跟踪进行良好的衡量(如果这确实是您所做的,请标记 加里的回答 正确)。

所以,总结一下:

  1. 通过混淆实现安全性不是 完全安全。
  2. 你不能相信 用户数据,即使它被遮挡了。验证您的数据.
  3. 使用安全通信通道 (SSL) 帮助阻止其他相关威胁。
  4. 你 应该放弃你的方法并做 正确的事情。正确的事情,在 你的情况,可能意味着添加一个 身份验证机制,具有 权限系统,防止用户 从访问他们不是的东西 有幸看到 - 包括 他们可能尝试访问的内容 篡改 GET 参数。 加里 R 的回答, ,以及戴夫和威尔的评论 这个在头上。

其他提示

如果你的目标是“从任意发送数据降低的可能性闲置的用户,”还有另一种更简单的方法我会尝试。做一个私有加密密钥并将其存储在您的应用程序的服务器端。每当您的应用程序生成URL,创建一个使用您的私人加密密钥的URL的哈希值,并将该散列在查询字符串。每当用户在URL请求一个页面参数,重新计算哈希值,看看它是否匹配。这会给你一些肯定,你的应用程序计算的URL。它将使你的查询字符串参数可读虽然。在伪代码中,

SALT = "so9dnfi3i21nwpsodjf";

function computeUrl(url) {
  return url + "&hash=" + md5(url + SALT );
}

function checkUrl(url) {
  hash = /&hash=(.+)/.match(url);
  oldUrl = url.strip(/&hash=.+/);
  return md5(oldUrl + SALT ) == hash;
}

如果你想限制访问的数据,然后使用某种类型的登录机制提供单点登录认证密钥的cookie。如果客户端发送cookie的使用键,然后他们可以按照他们的帐户(管理员,公共用户等)相关的当局操纵数据。只要看看春季安全,CAS等在Java中的这个简单易用的实现。在cookie中提供的令牌通常与发行服务器的私有密钥加密的,并且通常是防篡改。

另外,如果你希望你的公共用户(非认证),才能将一些数据发布到你的网站,那么所有的赌注都关闭。您必须验证在服务器端。这意味着限制访问某些URI和确保所有输入被清洗。

这里的指导原则是不允许一切,除了东西你知道是安全的。

如果目标是防止“静态”URL 被操纵,那么您可以简单地对参数进行加密或对其进行签名。添加 URL 参数的 MD5 以及一些盐可能“足够安全”。例如,盐可以是存储在会话中的随机字符串。

然后你就可以:

http://example.com/service?x=123&y=Bob&sig=ABCD1324

该技术公开了数据(即他们可以“看到”xyz=123),但无法更改数据。

“加密”有一个优点(我宽松地使用这个术语)。您可以在此处加密 URL 的整个参数部分。

在这里你可以做类似的事情:

http://example.com/service?data=ABC1235ABC

使用加密的好处有两个。

其一是保护数据(例如,用户永远看不到 xyz=123)。

另一个特点是它是可扩展的:

http://example.com/service?data=ABC1235ABC&newparm=123&otherparm=abc

在这里,您可以解码原始有效负载,并与新数据进行(安全)合并。

因此,请求可以将数据添加到请求中,但不能更改现有数据。

您可以通过签名技术执行相同的操作,只需将整个请求合并到一个“blob”中,并且该 blob 会被隐式签名。这是“有效”加密的,只是弱加密。

显然您不想在客户端上执行任何此操作。毫无意义。如果你能做到,“他们”也能做到,而你却无法区分,所以你最好根本不这样做——除非你想通过普通的 HTTP 端口“加密”数据(相对于 TLS,但人们会明智地想知道“为什么要麻烦”)。

对于 Java,所有这些工作都在 Filter 中进行,这就是我所做的。后端与此隔离。

如果您愿意,您可以使用出站过滤器使后端与此完全隔离,该过滤器在出站时处理 URL 加密/签名。

我也是这么做的。

不利的一面是,要使其正确并保持高性能,需要非常复杂的工作。您需要一个轻量级 HTML 解析器来提取 URL(我编写了一个流解析器来动态执行此操作,因此它不会将整个页面复制到 RAM 中)。

好的一面是所有内容都“正常工作”,因为他们对此一无所知。

处理 Javascript 时还有一些特殊处理(因为您的过滤器不会轻易“知道”哪里有要加密的 URL)。我通过要求将 url 签名为特定的“varsignedURL='....'”解决了这个问题,这样我就可以在输出中轻松找到这些内容。并不像您想象的那样给设计师带来沉重的负担。

过滤器的另一个亮点是您可以禁用它。如果您发生一些“奇怪的行为”,只需将其关闭即可。如果该行为继续存在,则您发现了与加密相关的错误。它还允许开发人员以纯文本方式工作,并将加密留给集成测试。

做起来很痛苦,但最终总体来说还是不错的。

喜欢的东西jCryption?

http://www.jcryption.org/examples/

您可以编码使用Base64或类似的东西的数据。我将编码参数中inself JSON序列化它们。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top