Silverlight 4 Socket Policy Changes

After installing the Silverlight plugin, a Silverlight application is able to run on your computer without your explicit consent whenever you browse to a webpage which links to it. Because there is no explicit user action required to run, Silverlight applications are executed within what is known as a security sandbox – a locked-down environment which prevents a malicious application from doing anything to attack your computer or your local network. For the Socket and UDP multicast client classes, this sandboxing takes the form of a required policy check which the application must pass before being able to communicate with network resources.

While these policy checks prevent a malicious application from attacking your computer or other devices on your local network, they also pose a barrier to deploying legitimate Silverlight applications. In order to make it easier to write and deploy Silverlight applications which communicate using Sockets and the UDP multicast clients, a number of changes have been made to the policy systems for Silverlight 4.

Elevated Trust

Silverlight 4 introduces the notion of Elevated Trust applications. Using this feature, an out-of-browser Silverlight application can indicate to the user that it wants to run in Elevated Trust while it is being installed for out-of-browser use. If the user consents, the application is run within an expanded sandbox which allows it to do things that a normal Silverlight application is explicitly denied the ability to do for security reasons.

In Silverlight 4, Elevated Trust applications have been given permission to use the Socket and UDP multicast client classes without policy checks. The Socket class may be used to create a TCP connection to any port on any host without the need for a cross-domain policy file. Similarly, the UDP multicast clients may join any multicast group on any port greater than or equal to 1024 without the need for a policy responder to authorize it. No extra API calls are needed in order to take advantage of this work; the existing APIs light up with the extra functionality when an app is running in Elevated Trust. In-browser and non-elevated out-of-browser applications still have the same policy check requirements as before, and will continue to throw a SocketException with the SocketErrorCode property set to SocketError.AccessDenied if the policy check fails.

Socket Policy via HTTP

When running in the browser sandbox, the policy check for the Socket class requires downloading a policy file from the intended target that controls which Silverlight applications are allowed to connect to it. In previous versions of Silverlight, this download was conducted using a custom protocol running on TCP port 943. While this protocol can be implemented in a very lightweight and easily-secured fashion on the server side, it requires running a dedicated service and opening port 943 in any firewalls between the client and server.

In Silverlight 4, applications using the Socket class may opt in to retrieving the policy file via the HTTP protocol (on TCP port 80) instead of the custom TCP protocol. This allows servers which are already running HTTP services to authorize Socket connections from Silverlight apps without having to deploy a new service on the machine or open up additional firewall surface. To toggle this behavior, set the new SocketAsyncEventArgs.SocketClientAccessPolicyProtocol property on the SocketAsyncEventArgs passed to Socket.ConnectAsync to SocketClientAccessPolicyProtocol.Http.

When this option is set, the Socket class will attempt to download the policy file using an HTTP GET request for https://[target ip address]/clientaccesspolicy.xml. It will NOT attempt to download the policy via the custom TCP protocol if the policy check fails. The path of the Uri (/clientaccesspolicy.xml) is the same as that used by the HttpWebRequest class for its policy check. The two policies may be combined into a single file; the Socket class will safely ignore any <resource> elements, and the HttpWebRequest class will safely ignore any <socket-resource> elements.

Unlike the HttpWebRequest class, the Socket class always specifies the target IP address as the host when retrieving the policy file, even if the connection is made to a DnsEndpoint. This prevents confusion in the case of a single machine hosting websites from multiple domains. As a result, the server must be configured to respond to requests made to its IP address in addition to requests made to a specific hostname.