Best Practices

You can use these best practices to create more efficient application filters.

Registration for Events

Buffers and Data

BSTR Strings

When working with BSTR strings, the implementing entity should be responsible for allocating and freeing memory. For example, if the Firewall service allocates the memory, it should also free it.

A likely scenario is the case where an application filter needs to use a BSTR held by the Firewall service. The Firewall service should provide a pointer to the BSTR, so that the application filter can allocate memory, copy the BSTR, and be responsible for freeing the memory. This approach reduces the likelihood of memory leaks.

Threading

Security for Secondary and Emulated Connections

There are situations where an application filter limits IP address access, including a:

For security purposes, the application filter defines a range of IP addresses for which a particular connection is allowed. Define that range of IP addresses by using the IFWXIpFilter interface.

Note  If you set the range of IP addresses equal to NULL, you are allowing all addresses to connect.

Managing Application Filter Resource Usage

When no data filter is present, the Firewall service user-mode data pump controls resource usage by limiting the number of pending sends on a connection in either direction. For a given communication direction, buffers are received as long as there are less than two pending sends. If there are two pending sends, the receive is delayed until a send is completed. This prevents the accumulation of data buffers when the send rate does not match the receive rate.

When an application filter that uses a data filter is added to the data pump, the send-limiting mechanism does not operate. Your application filter should therefore check whether each send is completed, and should establish a limit as to how many sends can accumulate. When the limit has been reached, your filter should stop calling receive until the number of sends drops below the limit. If you do not create this type of resource usage control mechanism, a large download or a deliberate attack could cause buffers to accumulate, using extensive non-paged pool and user-mode memory. This could result in a denial of service.

Pending I/O Operations

During inbound or output emulation, a filter may build up an excessive number of pending I/O operations and overflow the Firewall service. A filter should impose a strict limit on the number of pending I/O operations that it allows.

Handling Data

Application filters should be designed not to allocate excessive amounts of memory per session or request so that they will not become vulnerable to a denial-of-service (DoS) attack. If filters accumulate data (for example, until there is a complete message), they should set a maximum message size. If this maximum message size is significant, we also recommend that they limit the time during which a message can be stored.

Application filters should never trust data. They should verify that the data is coming from the correct side. For example, they should verify that the client is not sending information that should be coming only from the server. Your filter should also verify that the data has the correct format.

When using hash tables, use salt and other mechanisms to make sure that clients will not be able to craft data that will always be sent to the same bucket.

Filter Setup

If an application filter also provides an extension for Forefront TMG Management, the setup program should allow for separate installation of the administration component and the filter component because Forefront TMG Management can be run remotely. In particular, Forefront TMG Management can be run from a remote computer on which the Forefront TMG services are not installed.

During filter registration, the error code HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) should be considered as a success code, and installation should continue in a normal flow. This is done to avoid problems in re-registering an existing filter.

When an application filter is being uninstalled, the filter should try to uninstall all the objects that it registered (events, alerts, etc.), even if some of them no longer exist and an error code is returned. This is done to ensure that maximum cleanup is achieved, and to ensure forward compatibility with future support for array mode.

Writing to the Stored Configuration

Application filters should not attempt to write to the stored Forefront TMG configuration. Application filters are allowed read-only access to the stored Forefront TMG configuration. Therefore, an application filter that relies on successfully writing to the stored configuration will fail.

Any changes to the stored configuration that are needed for an application filter should be made by the setup process or through the application filter's administrative component.

Events and Alerts

An attacker can use an event or an alert to consume the resources of Forefront TMG computers by sending network traffic of a certain type. To mitigate the risk of denial-of-service (DoS) attacks, application filters should avoid signaling an event using the IFPCEventDefinition::Signal method for each occurrence of a network event that may occur many times in a short period of time. An application filter should maintain a record of the last time that each event was signaled and limit the total number of events that can be signaled in a short period of time (for example, to two or three times a second).

Similarly, an application filter should include a mechanism for preventing each alert that is issued by it from being issued more than once per second.


Send comments about this topic to Microsoft

Build date: 11/30/2009

© 2008 Microsoft Corporation. All rights reserved.