好的,
我开发了这个 WinForms 客户端,它通过 WCF 调用与服务器(ASPX 应用程序)进行交互。我现在想将服务器部署到我的共享虚拟主机,但我对 WCF 有点陌生,尤其是它背后的安全可能性。
目标是保护 WCF 服务的安全,以便不是每个知道或找到端点地址的人都可以调用它。相反,只有我的 WinForms 客户端必须能够调用 WCF 服务。
我不需要基于用户的身份验证,因此客户端的用户不需要身份验证。 但我只希望此 WinForms 客户端的实例能够与服务交互。服务器和客户端之间传递的信息不是很敏感,因此实际上不需要保护它,但这是一个优点如果可以轻松完成的话。
这对于共享主机 (IIS) 环境(没有可用的 HTTPS)可能吗?我应该使用哪些绑定和选项?我想是 wsHttpBinding,但是我将如何设置安全选项?
使用.NET 4.0
谢谢
Ok,
I have developed this WinForms client, which interacts with a server (ASPX Application) by means of WCF calls. I would now like to deploy the server to my shared webhost, but I'm kinda new to WCF and especially the security possibilities behind it.
The goal is to kind of secure the WCF service, so that not everybody that knows or finds out the endpoint address can call it. Rather, only my WinForms client must be able to call the WCF service.
I do not need authentication on a user basis, so no authentication is required from the user of the client. But I want only instances of this WinForms client to be able to interact with the service. The information passed between server and client is not very sensitive, so it's not really required to secure it, but it's a plus if it can easily be done.
Is this possible with a Shared Host (IIS) environment (no HTTPS at disposal) ? What bindings and options should I use ? I suppose wsHttpBinding, but how would I setup the security options ?
Using .NET 4.0
Thanks
发布评论
评论(2)
据我了解,您有一个面向互联网的服务,您希望限制只有您的客户端应用程序才能调用 - 对吗?或者您是否设想其他客户端(例如 PHP、Ruby 等)也希望在某个时候调用您的服务?
为了保护您的消息,您在 WCF 中有两个选项 - 消息安全或传输安全。在互联网上,由于客户端和服务之间的跃点数量未知,传输安全性不起作用 - 您只剩下消息安全性(在消息通过“网络”传输时对消息进行加密)。为此,您通常将数字证书添加到您的服务(仅限服务器端),客户端可以发现该数字证书并使用它来加密消息。只有您的服务才能解密它们 - 因此您在这方面是安全的。
下一点是:谁可以调用您的服务?如果您想对任何人完全开放,那么是的,您需要
wsHttpBinding
(或 RESTful 变体 -webHttpBinding
)。如果您想允许非 .NET 客户端,则通常仅限于不进行身份验证(任何人都可以调用)或用户名/密码方案,您将在服务器端根据有效用户的数据库对其进行验证。如果您只想允许自己的 .NET 客户端进入,那么您可以执行以下操作:
禁用服务上的元数据;这样,您将“隐藏”您的端点及其提供的服务 - 使用“元数据扫描仪”(如果存在)的人将无法偶然发现您的服务并找出它提供的方法等。但是,这还使得组织外部的其他开发人员无法对您的服务添加服务引用。
您可以定义和使用自定义二进制 http 绑定 - 只有具有此设置的其他客户端才能调用您的服务。二进制 http 绑定也会带来一些速度提升。请参阅此博客文章 如何执行此操作。
您需要以某种方式识别允许进入的调用者 - 一种可能的方法是将额外的标头放入您的 WCF 消息中,然后在服务器端检查该标头。这将简单地确保发现您的服务并找出二进制 http 绑定的休闲黑客仍然会被拒绝(至少在一段时间内)。请参阅此博客文章< /a> 如何为 WCF 实现这样的消息检查器扩展。
最终步骤是在客户端计算机上安装数字证书以及您的服务。然后,您将设置客户端代理以使用该证书对服务进行身份验证。只有拥有该证书的客户端计算机才能调用您的服务。
这实际上取决于您想走多远 - WCF 为您提供了很多选择,但您需要决定要为此投入多少努力。
From what I understand, you have an internet-facing service which you want to limit to only your client app to be able to call - correct? Or do you envision other clients (like PHP, Ruby etc.) also wanting to call into your service at some point?
To secure your message, you have two options in WCF - message or transport security. Over the internet, with an unknown number of hops between your client and your service, transport security doesn't work - you're left with message security (encrypting the message as it travels across the 'net). For this to work, you typically add a digital certificate to your service (only server-side) that the client can discover and use to encrypt the messages with. Only your service will be able to decrypt them - so you're safe on that end.
The next point is: who can call your service? If you want to be totally open to anyone, then yes, you need
wsHttpBinding
(or the RESTful variant -webHttpBinding
). If you want to allow non-.NET clients, you're typically limited to no authentication (anyone can call), or username/password schemes which you will validate on the server side against a database of valid users.If you only want to allow your own .NET client in, then you can do several things:
disable metadata on your service; with this, you would "hide" your endpoints and the services they provide - someone using a "metadata scanner" (if that exists) wouldn't be able to just stumble across your service and find out what methods it provides etc. This however also makes it impossible for another developer outside your organization to do an Add Service Reference to your service.
you could define and use a custom binary http binding - only other clients with this setup could even call your service. The binary http binding would bring some speed improvements, too. See this blog post on how to do this.
you need to somehow identify those callers that are allowed in - one possible method would be to put an extra header into your WCF messages that you then check for on the server side. This would simply make sure that a casual hacker who discovers your service and figures out the binary http binding would still be rejected (at least for some time). See this blog post here on how to implement such a message inspector extension for WCF.
the ultimate step would be to install a digital certificate on the client machine along with your service. You would then set up your client side proxy to authenticate with the service using that certificate. Only client machine that have that certificate could then call into your service.
It really depends on how far you want to go - WCF gives you a lot of options, but you need to decide how much effort you want to put into that .
您需要问自己的第一件事是:“如果有人连接了自己的定制客户端,他们可以对您的 WCF 服务做什么?”查看通过 WCF 公开的所有功能,并假设可以随意访问它。 你完全无法控制客户端,而且你永远不会有这种能力。
HTTPS 很漂亮,但你被迫容易受到 OWASP A9:传输层保护不足。如果由我决定,我会转移到另一个关心安全的主机。如果您通过网络泄露用户名和密码,那么您的用户就会处于危险之中。
我在 WCF 服务中看到的最大问题之一是它们有一个公开的“executeQuery()”函数。开发人员允许客户端构建由服务器执行的查询。这种方法从根本上来说是有缺陷的,因为您只是将数据库交给了攻击者。这种类型的漏洞不是 SQL 注入,它属于 CWE-602:客户端实施服务器端安全。
与 CWE-602 相同的是 OWASP A4:不安全的直接对象引用 。攻击者是否可以通过提供不同的用户 ID 来欺骗您的 WCF 服务,使其认为是另一个用户?您相信客户说的是实话吗?
您必须考虑的下一类漏洞是 OWASP A1:注入 ,也称为“污染和下沉”。例如,如果您公开一个函数,其中其参数之一在调用
cmd.exe
的 CreateProcess() 中使用。该参数可以由攻击者控制,并且该变量是“受污染的”,对 CreateProcess() 的调用是“接收器”。这些漏洞有许多类型,包括但不限于: SQL 注入、LDAP 注入、XPATH 注入。这些类型的漏洞会影响所有 Web 应用程序。The first thing you need to ask your self is: "What can someone do to your WCF service if they connected their own customized client?" Look at all of the functionality that is being exposed via WCF and assume that it could be accessed at will. You have absolutely no control over the client, and you will never have this ability.
HTTPS is beautiful, its a damn shame that your forced to be vulnerable to OWASP A9: Insufficient Transport Layer Protection. If it where up to me, I would move to a different host that cared about security. If you are throwing usernames and passwords over the network, then your putting your users in danger.
One of the biggest problems I have seen with a WCF service is that they had a "executeQuery()" function that was exposed. The developer allowing the client to build queries to be executed by the server. This approach is fundamentally flawed as you are just handing your database over to an attacker. This type of vulnerability isn't SQL Injection, it falls under CWE-602: Client-Side Enforcement of Server-Side Security.
Along the same lines as CWE-602 is OWASP A4: Insecure Direct Object References. Could an attacker fool your WCF service into thinking its another user by providing a different user id? Are you trusting the client to tell the truth?
The next classification of vulnerabilities that you must take into consideration is OWASP A1: Injection, other wise known as "Taint and Sink". For instance if you are exposing a function where one of its parameters is being used in a
CreateProcess()
which is invokingcmd.exe
. This parameter could be controlled by the attacker, and there for this variable is "tainted", the call toCreateProcess()
is a "sink". There are many types of vulnerabilities along these lines, including but not limited to; SQL Injection, LDAP Injection, XPATH Injection. These types of vulnerabilities affect all web applications.