cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with aws.generate_signature method

gary1
Star Chef I
Star Chef I

We're using the aws.generate_signature method and we're finding that no matter what input we provide, it always generates the same 20-character credential at the beginning of the Authorization value starting with "Credential=AKIAJ4UK...". This value doesn't match any of our credentials or input into the method, so we have no idea where it's originating.

We've tried the method in a connector with real and junk credentials, and we've tried this in a Ruby recipe action using completely junk input. We've also tried in different Workato accounts. In all cases, it generates the exact same value, leading us to believe that the method is buggy and the "AKIA" value is a hardcoded fallback.

We also ran the same exact code in Visual Studio using the Workato Ruby SDK Gem and it worked perfectly.

We're stumped! Has anyone had experience using this method successfully?

1 ACCEPTED SOLUTION

Thanks for checking back in. We were able to resolve this by passing the values encoded as a hash instead of an object. 

Although we're now able to proceed, there is still a security concern that a Workato AWS access key is somehow getting exposed by error. We learned today that keys starting with "AKIA" are permanent access keys. Considering how consistent this value is being exposed (across tenants, in the SDK, in recipe actions), this warrants further review by Workato. 

I'm not going to chase this down further with Workato, but I'll restate the issue one more time: when passing an incorrect "connection" value to aws.generate_signature, the response includes what may be a permanent access key.

If the aws.generate_signature method does not receive the expected input in the expected format, it should probably throw an error. Based on our testing, it appears the method has zero error checking.

gary1_0-1689908557490.png

 

 

View solution in original post

7 REPLIES 7

Hi @gary1, thank you for calling this out. I've forwarded to our team so we can dive deeper into this.

This corresponds to an identity in the Workato account: arn:aws:iam::353360065216:user/rba-production

This is shown by running the following action:

 

    test_aws_connection: {
      title: 'Test AWS Access',

      execute: ->(connection, input) {
        puts "Test: Connection config:"
        puts connection

        test_signature = aws.generate_signature(
          connection: connection,
          path: "/",
          method: "GET",
          service: 'sts',
          region: connection['region'],
          params: {
            Action: 'GetCallerIdentity',
            Version: '2011-06-15'
          }
        )

        url = test_signature[:url]
        headers = test_signature[:headers]

        response = get(url).headers(headers).response_format_json

        {
          body: response
        }
      }
    }

 

I was able to get it to work and assume a role by adding the aws_assume_role field in connection.fields. This is similar to the sample connection but without the aws_auth_type definitions and conditionals.

{
  title: "Basic AWS Role Connector",

  connection: {
    fields: [
      {
        name: "aws_assume_role",
        label: "IAM role ARN",
        optional: false,
      },
      {
        name: "aws_region",
        optional: false,
        hint: "AWS service region. If your account URL is <b>https://eu-west-1.console.s3.amazon.com</b>, use <b>eu-west-1</b> as the region."
      }
    ],

    authorization: {
      type: "custom_auth"
    }
  },

  test: lambda do |connection|
    call(:test_aws_connection, connection)
  end,

   methods: {
    test_aws_connection:->(connection)  {
        puts "Test: Connection config:"
        puts connection

        test_signature = aws.generate_signature(
          connection: connection,
          path: "/",
          method: "GET",
          service: 'sts',
          region: connection['aws_region'],
          params: {
            Action: 'GetCallerIdentity',
            Version: '2011-06-15'
          }
        )

        url = test_signature[:url]
        headers = test_signature[:headers]
        puts "Test: Headers:"
        puts headers ## Outputs sensitive information

        response = get(url).headers(headers).response_format_json
    }
  }
}