Tuesday, June 10, 2014

Hardening the Layer 7 Gateway

Introduction

While I am sure that everyone keeps their Layer 7 Gateways fully updated with each and every patch as soon as it is released and that these patches never cause any issues with existing services and integrations and that Layer 7 Technologies thoroughly and comprehensively test the patches before they are release as soon as they themselves discover an issue because no one would want to maliciously attack someone else's system and every day is filled with sunshine and rainbows...

Meanwhile, here in the real world, part of our job is to obfuscate the fact that we are using Layer 7's product, because it is possible that there is an issue which has not been corrected, or even discovered by the white hats, and once it is known it will take time to fix, test, and deploy.  If an issue affects our Layer 7 appliance and attackers know that we are using Layer 7 then they also know how to attack us effectively.  For these reasons, to more efficiently protect ourselves and the organizations for which we work, we must configure our gateways to conceal that they are Layer 7 appliances.

Overwriting the default error response message

You may have noticed that when you call one of your services and the service fails, or if the request does not resolve to a service, then the appliance returns a message that says l7 all over it.  Hardening your policies is another conversation, but at the end of this section you should never see those messages again unless you explicitly set your policy(s) to sent them.

Global Policy Fragment

First off, create a policy (fragment, not a service) and lets name it 'Generic Error' then select policy type 'Global Policy Fragment' with policy tag 'message-received'; I also like to check the 'Intended for SOAP Services' box because fragments intended for soap services can be used for non-soap services and fragments not intended for soap do not seem to appear in the include list for non soap services, though I am not sure that it makes a difference here.

This fragment will be executed every time a message is received, even if the request does not resolve to a service.  By adding a 'Customize Error Response' in this fragment we can globally overwrite the Layer 7 default failure message.  The following is a sample error response, the only assertion that should be in this policy fragment.

Sample Customize Error Response Assertion

<?xml version="1.0" encoding="UTF-8"?>
<wsp:Policy xmlns:L7p="http://www.layer7tech.com/ws/policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy">
    <wsp:All wsp:Usage="Required">
        <L7p:CustomizeErrorResponse>
            <L7p:Content stringValueReference="inline"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <soapenv:Fault>
            <faultcode>soapenv:Server</faultcode>
            <faultstring>Internal Server Error</faultstring>
            <faultactor>${request.url}</faultactor>
            <detail>Internal Server Error</detail>
        </soapenv:Fault>
    </soapenv:Body>
</soapenv:Envelope>]]></L7p:Content>
            <L7p:ContentType stringValue="text/xml; charset=UTF-8"/>
            <L7p:ExtraHeaders nameValuePairArray="included"/>
        </L7p:CustomizeErrorResponse>
    </wsp:All>
</wsp:Policy>

Catch-All (aka wildcard service)

Next off, as some of you have already been guided to do, is to create a 'catch-all' service.  By creating an API web service with a URI of * any request that does not resolve to a more specific URI will instead resolve to the wildcard.  This service can be used to capture and handle all requests that enter service resolution but would otherwise fail to resolve and in doing so end up sending the default Layer 7 failure response.  While this service is able to replace the error response in the same way as the generic error fragment there are still a couple of ways for a request to fail before reaching service resolution and therefor not run the catch-all, and if the generic error fragment is not in place, to receive the Layer 7 default failure message.

There are a few things that I would recommend to do in the catch-all, like logging information about the request, that I do not recommend to do in the generic error fragment; because the generic error fragment will run for every request and therefore should be as lean as possible.  The catch-all is only servicing requests that have already failed to resolve properly and we therefore do not mind taking a few extra milliseconds to triage the nature of the issue (i.e. does one of our customers need help or are we being probed).  Remember to check all the HTTP methods for the catch-all to make it more widely applicable.

Ping

Personally, I went quite a long time before I was aware of the ping service, now that I am aware of it I am acutely aware.  That is to say, this service betrays the fact that it is a Layer 7 appliance.  This service should not be accessible externally and because it is on by default for the default service ports you must go in and disable it for those ports, or make those ports inaccessible externally and host your services over another port.  Don't get me wrong, the service is useful, but it should be kept internal only.  I recommend to turn it on another port when turning it off for the default ports.

Under Tasks -> Manage Listen Ports, select port 9443 and click the Properties button, expand 'Built-in services' and uncheck the 'Ping service'.  You cannot change the settings on a port over which you are connected using the policy manager, you must therefore disconnect and re-connect over 9443 in order to uncheck the Ping service for port 8443.  You can turn it on for any port that is accessible to your internal network and firewalled off from the internet.

As a practical matter, the only 'Enabled Features' that you want checked on your externally accessible ports are:
  • Published service message input
  • WS-Trust security token service *if you use WS-Security
  • WSDL download service *if you host SOAP web services
  • *if you use the SecureSpan XML VPN Client then you will want to turn on some others
    • Policy download service
    • WS-Trust security token service *if you use WS-Security or SAML
    • Certificate signing service
    • Password changing service
    • WSDL download service

Authentication methods

I strongly recommend mutual-SSL over TLS as part of dual-factor authentication for the strongest security.  As the second factor I suggest some sort of token, such as WS, SAML, or OAuth depending on which best suits your use case.  At a minimum you should never use http, there is no excuse to not at least use server side SSL.  The only logical argument against it is to avoid the additional overhead, however this system (along with most others) has been optimized for https and as a result is slower when using unsecured http, therefore this argument does not hold up.

The point being, regardless of which authentication method(s) you are using, configure your server certificate and require in policy that your clients connect using SSL.  You can require SSL in the port settings, but that would reduce the traffic (troubleshooting information) available in the catch-all.

1 comment:

  1. I like to read an article that express interesting views. Many points the author made are unique and are things I wouldn't have thought about. One in particular (mentioned by a certain post-punk group) leads a normal life, and nobody notices he's a goid, and he's happy that way.

    ReplyDelete