[FOLIO-2287] Valid X-Okapi-Token (with permissions) returned on invalid login Created: 24/Sep/19  Updated: 26/Feb/21  Resolved: 26/Sep/19

Status: Closed
Project: FOLIO
Components: None
Affects versions: None
Fix versions: None

Type: Bug Priority: P1
Reporter: Craig McNally Assignee: Adam Dickmeiss
Resolution: Done Votes: 1
Labels: bugfest_q3.2.2019, platform-backlog, q3.2-2019, security
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original estimate: Not Specified
Environment:

folio-testing, daisy


Issue links:
Blocks
is blocked by MODLOGIN-117 Update to RMB 25.0.2 Closed
is blocked by MODUSERBL-79 Update to RMB 25.0.2 Closed
Relates
relates to FOLIO-2286 X-Okapi-Module-Tokens response header... Closed
relates to OKAPI-763 Prevent X-Okapi-Token being returned ... Closed
relates to MODLOGIN-119 change login API to return tokens in ... Closed
relates to RMB-478 RMB echoes all headers Closed
relates to STCOR-391 Fix invalid x-okapi-token header error Closed
Sprint: CP: sprint 73
Story Points: 3
Development Team: Core: Platform

 Description   

Overview

It was discovered that when logging in with bogus credentials you get an appropriate error response, but also a valid token with the following permissions:

  [
    "auth.signtoken",
    "auth.signrefreshtoken",
    "users.collection.get",
    "users.item.put",
    "users.item.get",
    "configuration.entries.collection.get"
  ]

Reproducer

1. Login with bad credentials

