JNBridgePro and Network Security
Note: Please see the newer post JNBridgePro 10.1 offers new network security options
Recently, a professional security researcher reported a vulnerability when using JNBridgePro with the TCP/binary or HTTP/SOAP channels. The vulnerability makes it possible for an unauthorized user to execute arbitrary code. For example, in the .NET-to-Java direction, an unauthorized user can access any API on the Java side, including Runtime.exec(). It is not necessary to have the proxies in order to access these APIs; an unauthorized application could mimic the JNBridge binary and HTTP protocols. A similar exploit exists in the Java-to-.NET direction.
The problem does not exist when using shared memory communications, as these cross-platform requests can only be made from the same process.
In order to address this problem, we have implemented an IP whitelisting mechanism. JNBridgePro’s communication mechanisms can now be configured to only accept requests from clients residing on machines with specific IP addresses.
Which versions of JNBridgePro have the vulnerability?
The vulnerability exists in all versions of JNBridgePro before version 10.0.1, the current version available for download on the website.
For previous versions of JNBridgePro, we have prepared patches, and we have attempted to contact all customers using old versions. If you are using a version of JNBridgePro older than 10.0.1, and have not been contacted by us concerning the patch and how to obtain it, please contact support@jnbridge.com.
Should I be concerned about the vulnerability?
You should apply this patch if your application uses JNBridgePro and uses TCP/binary or HTTP/SOAP communications. You should also apply this patch if your application currently uses shared memory communications, but might use TCP/binary or HTTP/SOAP at some time in the future.
If your application uses shared memory communications and will never use a different communications mechanism (for example, if your application makes use of JNBridgePro’s UI embedding facility, which requires that shared memory be used), you do not need to apply this patch, because the Java and .NET sides are running in the same process and are communicating through shared data structures. When shared memory is used, there are no open sockets that can be accessed by a client.
If your application uses TCP/binary or HTTP/SOAP, and both the Java and .NET sides are behind a properly configured firewall, unauthorized users will not be able to exploit this vulnerability through the firewall. However, the vulnerability will still exist if hostile code has been installed behind the firewall. You will have to use your judgement on this.
If you’re not sure how JNBridgePro has been configured in your application, the easiest way to tell is to determine whether your Java and .NET sides are running in the same process (in which case you’re using shared memory) or whether they’re running in separate processes (in which case they’re communicating via the socket-based TCP/binary or HTTP/SOAP mechanisms). You can also look at the JNBridgePro configuration mechanisms (in the app.config or Java-side .properties files, or in calls to JNBridgePro’s programmatic configuration APIs). If you are still unsure about the communication mechanism being used, please contact support@jnbridge.com.
How does the whitelisting mechanism work?
Previously to version 10.0.1, the JNBridgePro Java-side or .NET-side server would accept TCP/binary or HTTP/SOAP requests from clients on any machine that could reach the server. Starting with 10.0.1, and also available through patches for older versions, the Java-side or .NET-side servers can be configured to only accept requests from clients on machines with specific IP addresses. By default, the Java-side and .NET-side servers will only accept requests from clients on the same machine on which the server is running (i.e., 127.0.0.1 or the IPv6 equivalent). This means that the proxy generation tool, for example, will still work out of the box without any further configuration.
If you want to accept requests from clients on other machines, you can add their IP addresses to the server’s whitelist. You can list specific addresses, and you can also add wildcards (for example, ‘1.2 *.4’), so that ranges of addresses can be accepted. You can also configure the servers to accept requests from any IP address, as before (by specifying ‘*’ as the whitelist), but you should think very carefully about whether you want to do this, and assess the risks.
Note: The whitelisting mechanism does not support HTTP/SOAP communications in the Java-to-.NET direction. We recommend that you not use HTTP/SOAP communications in that scenario. Whitelisting is supported with HTTP/SOAP in the .NET-to-Java direction, and it is supported with TCP/binary communications in both directions.
Note that use of the IP whitelist is unnecessary when using shared memory, and it will be ignored if it is supplied. With shared memory, cross-platform requests always come from the same process.
How do I configure the whitelist my application?
Whitelisting in the .NET-to-Java direction
By default, for security reasons, a JNBridgePro Java side will only accept requests from .NET sides on the same machine. It may be desirable to specify a whitelist of additional hosts from which a Java side will accept .NET requests. To specify such a whitelist, add the following property to the Java-side specification:
dotNetSide.ipWhitelist=semicolon-separated list of IP addresses
Note that there should be no quotation marks around the list of IP addresses. Also note that case matters when specifying the property name dotNetSide.ipWhiteList.
The IP addresses may be in IPv4 (‘.’-separated) or IPv6 (“:”-separated) style. “*” may be used as a wildcard in place of any element. “*” or “::” may be used as a wildcard to match any IP address.
If the dotNetSide.ipWhilelist property is not specified, it is equivalent to having specified
dotNetSide.ipWhitelist=127.0.0.1;0:0:0:0:0:0:0:1
that is, the Java side will only accept requests from clients on the same machine.
As an example,
dotNetSide.ipWhitelist=1.2.3.4
will cause the Java side to only accept requests from the machine whose IP address is 1.2.3.4. All other requests will be rejected, and any .NET side making a proxy call to that Java side from any other machine will see a System.IO.IOException.
As another example,
dotNetSide.ipWhitelist=127.0.0.1;10.1.2.*
will cause the Java side to only accept .NET requests from the same host, or from any host in the range 10.1.2.0 to 10.1.2.255, and reject all others.
Whitelisting in the Java-to-.NET direction
By default, for security reasons, a JNBridgePro .NET side will only accept requests from .NET sides on the same machine. It may be desirable to specify a whitelist of additional hosts from which a .NET side will accept Java requests. To specify such a whitelist, add the following element to the .NET-side configuration:
<javaToDotNetConfig
scheme=”jtcp”
port=port_responding_to_requests
… other specification elements …
ipWhitelist=”semicolon-separated list of IP addresses“
/>
Note that case matters when specifying the ipWhitelist element.
The IP addresses may be in IPv4 (‘.’-separated) or IPv6 (“:”-separated) style. “*” may be used as a wildcard in place of any element. “*” or “::” may be used as a wildcard to match any IP address.
If the ipWhilelist element is not specified, it is equivalent to having specified
ipWhitelist=”127.0.0.1;0:0:0:0:0:0:0:1″
that is, it will accept requests from any client on the same machine.
As an example,
ipWhitelist=”1.2.3.4″
will cause the .NET side to only accept requests from the machine whose IP address is 1.2.3.4. All other requests will be rejected, and any Java side making a proxy call to that .NET side from any other machine will see an exception.
As another example,
ipWhitelist=”127.0.0.1;10.1.2.* ”
will cause the .NET side to only accept Java requests from the same host, or from any host in the range 10.1.2.0 to 10.1.2.255, and reject all others.
Note: The ipWhitelist is only recognized when TCP/binary communications are used. It is ignored when HTTP/SOAP communications is used. Because of this, we do not recommend using HTTP/SOAP communications in the Java-to-.NET direction.
For .NET Core 3.0, an ipWhitelist element can be specified in the JSON configuration file in a similar manner.
If you are configuring your .NET side programmatically, we have provided additional variants of the programmatic configuration API to specify the IP whitelist. If you use one of the configuration API that does not specify the IP whitelist, then the default IP whitelist value will be used, and only requests from the same machine will be accepted.
For more information on programmatic configuration, please see the JNBridgePro Users’ Guide.
Will use of the IP whitelist protect me?
Use of the IP whitelist will mitigate the problem. A properly configured IP whitelist will prevent malicious accesses from the wider internet. Use of a properly configured firewall will also help. There is still the possibility of malicious clients being placed on machines listed in the IP whitelist, so you should concentrate on protecting those machines.
What else can be done?
An upcoming version of JNBridgePro will offer additional security features to offer protection from malicious clients.
In the meantime, you can protect yourself from accesses by malicious clients
- by using the IP whitelist,
- by having a properly configured firewall that prevents accesses from outside the firewall,
- by taking precautions to keep malware out of your network, and particularly off the machines on the IP whitelist,
- by not using the HTTP/SOAP communications mechanism (we suspect very few, if any, of our users are),
- and, finally, by using shared memory where your application allows it.
For more information, contact support@jnbridge.com.