Recently in Information Security Category

Locking down PingFederate with Jetty Rewrites

| No Comments

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>
</Configure>

Calling One OAuth-protected API from Another

| No Comments

I got an email the other day from Pedro FĂ©lix, asking for my thoughts on an OAuth scenario that he was wondering about and discussing with Howard Dierking. As Pedro and I talked, I learned that he had a really interesting problem on his hands. Basically, he wanted to create an OAuth 2.0 protected service that called an OAuth 1.0a protected service (e.g., Twitter). So, what he had on his hands was a bunch of clients, tokens, services, and two different protocols that do things similarly but w/ slightly different names. Very confusing stuff.

To begin making sense of all this, it's helpful to list out what we know:

  • Pedro wants to call the Twitter API from his own API.
  • The Twitter service is an OAuth 1.0a Resource Server (RS).
  • Twitter has an OAuth 1.0a Authorization Server (AS).
  • The Twitter service naturally only trusts it's own AS.
  • Pedro's service is an OAuth 2 RS and an OAuth 1.0a Twitter client.
  • Pedro has an OAuth 2 AS.
  • Pedro's service naturally only trusts his own AS.
  • The Web app that calls Pedro's service is an OAuth 2.0 client and must submit Access Tokens (ATs) emitted by his own AS (not Twitter's) when calling his service.
  • The Resource Owner (RO) is a Twitter user and will authorize Pedro's service to call the Twitter API to modify their data.
  • The RO authenticates to Pedro's AS using Twitter's OAuth 1.0a AS.
  • Pedro's AS asks the RO to authorize the third-party client to access his service which in turn will access Twitter's.

With these basics in mind, have a look the the following picture that presents an overview of the actors involved and flip through the following slideshow to see the message flow:

Update on OpenID and OAuth

| No Comments

OpenID and OAuth are undergoing a lot of work ATM, and it can be confusing to those that aren't in the thick of it to keep up w/ where things stand. Based on what I heard last week at IIW, where a lot of this work happens, I thought I'd put together an update in hopes that it helps.

After OpenID 2.0 was around for a while, Google and IINM Facebook proposed a new version of the standard called OpenID Connect. This version of the protocol uses OAuth on the front-channel to securely access an API on the back-channel to get user attributes. Around the same time, a need in Japan to provide higher levels of assurance (LOA) and secure interaction w/ Web APIs from mobile applications resulted in the creation of another derivative of the protocol called OpenID Artifact Binding (AB). Last fall at IIW, the authors of each of these vNext protocols started working to align their efforts. The combined spec was commonly referred to by the authors and other insiders as OpenID ABC (as in Artifact Binding + Connect). This harmonization was tricky though because OAuth 2, which they each depend on, wasn't done and the timeframes of the initial customer needing OpenID AB and funding its development might not allow for the work to wait till OAuth was ready.

As of last week, it looks like the stars are aligning and these two updates of OpenID will be merged. This result will be called OpenID Connect rather than OpenID 3.0, OpenID AB, or OpenID ABC. It also looks like OAuth will finish in time for OpenID Connect to normatively reference it, something that isn't allowed by the IETF (which governs that emerging standard) unless the spec has been officially ratified. If OpenID Connect finishes before OAuth 2, it will have to reference the latest draft (which hopefully won't happen). A draft of OpenID Connect is on tap for Julyish.