yahoo-eng-team team mailing list archive
-
yahoo-eng-team team
-
Mailing list archive
-
Message #65842
[Bug 1618615] Re: Potential information disclosure in EC2 "credentials"
will add a docs bug for this issue.
** Changed in: ossn
Status: New => Won't Fix
--
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to OpenStack Identity (keystone).
https://bugs.launchpad.net/bugs/1618615
Title:
Potential information disclosure in EC2 "credentials"
Status in OpenStack Identity (keystone):
New
Status in OpenStack Security Advisory:
Won't Fix
Status in OpenStack Security Notes:
Won't Fix
Bug description:
When creating a "credential" in Keystone, instead of using
uuid.uuid4() like in most places to generate a unique identifier, the
id is created from the SHA256 hash value of whatever is passed in as
the "access" key in the POST request (Code here:
https://github.com/openstack/keystone/blob/master/keystone/credential/controllers.py#L36-L60)
===== EXAMPLE REQUEST =====
POST /v3/credentials HTTP/1.1
Host: [ENDPOINT]
X-Auth-Token: [ADMIN TOKEN]
Content-Length: 231
Content-Type: application/json
{
"credential": {
"blob": "{\"access\":\"<script>alert(2)</script>\",\"secret\":\"secretKey\"}",
"project_id": "12345",
"type": "ec2",
"user_id": "12345"
}
}
HTTP/1.1 201 Created
Date: Tue, 30 Aug 2016 19:14:54 GMT
Server: Apache/2.4.7 (Ubuntu)
Vary: X-Auth-Token
Content-Length: 383
Content-Type: application/json
{"credential": {"user_id": "12345", "links": {"self":
"[ENDPOINT]/v3/credentials/141ce7a938b5973dd71c90bcdd7e4097317ee7374259cf6d8774fdfd86c1f8ea"},
"blob":
"{\"access\":\"<script>alert(2)</script>\",\"secret\":\"secretKey\"}",
"project_id": "12345", "type": "ec2", "id":
"141ce7a938b5973dd71c90bcdd7e4097317ee7374259cf6d8774fdfd86c1f8ea"}}
===== /EXAMPLE =====
The id from the example above is
"141ce7a938b5973dd71c90bcdd7e4097317ee7374259cf6d8774fdfd86c1f8ea",
which is the same as the SHA256 value of "<script>alert(2)</script>"
(you can test this with `echo -n "<script>alert(2)</script>" | openssl
dgst -sha256` on *nix)
The documentation here seems to show MD5s and possibly tenant IDs used
as "access" values: http://developer.openstack.org/api-
ref/identity/v3/?expanded=assign-role-to-user-on-projects-owned-by-
domain-detail,create-policy-detail,show-credential-details-detail
,list-credentials-detail,create-credential-detail#list-credentials
Bruteforcing an actual MD5 isn't a huge security risk (i.e. trying to
predict all 32 characters from thin air), but if the MD5 is a hash of
a known value (i.e. the string "admin"), it would be trivial to test
for common values:
md5(admin) = 21232f297a57a5a743894a0e4a801fc3
sha256(21232f297a57a5a743894a0e4a801fc3) = 465c194afb65670f38322df087f0a9bb225cc257e43eb4ac5a0c98ef5b3173ac
If tenant IDs are used, this task becomes even easier: just generate
SHA256 hashes for 0 - 999999
A non-admin user can determine whether there are credentials using a
given access key by attempting to access the resource from its sha256
url identifier:
===== EXAMPLE REQUESTS =====
Existing credential
GET /v3/credentials/141ce7a938b5973dd71c90bcdd7e4097317ee7374259cf6d8774fdfd86c1f8ea HTTP/1.1
Host: [ENDPOINT]
X-Auth-Token: [NON-ADMIN TOKEN]
Content-Type: application/json
Connection: close
HTTP/1.1 403 Forbidden
Date: Tue, 30 Aug 2016 19:55:24 GMT
Server: Apache/2.4.7 (Ubuntu)
Vary: X-Auth-Token
Content-Length: 140
Content-Type: application/json
{"error": {"message": "You are not authorized to perform the
requested action: identity:get_credential", "code": 403, "title":
"Forbidden"}}
Non-existent credential
GET /v3/credentials/deadbeef HTTP/1.1
Host: [ENDPOINT]
X-Auth-Token: [NON-ADMIN TOKEN]
Content-Type: application/json
HTTP/1.1 404 Not Found
Date: Tue, 30 Aug 2016 20:03:38 GMT
Server: Apache/2.4.7 (Ubuntu)
Vary: X-Auth-Token
Content-Length: 96
Content-Type: application/json
{"error": {"message": "Could not find credential: deadbeef",
"code": 404, "title": "Not Found"}}
===== /EXAMPLE =====
It is also possible to get a 500 error by creating a credential with
an invalid character in the "access" key:
===== EXAMPLE REQUEST =====
POST /v3/credentials HTTP/1.1
Host: [ENDPOINT]
X-Auth-Token: [ADMIN TOKEN]
Content-Length: 212
Content-Type: application/json
{
"credential": {
"blob": "{\"access\":\"\uffff\",\"secret\":\"secretKey\"}",
"project_id": "12345",
"type": "ec2",
"user_id": "12345"
}
}
HTTP/1.1 500 Internal Server Error
Date: Tue, 30 Aug 2016 20:06:16 GMT
Server: Apache/2.4.7 (Ubuntu)
Vary: X-Auth-Token
Content-Length: 143
Content-Type: application/json
{"error": {"message": "An unexpected error prevented the server
from fulfilling your request.", "code": 500, "title": "Internal Server
Error"}}
===== /EXAMPLE =====
I'm unsure what the security impact would be here, mainly because of
the ambiguous examples provided in the Keystone API documentation
(linked above). If either of the 2 scenarios I outlined is a
reasonable use case (i.e. MD5 of a guessable value, or tenant IDs),
there may be a risk of information leakage by brute-force. It would
also be possible to prevent others from creating credentials with a
given access key by simply creating lots of credentials in Keystone
with predictable access keys. This would cause a collision whenever
attempting to create a credential set with an access key that has
already been used.
If, on the other hand, the credentials are always in the format
described by AWS here ( link:
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSGettingStartedGuide/AWSCredentials.html
), it would require a huge number of requests to bruteforce the access
key (though it would not be impossible). However, it would be
possible, using the approach described above with a regular user
token, to determine whether a known EC2 access key was in place as a
credential in a given Keystone database.
I'm unclear on the utility of using SHA256 for the identifier at all
here, since random UUIDs would make this potential issue moot.
To manage notifications about this bug go to:
https://bugs.launchpad.net/keystone/+bug/1618615/+subscriptions