简体   繁体   English

Web服务API密钥和Ajax - 保护密钥

[英]Web services API Keys and Ajax - Securing the Key

This is probably a generic security question, but I thought I'd ask in the realm of what I'm developing. 这可能是一个通用的安全问题,但我想我会在我正在开发的内容中提出这个问题。

The scenario is: A web service (WCF Web Api) that uses an API Key to validate and tell me who the user is, and a mix of jQuery and application on the front ends. 场景是:一个Web服务(WCF Web Api),它使用API​​ Key来验证并告诉我用户是谁,以及前端的jQuery和应用程序的混合。

On the one hand, the traffic can be https so it cannot be inspected, but if I use the same key per user (say a guid), and I am using it in both then there's the chance it could be taken and someone could impersonate the user. 一方面,流量可以是https,因此无法检查,但如果我每个用户使用相同的密钥(比如一个guid),并且我在两者中都使用它,那么就有可能采取它并且有人可以冒充用户。

If I implement something akin to OAuth, then a user and a per-app key is generated, and that could work - but still for the jQuery side I would need the app API key in the javascript. 如果我实现类似于OAuth的东西,那么会生成一个用户和每个应用程序密钥,这可能会起作用 - 但仍然对于jQuery方面,我需要javascript中的应用程序API密钥。

This would only be a problem if someone was on the actual computer and did a view-source. 如果某人在实际计算机上并且执行了视图源,那么这只会是一个问题。

What should I do? 我该怎么办?

  1. md5 or encrypt the key somehow? md5或以某种方式加密密钥?
  2. Put the key in a session variable, then when using ajax retrieve it? 把密钥放在会话变量中,然后当使用ajax检索它时?
  3. Get over it, it's not that big a deal/problem. 克服它,这不是一个大交易/问题。

I'm sure it's probably a common problem - so any pointers would be welcome. 我敢肯定这可能是一个常见的问题 - 所以任何指针都会受到欢迎。

To make this clearer - this is my API I have written that I am querying against, not a google, etc. So I can do per session tokens, etc, I'm just trying to work out the best way to secure the client side tokens/keys that I would use. 为了使这更清楚 - 这是我写的API,我写的是我要查询,而不是谷歌等。所以我可以做每个会话令牌等,我只是想找出最好的方法来保护客户端我会用的代币/钥匙。

I'm being a bit overly cautious here, but just using this to learn. 我在这里有点过于谨慎,但只是用它来学习。

(I suggest tagging this post "security".) (我建议标记这篇文章“安全”。)

First, you should be clear about what you're protecting against. 首先,你应该清楚你正在保护什么。 Can you trust the client at all? 你能信任客户吗? A crafty user could stick a Greasemonkey script on your page and call exactly the code that your UI calls to send requests. 一个狡猾的用户可以在您的页面上粘贴Greasemonkey脚本,并准确调用您的UI调用发送请求的代码。 Hiding everything in a Javascript closure only means you need a debugger; 将所有内容隐藏在Javascript闭包中只意味着您需要一个调试器; it doesn't make an attack impossible. 它不会使攻击变得不可能。 Firebug can trace HTTPS requests. Firebug可以跟踪HTTPS请求。 Also consider a compromised client: is there a keylogger installed? 还要考虑受感染的客户端:是否安装了键盘记录器? Is the entire system secretly running virtualized so that an attacker can inspect any part of memory at any time at their leisure? 整个系统是否秘密运行虚拟化,以便攻击者可以随时随地检查内存的任何部分? Security when you're as exposed as a webapp is is really tricky. 当你像webapp一样暴露时的安全性真的很棘手。

