Locking down PingFederate with Jetty Rewrites

|

PingFederate is a very secure product, as a Federation server and STS it can operate in many different roles and situations. One particular scenario is when direct access to certain endpoints need to be exposed to the outside world.

Sometimes when using PingFederate it is desirable to be able to terminate SSL/TLS directly. This of course limits the possibilities to block un-used endpoints to the outside in a reverse proxy since it cannot investigate the traffic.

This may be to protect from internal attacks on the company network, or when some endpoints need to be exposed to the outside world. In such scenario it is of course not recommended to allow any source IP to communicate with the federation server, but in either case, the security of the client is out of the hands of the organization. In these cases measures can be taken to lock PingFederate down even further.

PingFederate runs on Jetty, and much of the configuration is done in Jetty configuration files and with Jetty configuration parameters.

Jetty has a module called Jetty Rewrites which essentially lets the request be rewritten or redirected before its passed along in the handler stack. Unfortunately the rewrite modules is not shipped with the Jetty setup that PingFederate ships with, but luckily it's very easy to add.

Simply download the jetty-rewrite-XYZ.jar where XYZ corresponds with the Jetty version your PingFederate installation is running on. Note that the version must correspond EXACTLY for the Jetty runtime to pick it up. Install the jar in <PF>/lib where the rest of the jars for jetty are located.

To enable the rewrite capability edit the jetty.start.ini file in <PF>/bin and update the following: Add 'rewrite' to the end of the OPTIONS list:

OPTIONS=Server,jsp,resources,ext,plus,annotations,jmx,rewrite

Add etc/jetty-rewrite.xml to the bottom of the file after etc/jetty-admin.xml.

Create the rewrite rules

Now the preparations are done. To actually do some rewrites create a file called jetty-rewrite.xml and place it in the <PF>/etc directory.

A common example would be to lock down the PingFederate box to only operate as an OAuth2 server. In such case the following rules would block everything except the /as/authorization.oauth2 and the /as/token.oauth2 endpoints.

<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id="RuntimeServer" class="org.eclipse.jetty.server.Server">

<Get id="oldhandler" name="handler"/>

<Set name="handler">
  <New id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
    <Set name="handler"><Ref id="oldhandler"/></Set>
    <Set name="rewriteRequestURI">true</Set>
    <Set name="rewritePathInfo">true</Set>
    <Set name="originalPathAttribute">requestedPath</Set>

    <!-- Add rule to protect against IE ssl bug -->
    <Call name="addRule">
      <Arg>
        <New class="org.eclipse.jetty.rewrite.handler.MsieSslRule"/>
      </Arg>
    </Call>

    <!-- =================================================== -->
    <!-- Response rules                                      -->
    <!-- =================================================== -->
    <!-- Response rule for failed requests -->
    <Call name="addRule">
      <Arg>
        <New class="org.eclipse.jetty.rewrite.handler.ResponsePatternRule">
          <Set name="pattern">/not-allowed</Set>
          <Set name="code">405</Set>
          <Set name="reason">Not Allowed</Set>
        </New>
      </Arg>
    </Call>

    <!-- =================================================== -->
    <!-- Allowed endpoints                                   -->
    <!-- =================================================== -->

    <!-- Allow -->
    <Call name="addRule">
      <Arg>
        <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
          <Set name="pattern">/as/authorization.oauth2/*</Set>
          <Set name="replacement">/as/authorization.oauth2</Set>
          <Set name="terminating">true</Set>
        </New>
      </Arg>
    </Call>

    <!-- Allow -->
    <Call name="addRule">
      <Arg>
        <New class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
          <Set name="pattern">/as/token.oauth2/*</Set>
          <Set name="replacement">/as/token.oauth2</Set>
          <Set name="terminating">true</Set>
        </New>
      </Arg>
    </Call>

    <!-- =================================================== -->
    <!-- Deny rules                                          -->
    <!-- =================================================== -->
    <!-- Blocks all -->
    <Call name="addRule">
      <Arg>
        <New class="org.eclipse.jetty.rewrite.handler.RedirectRegexRule">
          <Set name="regex">/(.*)</Set>
          <Set name="replacement">/not-allowed</Set>
          <Set name="terminating">true</Set>
        </New>
      </Arg>
    </Call>

  </New>
</Set>

Comments