Understanding the Check Token ID in PeopleTools 8.56

This is a guest post by a PeopleSoft security researcher.

PeopleSoft has introduced a new parameter on Node Definitions called the CheckTokenID. This parameter is required if you plan on using PeopleSoft Single Signon. In this post we will take a look at what exactly this Check Token feature is, how it works, and lastly some implications.

What is Check Token?

Check Token is a response from Oracle to combat vulnerabilities with PS_TOKEN and the ability to execute brute force attacks on the node password. Should the node password be recovered attackers would be able to create “authentic” PS_TOKENs. This was covered in a previous podcast

Check Token involves a set of low level changes to how the psp and psc servlets (and related Java code) handle the authentication process. These changes harden the servlets against such forged tokens.

However the process by which Check Token improves the security of PS_TOKEN is not very well detailed and for the remainder of this post we will look at the internals of how this set of changes improves security.

Check Token Pieces

The changes made in 8.56 for the Check Token feature can be split into 2 general sections:

  1. The Token Lookup
  2. The Knock Knock Request

The “Token Lookup” portion is a security precaution added to ensure that the PS_TOKEN being provided was actually issued by the PeopleSoft system.

The Knock Knock Request is a mechanism by which the target application can “phone home” to the site that generated the token and ask them if the Token is good.

We will go more into the details of how this is accomplished in the Step By Step section below.

Environment Setup

For the following sections assume that we have the following PeopleSoft Environments:

  • Interaction Hub (IH) on Tools 8.56
  • CRM on Tools 8.56
  • HCM on Tools 8.55

As part of configuring PeopleSoft SSO on 8.56, each Node that will participate (and is 8.56 or later) must have the Check Token ID field populated:

This CheckTokenID field must match for each node in each environment (for example, the IH node has the same value in IH and CRM, and the CRM node has the same value in IH and CRM).

Pressing the Create CheckTokenID button will securely generate a random 189 bytes (252 characters when encoded to base64). The page will also present you this value to copy out for use in the other environments.

You are able to specify any value you want for the CheckTokenID, but for the most security it is better to use the Create button.

There is more to the SSO setup than this, but this is the only portion relevant to the blog post.

An 8.56 SSO Event Step by Step

Now that the environments have been configured for SSO, the best way to show how Check Token works is to go Step by Step through an SSO event. That is when a user with an active session in the IH tries to access a page in CRM and triggers PeopleSoft SSO.

Initial Access

When a user hits a CRM page with a PS_TOKEN issued by IH, the psp or psc servlet initiates an authentication attempt by calling the authenticate method in the PSAuthenticator class (this is done in the servlet’s onLogin method). The PSAuthenticator class eventually calls an isAuthTokenValidFromRequest method. Inside this method it makes a couple of checks:

  1. Is the App Server a “portal” server
  2. Is this request from the “same site”

The “same site” is determined by looking at a cookie that is new to 8.56 called PS_LASTSITE.

If either 1 or 2 are true, then the “knock knock” portion of the CheckToken changes is not executed. In this scenario only the “Token Lookup” part is executed. The Token Lookup grabs the web server session (via the JSESSION cookie) and asks for the PS_TOKEN from the web server, it then compares this PS_TOKEN to the one that it has been presented and the check only succeeds if they match.

This in effect prevents forged tokens from being used, as they will be rejected since the token issued by the application itself wont match.

However, in our scenario the user just left IH and hit a CRM page. Because of this #1 isn’t true and PS_LASTSITE will be an IH url so #2 isn’t true. In this case the Authenticator starts the CheckToken “Knock Knock” portion.

CheckToken Request

Since CRM has decided that the Knock Knock should be performed, it begins the Knock Knock portion by calling doKnockKnockRequest of the PSCheckToken class.

The Knock Knock portion has the following steps:

  1. Get the Last Site (PS_LASTSITE cookie)
  2. Append ?cmd=checkToken to the URL from #1
  3. Form a POST request
  4. Send Request

The POST request is blank in terms of the content that gets posted, however it does contain a copy of all headers from the inbound request to CRM (including cookies like PS_TOKEN and JSESSION). The Request is sent off to the URL of the Last Site (in our case Interaction Hub) and PSCheckToken class waits for a response.

CheckToken Processing in IH

When IH receives the HTTP POST with ?cmd=checkToken the psp or psc servlet handles this in the process method. The process of handling the checkToken command is 2 steps, first IH will perform a “Token Lookup” action to ensure the IH really did issue this token. If IH did not, an exception is raised and CRM will not get a valid response.

If IH did issue the token it then begins to form the Knock Knock Response. At a high level the Knock Knock Response value consists of a digest and a nonce. A nonce is generated by using the generateNonce method of PSTrustAuthUtil this Nonce is generated by Base64 encoding 16 random bytes (source of random is SHA1PRNG).