Nonetheless, here are a few things for you to consider: 尽管如此,您可以考虑以下几点:

  1. Consider not actually using keys but rather HMAC hashes of, eg, a token you give immediately upon authentication. 考虑不是实际使用密钥而是使用HMAC哈希,例如,您在认证时立即提供的令牌。

  2. DOM storage can be a bit harder to poke at than cookies. DOM存储可能比cookie更难捅。

  3. Have a look at Google's implementation of OAuth 2 for an example security model. 有关示例安全模型,请查看Google的OAuth 2实现。 Basically you use tokens that are only valid for a limited time (and perhaps for a single IP address). 基本上,您使用的令牌仅在有限时间内有效(并且可能对于单个IP地址有效)。 That way even if the token is intercepted or cloned, it's only valid for a short length of time. 这样即使令牌被拦截或克隆,它也仅在很短的时间内有效。 Of course you need to be careful about what you do when the token runs out; 当然,当令牌用完时你需要小心你做的事情; could an attacker just do the same thing your code does and get a new valid token? 攻击者可能只是做你的代码所做的事情并得到一个新的有效令牌吗?

Don't neglect server-side security: even if your client should have checked before submitting the request, check again on the server if the user actually has permission to do what they're asking. 不要忽视服务器端安全性:即使您的客户端在提交请求之前已经检查过,如果用户实际上有权执行他们要求的操作,请再次检查服务器。 In fact, this advice may obviate most of the above. 事实上,这个建议可以消除上述大部分内容。

It depends on how the API key is used. 这取决于API密钥的使用方式。 API keys like that provided by Google are tied to the URL of the site originating the request; Google提供的API密钥与发起请求的网站的网址相关联; if you try and use the key on a site with an alternate URL then the service throws and error thus removing the need to protect the key on the client side. 如果您尝试在具有备用URL的站点上使用该密钥,则该服务将引发错误,从而无需保护客户端上的密钥。

Some basic API's however are tied to a client and can be used across multiple domains, so in this instance I have previously gone with the practice of wrapping this API in server side code and placing some restrictions on how the client can communicate with the local service and protecting the service. 然而,一些基本API与客户端绑定并且可以跨多个域使用,因此在此实例中,我之前已经将这个API包装在服务器端代码中,并对客户端如何与本地服务进行通信设置了一些限制并保护服务。

My overall recommendation however would be to apply restrictions on the Web API around how keys can be used and thus removes the complications and necessity of trying to protect them on the client. 然而,我的总体建议是对Web API应用如何使用密钥的限制,从而消除了尝试在客户端上保护密钥的复杂性和必要性。

Generally in cases like this though you proxy requests through the server using 'AJAX' which verifies the browser making requests is authorized to do so. 通常在这种情况下,虽然您通过服务器使用'AJAX'代理请求,该'AJAX'验证浏览器是否有权这样做。 If you want to call the service directly from JavaScript, then you need some kind of token system like JSON Web Tokens (JWT) and you'll have to work out cross-domain issues if the service is located somewhere other than the current domain. 如果您想直接从JavaScript调用服务,那么您需要某种令牌系统,如JSON Web令牌(JWT) ,如果服务位于当前域以外的某个位置,您将不得不解决跨域问题。

How about using jQuery to call server side code that handles communication with the API. 如何使用jQuery调用处理与API通信的服务器端代码。 If you are using MVC you can call a controller action that can contain the code and API key to hit your service and return a partial view (or even JSON) to your UX. 如果您正在使用MVC,则可以调用控制器操作,该操作可以包含代码和API密钥以命中您的服务并返回部分视图(甚至是JSON)到您的UX。 If you are using web forms you could create an aspx page that will do the API communication in the code behind and then write content to the response stream for your UX to consume. 如果您使用Web表单,则可以创建一个aspx页面,该页面将在后面的代码中进行API通信,然后将内容写入响应流以供您使用。 Then your UX code can just contain some $.post() or $.load() calls to your server side code and both your API key and endpoint would be protected. 然后,您的UX代码可以包含对服务器端代码的一些$ .post()或$ .load()调用,并且您的API密钥和端点都将受到保护。

请参阅http://blogs.msdn.com/b/rjacobs/archive/2010/06/14/how-to-do-api-key-verification-for-rest-services-in-net-4.aspx了解更多信息信息(如何在.NET 4中对REST服务进行API密钥验证)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM