javascript 编码/混淆 HTTP 参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4017757/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 10:10:05  来源:igfitidea点击:

Encode/obfuscate HTTP parameters

javajavascriptweb-applicationsobfuscationhttp-request-parameters

提问by OscarRyz

We are currently working on a very simple Webapp, and we would like to "obfuscate"( what would be the right term? ) or encode somehow the request parameter, so we can reduce the chance an idle user from sending arbitrarily data.

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

For instance, the url looks like /webapp?user=Oscar&count=3

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

We would like to have somthing like: /webapp?data=EDZhjgzzkjhGZKJHGZIUYZTand have that value decoded in the server with the real request info.

我们希望有类似的东西:/webapp?data=EDZhjgzzkjhGZKJHGZIUYZT并在服务器中使用真实的请求信息对该值进行解码。

Before going into implementing something like this ourselves ( and probably doing it wrong ) I would like to know if there is something to do this already?

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

We have Java on the server and JavaScript on the client.

我们在服务器端使用 Java,在客户端使用 JavaScript。

回答by Mike Atlas

No, don't do this. If you can build something in your client code to obfuscate the data being transmitted back to the server, then so can a willful hacker. You simply can't trust data being sent to your server, no matter what your official client does. Stick to escaping client data and validating it against a whitelist on the server side. Use SSL, and if you can, put your request parameters in a POST instead of GET.

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

Expansion edit

扩展编辑

Your confusion stems from the goal to block users from tampering with request data, with the need to implementing standard security measures. Standard security measures for web applications involve using a combination of authentication, privilege and session management, audit trails, data validation, and secure communication channels.

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

Using SSL doesn't prevent the client from tampering with the data, but it does prevent middle-men from seeing or tampering with it. It also instructs well-behaved browsers not to cache sensitive data in the URL history.

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

It seems you have some sort of simple web application that has no authentication, and passes around request parameters that control it right in the GET, and thus some non-technically savvy people could probably figure out that user=WorkerBeecan simply be changed to user=Bossin their browser bar, and thus they can access data they shouldn't see, or do things they shouldn't do. Your desire (or your customer's desire) to obfuscate those parameters is na?ve, as it is only going to foil the least-technically savvy person. It is a half-baked measure and the reason you haven't found an existing solution is that it isn't a good approach. You're better off spending time implementing a decent authentication system with an audit trail for good measure (and if this is indeed what you do, mark Gary's answeras correct).

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

So, to wrap it up:

所以,总结一下:

  1. Security by obfuscation isn't security at all.
  2. You can't trust user data, even if it is obscured. Validate your data.
  3. Using secure communication channels (SSL) helps block other related threats.
  4. You should abandon your approach and do the right thing. The right thing, in your case, probably means adding an authentication mechanism with a privilege system to prevent users from accessing things they aren't privileged enough to see - including things they might try to access by tampering with GET parameters. Gary R's answer, as well as Dave and Will's comment hit this one on the head.
  1. 通过混淆实现的安全根本不是安全。
  2. 您不能信任用户数据,即使它被掩盖了。 验证您的数据
  3. 使用安全通信通道 (SSL) 有助于阻止其他相关威胁。
  4. 你应该放弃你的方法并做正确的事情。在您的情况下,正确的做法可能意味着添加带有权限系统的身份验证机制,以防止用户访问他们没有足够权限查看的内容 - 包括他们可能试图通过篡改 GET 参数来访问的内容。Gary R 的回答以及 Dave 和 Will 的评论击中了这一点。

回答by Dave Aaron Smith

If your goal is to "reduce the chance an idle user from sending arbitrarily data," there's another simpler approach I would try. Make a private encryption key and store it in your application server side. Whenever your application generates a url, create a hash of the url using your private encryption key and put that hash in the query string. Whenever a user requests a page with parameters in the url, recompute the hash and see if it matches. This will give you some certainty that your application computed the url. It will leave your query string parameters readable though. In pseudo-code,

如果您的目标是“减少空闲用户发送任意数据的机会”,那么我会尝试另一种更简单的方法。制作私人加密密钥并将其存储在您的应用程序服务器端。每当您的应用程序生成 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;
}

回答by Gary Rowe

If you're trying to restrict access to data then use some kind of login mechanism with a cookie providing a Single Sign On authentication key. If the client sends the cookie with the key then they can manipulate the data in accordance with the authorities associated with their account (admin, public user etc). Just look at Spring Security, CAS etc for easy to use implementations of this in Java. The tokens provided in the cookie are usually encrypted with the private key of the issuing server and are typically tamper proof.

如果您试图限制对数据的访问,则使用某种登录机制,并通过 cookie 提供单点登录身份验证密钥。如果客户端发送带有密钥的 cookie,那么他们可以根据与其帐户相关联的权限(管理员、公共用户等)操作数据。只需查看 Spring Security、CAS 等,即可在 Java 中轻松使用它的实现。cookie 中提供的令牌通常使用发行服务器的私钥进行加密,并且通常是防篡改的。

Alternatively, if you want your public user (unauthenticated) to be able to post some data to your site, then all bets are off. You must validate on the server side. This means restricting access to certain URIs and making sure that all input is cleaned.

或者,如果您希望您的公共用户(未经身份验证)能够将一些数据发布到您的网站,那么所有赌注都将关闭。您必须在服务器端进行验证。这意味着限制对某些 URI 的访问并确保清除所有输入。

The golden rule here is disallow everything, except stuff you know is safe.

这里的黄金法则是禁止一切,除非你知道是安全的。

回答by Will Hartung

If the goal it to prevent "static" URLs from being manipulated, then you can simply encrypt the parameters, or sign them. It's likely "safe enough" to tack on an MD5 of the URL parameters, along with some salt. The salt can be a random string stored in the session, say.

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

Then you can just:

然后你可以:

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

This technique exposes the data (i.e. they can "see" that xyz=123), but they can not change the data.

这种技术公开数据(即他们可以“看到”xyz=123),但他们不能更改数据。

There's is an advantage of "encryption" (and I use that term loosely). This is where you encrypt the entire parameter section of the URL.

“加密”有一个优势(我松散地使用该术语)。这是您加密 URL 的整个参数部分的地方。

Here you can do something like:

在这里,您可以执行以下操作:

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

The nice thing about using encryption is two fold.

使用加密的好处有两个方面。

One it protects the data (they user can never see that xyz=123, for example).

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

The other feature tho is that it's extensible:

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

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

Here, you can decode the original payload, and do a (safe) merge with the new data.

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

So, requests can ADD data to the request, just not change EXISTING data.

因此,请求可以向请求添加数据,而不是更改现有数据。

You can do the same via the signing technique, you would just need consolidate the entire request in to a single "blob", and that blob is implicitly signed. That's "effectively" encrypted, just a weak encryption.

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

Obviously you don't want to do ANY of this on the client. There's no point. If you can do it, "they" can do it and you can't tell the difference, so you may as well not do it at all -- unless you want to "encrypt" data over a normal HTTP port (vs TLS, but then folks will wisely wonder "why bother").

显然你不想在客户端上做任何这些。毫无意义。如果你能做到,“他们”就能做到,而你无法分辨其中的区别,所以你最好根本不这样做——除非你想通过普通的 HTTP 端口“加密”数据(vs TLS,但是人们会明智地想知道“为什么要麻烦”)。

For Java, all this work goes in a Filter, that's the way I did it. The back end is isolated from this.

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

If you wish, you can make the back end completely isolated from this with an outbound filter that handles the URL encryption/signing on the way out.

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

That's also what I did.

这也是我所做的。

The down side is that it's very involved to get it right and performant. You need a light weight HTML parser to pull out the URLs (I wrote a streaming parser to do it on the fly so it didn't copy the entire page in to RAM).

不利的一面是,要使其正确且高效,需要非常投入。您需要一个轻量级的 HTML 解析器来提取 URL(我编写了一个流解析器来即时完成它,因此它不会将整个页面复制到 RAM 中)。

The bright side is all of the content side "just works", as they don't know anything about it.

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

There's also some special handling when dealing with Javascript (as your filter won't easily "know" where there's a URL to encrypt). I resolved this by requiring urls to be signed to be specific "var signedURL='....'", so I can find those easily in the output. Not as crushing a burden on designers as you might think.

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

The other bright side of the filter is that you can disable it. If you have some "odd behavior" happening, simply turn it off. If the behavior continues, you've found a bug related to encryption. It also let developers work in plain text and leave the encryption for integration testing.

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

Pain to do, but it's nice overall in the end.

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

回答by oimoim

Something like jCryption ?

像 jCryption 这样的东西?

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

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

回答by Florian

You can encode data using base64 or something similar. I would encode the arguments inself in JSON to serialize them.

您可以使用 base64 或类似的东西对数据进行编码。我会在 JSON 中对参数进行编码以序列化它们。