The Digest itself is calculated by hashing the PS_TOKEN, the “knock knock constant”, the Nonce*, and the PS_TOKEN‘s issue date. The PSCheckToken class supports both SHA1 and SHA256, however the method createKnockKnockDigest appears to hard-code the algorithm to be SHA256.

The “knock knock constant” referenced above is simply the “hashed” version of CheckTokenID that was set on the Node Definition. Hashed is in quotes because its not truly a hash, but rather it is encrypted with the same algorithm that Node Passwords are. Try setting a node password and a CheckTokenID to the same value and then query the PSMSGNODEDEFN table to see that this is true.

Once the digest is calculated, the Nonce that was chosen by IH is then appended to the resulting hash and this value is set in the PS_CTDIGEST header. The * next to “Nonce” is because there seems to be a cryptographic oversight (at least in the 8.56 versions I’ve looked at). When using SHA1 the Nonce is correctly included in the hashing, but when SHA256 is used the Nonce is NOT included in the hash like it should be: ![Nonce Issue for SHA256][2]

CheckToken Response Processing

Once IH has generated the response and sent it back to CRM, the CRM application server continues execution of replyFromKnockKnockRequest in the PSCheckToken class. This method retrieves the PS_CTDIGEST header and splits the value into 2 parts, the digest and the nonce. This is doable because hashes have a determinate length so it is easy to grab the Nonce off the end.

Once the values are split CRM goes ahead and generates the same digest, using its copy of the CheckTokenID value for the appropriate node as well as the Nonce*. If the generated digest matches the digest that IH sent, authentication succeeds and the user is successfully SSO’d into CRM! The * next to “Nonce” is for the same reason as earlier.

Applications < 8.56

As mentioned in the environment setup we are pretending to have an HCM environment that is below 8.56. Let’s briefly discuss how Oracle kept compatibility for this mode of operation (IH on 8.56 and other apps lower than that).

The way Oracle engineered this change puts the responsibility of determining when to enforce CheckToken on the target application (the one that is being SSO’d to). Oracle deliberately made no changes to the format of PS_TOKEN itself so that tokens issued by 8.56 would still be valid on 8.55 systems.

Because our HCM environment knows nothing about Check Token, it will never determine that it needs to ask the IH to check the PS_TOKEN. And because of this the PeopleSoft SSO operates effectively the same way it has been.

What about that Nonce thing?

As mentioned above there seems to have been an oversight with the generation of the Knock Knock response when using SHA256 (not including the Nonce in the hash). Nonce’s are intended to prevent the ability to replay a request. So while technically the lack of the Nonce in the hash renders this protection moot, ultimately the attacker would not be able to get back to “Token Lookup” phase with a forged token because the Application Server will not find that token as not having been issued.

What is important to note is that should Oracle release patches to fix this oversight, they would need to be applied to all systems, if only applied to the CRM in our example, the digest that IH produces would no longer match what CRM produces.

#6 – TokenChpoken and Other Security Issues

In Episode 6 of The PeopleSoft Administrator Podcast, Dan and Kyle talk about the TokenChpoken (or PS_TOKEN) vulnerability. We explain how the vulnerability works and how to mitigate it, Oracle CPU’s and Java Patching. Kyle shares a handy tip to clear end-user cache from the web profile.

We want to make this podcast part of the community discussion on PeopleSoft administration. If you have comments, feedback, or topics you’d like us to talk about, we want to hear from you! You can email us at podcast@psadmin.io, tweet us at @psa_io, or use the Twitter hashtag #psadminpodcast.

You can listen to the podcast here on psadmin.io or subscribe with your favorite podcast player using the URL below, or subscribe in iTunes.

Podcast RSS Feed

Show Notes


From Kyle Benson: a servlet filter to remove PS_TOKEN from the response cookie:

One option is to simply disable the PS_TOKEN, and therefore prevent this vulnerability altogether! The problem is, PeopleSoft does not give us the option to disable it.

I decided to come up with a proof of concept for a custom solution to this issue. I wrote a Java servlet filter, called PSEatCookies, that will prevent a PS_TOKEN, or any other Cookie you specify, from being added to the ServletHttpResponse.

Limit PeopleSoft Vulnerabilities

Last week a presentation at Hack in the Box, “Oracle PeopleSoft Applications are Under Attack”, focused on vulnerabilities in PeopleSoft applications. The presentation showed a number of ways that hackers could get access to a system. While some of the issues need to be fixed by Oracle (like poor encryption), there are a number of steps you can take to reduce the risk of someone gaining unauthorized access to your system.

For reference, here is the presentation and here is the white paper.

Database Security

The first part of the presentation talks about back-end attacks (gaining access to the database). For someone who is on the internal network, there are a few ways to grab the Access ID.

Access ID Attacks