$ curl https://folio-testing-okapi.aws.indexdata.com:443/authn/login -H 'Content-Type: application/json' -H 'X-Okapi-Tenant: diku' --data-binary '{"username":"foo","password":"bar"}' -v -w '\n'
+ curl https://folio-testing-okapi.aws.indexdata.com:443/authn/login -H 'Content-Type: application/json' -H 'X-Okapi-Tenant: diku' --data-binary '{"username":"foo","password":"bar"}' -v -w '\n'
*   Trying 52.72.80.49...
* Connected to folio-testing-okapi.aws.indexdata.com (52.72.80.49) port 443 (#0)
* found 148 certificates in /etc/ssl/certs/ca-certificates.crt
* found 597 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* 	 server certificate verification OK
* 	 server certificate status verification SKIPPED
* 	 common name: *.aws.indexdata.com (matched)
* 	 server certificate expiration date OK
* 	 server certificate activation date OK
* 	 certificate public key: RSA
* 	 certificate version: #3
* 	 subject: CN=*.aws.indexdata.com
* 	 start date: Thu, 23 May 2019 00:00:00 GMT
* 	 expire date: Tue, 23 Jun 2020 12:00:00 GMT
* 	 issuer: C=US,O=Amazon,OU=Server CA 1B,CN=Amazon
* 	 compression: NULL
* ALPN, server accepted to use http/1.1
> POST /authn/login HTTP/1.1
> Host: folio-testing-okapi.aws.indexdata.com
> User-Agent: curl/7.47.0
> Accept: */*
> Content-Type: application/json
> X-Okapi-Tenant: diku
> Content-Length: 35
> 
* upload completely sent off: 35 out of 35 bytes
< HTTP/1.1 422 Unprocessable Entity
< Date: Tue, 24 Sep 2019 18:54:15 GMT
< Content-Type: application/json
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Okapi-Trace: POST mod-authtoken-2.3.0-SNAPSHOT.55 http://10.36.1.89:9132/authn/login : 202 2984us
< x-forwarded-for: 140.234.253.9
< x-forwarded-proto: https
< x-forwarded-port: 443
< host: folio-testing-okapi.aws.indexdata.com
< x-amzn-trace-id: Root=1-5d8a6657-3ecd6a4e80aa647813c1ebda
< user-agent: curl/7.47.0
< accept: */*
< x-okapi-tenant: diku
< x-okapi-request-id: 618738/authn
< x-okapi-url: http://10.36.1.89:9130
< x-okapi-request-ip: 10.36.1.246
< x-okapi-request-timestamp: 1569351255862
< x-okapi-request-method: POST
< x-okapi-permissions: []
< x-okapi-token: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJVTkRFRklORURfVVNFUl9fMTAuMzYuMS44OTo0ODgyOF9fMjAxOS0wOS0yNFQxODo1NDoxNS44NjQrMDAwMCIsIm1vZHVsZSI6Im1vZC1sb2dpbi02LjEuMC1TTkFQU0hPVC42NSIsImV4dHJhX3Blcm1pc3Npb25zIjpbImF1dGguc2lnbnRva2VuIiwiYXV0aC5zaWducmVmcmVzaHRva2VuIiwidXNlcnMuY29sbGVjdGlvbi5nZXQiLCJ1c2Vycy5pdGVtLnB1dCIsInVzZXJzLml0ZW0uZ2V0IiwiY29uZmlndXJhdGlvbi5lbnRyaWVzLmNvbGxlY3Rpb24uZ2V0Il0sInJlcXVlc3RfaWQiOiI2MTg3MzhcL2F1dGhuIiwidGVuYW50IjoiZGlrdSJ9.cE-oO4uJzR05ArSqMMA_dR89HcNA0cgc72Ped7Mb-aQ
< x-okapi-match-path-pattern: /authn/login
< X-Okapi-Trace: POST mod-login-6.1.0-SNAPSHOT.65 http://10.36.1.89:9135/authn/login : 422 13785us
< 
{
  "errors" : [ {
    "message" : "Error verifying user existence: No user found by username foo",
    "type" : "error",
    "code" : "username.incorrect",
    "parameters" : [ {
      "key" : "username",
      "value" : "foo"
    } ]
  } ]
* Connection #0 to host folio-testing-okapi.aws.indexdata.com left intact
}

2. Decode the token:

{
  "sub": "UNDEFINED_USER__10.36.1.89:48828__2019-09-24T18:54:15.864+0000",
  "module": "mod-login-6.1.0-SNAPSHOT.65",
  "extra_permissions": [
    "auth.signtoken",
    "auth.signrefreshtoken",
    "users.collection.get",
    "users.item.put",
    "users.item.get",
    "configuration.entries.collection.get"
  ],
  "request_id": "618738/authn",
  "tenant": "diku"
}


 Comments   
Comment by Adam Dickmeiss [ 24/Sep/19 ]

I get mod-login-6.1.0-SNAPSHOT.65 and mod-authtoken-2.3.0-SNAPSHOT.55 .

Comment by Adam Dickmeiss [ 24/Sep/19 ]

I'll look at this first thing tomorrow morning. My guess is that it's a trivial fix.

Comment by Hongwei Ji [ 24/Sep/19 ]

Just a FYI, I tried it on q1 Vagrant and it has the same issue. Maybe Okapi can remove the non-authenticated token before returning the response.

x-okapi-token: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJVTkRFRklORURfVVNFUl9fMTAuMC4yLjE1OjUzNTk0X18yMDE5LTA5LTI0VDE5OjMzOjUwLjU2NyswMDAwIiwibW9kdWxlIjoibW9kLWxvZ2luLTUuMS4wIiwiZXh0cmFfcGVybWlzc2lvbnMiOlsiYXV0aC5zaWdudG9rZW4iLCJhdXRoLnNpZ25yZWZyZXNodG9rZW4iLCJ1c2Vycy5jb2xsZWN0aW9uLmdldCIsInVzZXJzLml0ZW0ucHV0IiwidXNlcnMuaXRlbS5nZXQiLCJjb25maWd1cmF0aW9uLmVudHJpZXMuY29sbGVjdGlvbi5nZXQiXSwicmVxdWVzdF9pZCI6IjcwMTk1M1wvYXV0aG4iLCJ0ZW5hbnQiOiJkaWt1In0.EURjNFl1cUo38KmztOHLhvgkTLCtt2BA4-svStpOLoM
{
  "sub": "UNDEFINED_USER__10.0.2.15:53594__2019-09-24T19:33:50.567+0000",
  "module": "mod-login-5.1.0",
  "extra_permissions": [
    "auth.signtoken",
    "auth.signrefreshtoken",
    "users.collection.get",
    "users.item.put",
    "users.item.get",
    "configuration.entries.collection.get"
  ],
  "request_id": "701953/authn",
  "tenant": "diku"
}
Comment by Craig McNally [ 24/Sep/19 ]

Also note that this is also an issue with /bl-users/login - though the token has different permissions:

  [
    "users.item.get",
    "users.collection.get",
    "perms.users.item.get",
    "perms.users.get",
    "usergroups.item.get",
    "inventory-storage.service-points-users.collection.get",
    "inventory-storage.service-points-users.item.get",
    "inventory-storage.service-points.collection.get",
    "inventory-storage.service-points.item.get"
  ]

Not sure if we need a separate issue for this or not...

Comment by Hongwei Ji [ 24/Sep/19 ]

Looks to me all those perms are coming from the API level modulePermissions. For example;
https://github.com/folio-org/mod-login/blob/master/descriptors/ModuleDescriptor-template.json#L37-L40
https://github.com/folio-org/mod-users-bl/blob/master/descriptors/ModuleDescriptor-template.json#L38-L49

Comment by Adam Dickmeiss [ 25/Sep/19 ]

Moving this issue to Folio because it's not related to mod-authtoken . The main problem is that all RMB modules echo most/all request headers to response. This makes mod-login return all its request headers - including X-Okapi-Token that it got from Okapi that contains module permissions for mod-login. The reason why it even works - when a successful login is performed must be due to RMB overriding the response header .. headers201().. thingy. But when that is not called due to error 400, the request headers are just relayed.

While it's possible RMB and it should be fixed so that RMB modules do not return response headers - not mentioned in RAML - except for fundamental ones, like Content-Type and Content-Length .. The problem is that it will take weeks for all modules to be updated to a fixed RMB. So for this reason, we believe it's best to make a change to Okapi to, at least, ignore the returned X-Okapi-Token in the "faulty" cases.

Comment by Marc Johnson [ 25/Sep/19 ]

The main problem is that all RMB modules echo most/all request headers to response. This makes mod-login return all its request headers - including X-Okapi-Token that it got from Okapi that contains module permissions for mod-login.

Agreed, that has been bugging me for a while. I imagine in the early days it was convenient and useful for debugging.

The reason why it even works - when a successful login is performed must be due to RMB overriding the response header .. headers201().. thingy. But when that is not called due to error 400, the request headers are just relayed.

I didn't realise this didn't occur on success, only that it mattered less, because in that case the token would be replaced by a legitimate user token.

While it's possible RMB and it should be fixed so that RMB modules do not return response headers - not mentioned in RAML - except for fundamental ones, like Content-Type and Content-Length .. The problem is that it will take weeks for all modules to be updated to a fixed RMB. So for this reason, we believe it's best to make a change to Okapi to, at least, ignore the returned X-Okapi-Token in the "faulty" cases.

This seems like a reasonable approach. What could be considered faulty? Is it based upon the module producing the response, the status code etc?

Comment by Adam Dickmeiss [ 25/Sep/19 ]

1. There's a PR for RMB out now https://github.com/folio-org/raml-module-builder/pull/526 .. A matter of removing lines of code and a comment that it was problematic to just copy them down Of course mod-login is using RMB 25.0.1 and not RMB 27 and of course, it just hangs when you compile with RMB 27. We tried to backport the fix to the b25 branch without problems and we were able to install a mod-login on vagrant-testing box and saw that indeed that fixes the issue.

2. It's not easy to fix it in Okapi and .. quite frankly, should we even bother? In general how can Okapi know what's a secret or not.. We know this one is. We'll see if wen can fix it there as well.

The shortest path to fixing is - it seems - release RMB 25.0.2 and release mod-login using that.

Comment by Marc Johnson [ 25/Sep/19 ]

Adam Dickmeiss Thanks for the quick work.

2. It's not easy to fix it in Okapi and .. quite frankly, should we even bother? In general how can Okapi know what's a secret or not.. We know this one is. We'll see if wen can fix it there as well.

I thought you were advocating for that change. My questions above were to explore the practicalities of that approach. I agree that it could get complicated and it might not be Okapi's place to do that.

The shortest path to fixing is - it seems - release RMB 25.0.2 and release mod-login using that.

I agree, that is the most expedient thing to do, and it resolves this issue. Broader changes can be deferred and thought about more.

Comment by Adam Dickmeiss [ 25/Sep/19 ]

mod-login 6.1.1 is now released. This hopefully resolves the immediate issue. All RMB based modules should be updated as well. After a user is logged in, all RMB modules will return all headers, some of which should NOT be shared with users.

Comment by jroot [ 25/Sep/19 ]

How does this behave, when Okapi is secured? Or does this assume a secured Okapi?

Comment by Anton Emelianov (Inactive) [ 25/Sep/19 ]

Moved this bug to mod-login because FOLIO project is filtered out from release dashboard.

Comment by Adam Dickmeiss [ 25/Sep/19 ]

Anton Emelianov I'm inclined to revert your project move..

The product related issues and those that are pertained to Q3.2 releases are in MODLOGIN-117 Closed MODUSERBL-79 Closed RMB-468 Closed ..

The security issue does NOT only pertain to mod-login.

Comment by Adam Dickmeiss [ 25/Sep/19 ]

jroot .. not really related to secured Okapi at all.. If supertenant is secured , then that user (like others users) can be tampered with until this is fixed.

Comment by Anton Emelianov (Inactive) [ 25/Sep/19 ]

Adam Dickmeiss, FOLIO project contains a lot of tickets that don't have any significance for product releases (a lot of DevOps staff, for example). This is why I am filtering out FOLIO project on release dashboards. I don't mind if you have a better home for this ticket other than FOLIO.

Comment by Jakub Skoczen [ 26/Sep/19 ]

[EDITED]

I have moved this ticket back to FOLIO as the issue is present in both mod-login and mod-users-bl. This also now fixed directly in those module (see linked BLOCKERs).

This is the critical security problem, exploitable be a remote attacker vs FOLIO-2286 Closed which is only exploitable locally (we believe).

Comment by Jakub Skoczen [ 26/Sep/19 ]

Verified by Craig McNally

Generated at Thu Feb 08 23:19:32 UTC 2024 using Jira 1001.0.0-SNAPSHOT#100246-sha1:7a5c50119eb0633d306e14180817ddef5e80c75d.