First, the Connect ID and password are often left to the default people and peop1e. The Connect ID has access to the PSACCESSPRFL table (by design), but the values in PSACCESSPRFL are not securely encrypted. According to the presentation, PeopleSoft uses a simple XOR operation to encrypt the values. XOR encryption is fairly simple to decrypt compared with newer encryption technologies. Update 5/11/2016 I have been informed that this is incorrect. XOR is not used for the Access ID and Password. The encrypt is 3des-168-cfb, which means it requires a 24 byte key, and a 64bit Initialization Vector, which is far harder to decrypt. End update The presentation also mentions that people often choose a Connect ID password that is the same as the Access ID. DO NOT DO THAT! Passwords should be unique and complex (as possible) so that one account doesn’t compromise other accounts.

This attack vector does bring up a concern that Oracle should address in a future PeopleTools release. Starting with 8.53, PSORPDEFN added a OPERPWSDSALT field that increased the complexity of password encryption. This functionality should be extended to the Access ID Password. Additionally, the limitation of an 8 character password for the Access ID password needs to be fixed.

Second, if someone has access to a developer machine there a two ways to grab the Access ID and password. One is to grab the configuration from the Windows Registry and decrypt the password from there. The encryption in the config file appears to be XOR based. The other method is to connect App Designer via 3-Tier connection and grab the network packets because the Tuxedo protocol is a plain text protocol. When developer tools communicate with the application server, their User ID and password are sent with each request. Plain text SQL is also sent via Tuxedo, and also executed under the Access ID, which is another potential issue.

In reality, the second attack requires far more access that most users have because it requires a 3-Tier connection along with App Designer access. It would be good for Oracle to start updating the Tuxedo protocol, but addressing the issues in the first attack would be the top priority. Another way to grab the Connect ID, is to open the psappsrv.cfg or psprcs.cfg files used by the Tuxedo domains. If a user has file server access to the process scheduler (very common for developers), they often times have read access to the process scheduler domain directory. If an administrator does not encrypt the Connect ID password when building the domain, anyone with read access can find the password.

Locking Down Database Access

  • Stop using default passwords
    Change the Connect ID password for your environment. You can even change the Connect ID itself, but changing the password from peop1e is the most important step.
  • Make the Access ID password unique
    While we can only have an 8 character password, make the password unique and complex. Don’t use dictionary words to make it memorable. Passwords need to be secure and complexity helps make them more secure.
  • Encrypt all passwords in config files
    When creating Tuxedo domains (application servers and process schedulers), make sure to encrypt any passwords in the file. The psadmin utility can do this for you when you configure the domain.

Web Security

The second part of the presentation focused on front-end attacks, or attacks through the web server. Front-end attacks are targeted at WebLogic, the PIA and other servlets delivered by PeopleSoft.

WebLogic Security

Attacks When deploying a Single Server PeopleSoft site, the WebLogic console is accessible on the same server & port as the PIA. Using http://server:port/console, anyone can access the WebLogic console login page. The default user and password for the console is system and Passw0rd in newer PeopleTools versions. If you do not change the password, a quick Google search can let anyone into the WebLogic console.

If you create a multi-server site, the Admin server will run on a separate port (or even server). You should still change the default passwords, but external hackers will have to discover the admin server and port before they can attempt an attack. There are two more accounts in WebLogic that can also expose a vulnerability: monitor and operator. These accounts are used for monitoring your WebLogic instance, but they offer enough access to the console that a hacker could install a .war application to run.

Locking Down WebLogic Access

  • Use a complex system password
    When creating a new PIA site, use a complex password for the system account. This account has full access to WebLogic (and subsequently the server file system) so do not use the default password.
  • Disable monitor and operator accounts
    If you are not using these accounts for monitoring, it is best to disable them. No need to have active accounts if they are unused. If you are using the accounts, make sure you change their password. Give these accounts unique passwords too; you don’t want to make them the same as the system account either.
  • Restrict access to the WebLogic console
    This post has an overview on how to limit access to the WebLogic console. If you are using a load balancer or RPS for external access (which is a good idea), you can block the IP address for those devices from the console. To access the console, you can VPN into your network and access the console from inside the network.

Servlet Attacks

Next in the list of web-based attacks are the servlets installed on the web server. There are a number of servlets installed on the web server like PSIGW, xmllink, etc. If you open up your web server directory structure (or through the WebLogic console) you can see the default servlets.

Some servlets handle XML processing (like PSIGW) and are susceptible to XXE (XML External Entity) attacks. XXE vulnerabilities allow for external code to be run on your web server.

Another attack vector (via XXE) is to read config files for passwords stored on your web server, like the integrationGateway.properties file for the PSIGW servlet. Passwords in this file can be encrypted, but the encryption uses the default 3DES key. You can tell this by looking at the beginning of the encrypted password string and seeing {V1.1}.

The last servlet attack mentioned is against the Integration Broker directly. The IB supports remote configuration (e.g, editing the integrationGateway.properties file via the PIA) and with a specially crafted URL an external system could read or overwrite the IB config file. Many organizations don’t change the default password (administrator and password) for the integrationGateway.properties file. This leaves the system vulnerable to an attack.

Locking Down Servlet Security

  • Patch WebLogic and PeopleTools
    The XXE vulnerability was fixed in WebLogic and also in these version of PeopleTools:

    • 8.51.24
    • 8.52.17
    • 8.53.05
  • Generate a new PSCipher key
    Before you encrypt values in the web server config files, run this command on the web server to generate a new key: pscipher -buildkey When you encrypt values on the web server, you’ll see {V1.2} at the beginning of the string. That will tell you that a new (and non-default) key was used to encrypt the password.
  • Give service accounts unique and complex passwords
    For accounts that you assign different parts of the application, like the Node Default User, or SES Callback User, give those accounts unique and complex passwords. (Have you picked up on a theme yet?)
  • Change the password IB Administrator password
    You can change the IB Administrator password by selecting the “Change Password” box under under the Gateway Setup Properties link on the IB Gateways page. You an also edit the gatewayUserProfile.xml file on the web server.

Single Signon Attacks

The last topic of the presentation focused on the Single Signon feature between PeopleSoft systems. PeopleSoft SSO is handled by the PS_TOKEN browser cookie. If a browser session contains a valid PS_TOKEN, and the issuing system is trusted by other PeopleSoft applications, users are considered authenticated and will have access to the application. The PS_TOKEN is generated using these values:

  • User ID
  • Language Code
  • Node Name
  • Date and Time
  • Signature (SHA1 Hash of User ID + Language Code + Node Name + Date and Time + Node Password)

By default, PeopleSoft uses standard node names for HR (PSFT_HR), FS (PSFT_EP) and the other applications. Since all but the Node Password are potentially known ahead of time, the SHA1 Hash can be calculated and compared against a PS_TOKEN to identify the Node Password.

While you could remove the trust from any nodes (PSTRUSTNODES table), that would break many features in the application (like the Report Repository and Single Signon). Removing node trust isn’t a great option.

Another way to get a PS_TOKEN is to open a page where the system automatically logs in as a public user. For example, a landing page or the PeopleSoft “Forgot My Password” page require the Web Profile to have a public user configured. If the public user has lots of security, any knowledge user can navigate into pages inside the application using the PS_TOKEN.

Locking Down SSO Access

  • Use a complex Node password
    Use a complex node password for your Default Local Node, and the other trusted nodes. The longer the password, the more time it will take to calculate the SHA1 hash.
  • Use unique node names for all environments
    Use a different node name for each application across all the environments (Development, Test, etc). For example, use HR92PRD for HR Production, HR92TST for HR Test, etc. Also, make your node passwords different between Dev, Test and Production. This will prevent someone from logging in to your Dev environment and using that valid PS_TOKEN to authenticate into Production.
  • Limit Public user security
    For the Public User on any Web Profiles, ensure they only have access to the fewest Components/WEBLIBS/etc needed to function. A PS_TOKEN generated by the user with limited security will prevent users from gaining unauthorized access to other parts of the application.
  • Implement Node Certificate Security
    Select Certificate for the node authentication method instead of Password. You will need to generate and load certificates for the Gateway URL for each node.
  • Use external authentication
    PeopleSoft can plug into different authentication methods, like LDAP and Kerberos. If you are using an external system for user authentication, you can reduce some of the risk with the PS_TOKEN issue by removing other applications’ nodes from the PSTRUSTNODES table.

GreyHeller has an excellent blog post with more details on the PS_TOKEN vulnerability and they show how their own tools can help with this security risk.

Recommendations for Oracle

With proper configuration, many of the vulnerabilities in this presentation can be properly mitigated. The main theme in the presentation, and in this article, is to not use default, shared or simple passwords.

There are some issues identified in the presentation that are out of our control. Oracle will need to make the changes in PeopleTools to address some of these vulnerabilities. To help bring visibility to the issues, filing a feature request SR with Oracle will show that there is user interest in making the product more secure. Here are three suggested SR’s to file:

  • Access ID Password needs to support complex passwords (more than 8 characters)
    The Access ID has an 8 character limit. To ensure the security of the database and its information, this password should only be limited by the RDBMS platform.
  • PSACCESSPRFL encryption support
    Like PSOPRDEFN, PSACCESSPRFL should support additional/newer encryption options (like using a SALT).
  • PS_TOKEN should generate a more secure hash
    The SHA1 hash used to create the PS_TOKEN signature should be updated to use a newer hashing algorithm, or find a more secure alternative. Utilizing the JSSE libraries on the web server would allow for stronger hashes to be built (albeit with some performance impacts).