8

I've been trying to set up Amazon's STS (Security Token Service) to create temporary credentials for client side uploads to S3.

I can get the code working fine with an access key generated from the IAM user, but when I swap out the access key/secret key and then add the session token I am getting a 403 Forbidden. S3 access logs do not log the attempt.

On the STS side I am generating the credentials via the aws-sdk for node.js, using the same IAM user as above, the SDK generates the STS credentials happily:

let sts = new AWS.STS({apiVersion: '2011-06-15'});
sts.assumeRole({
  RoleArn: 'arn:aws:iam::[REMOVED]:role/[REMOVED]',
  RoleSessionName: [REMOVED (generated by concatenating a few ids)]
  DurationSeconds: 60 * 20,
}, (err, data)=>{
  //callback handling
});

Upload test code:

var AWS = require('aws-sdk');

// Load the stream
var fs = require('fs');
var body = fs.createReadStream('./helloworld.txt');

AWS.config.update({
  region: 'ap-southeast-2',
  accessKeyId: '[REMOVED]',
  secretAccessKey: '[REMOVED]',
  sessionToken: '[REMOVED]'
});

// Upload the stream
var s3 = new AWS.S3();

s3.putObject({
  Body: body,
  Bucket: '[REMOVED]',
  Key: 'helloworld.txt'
}, function(err, data) {
  if (err) console.log(err, err.stack); // an error occurred
  else     console.log(data);           // successful response
});

aws-sdk version: 2.4.8 node.js: 4.2.3

I've tested the role policy that it assumes using the IAM simulator which says it's fine. Tried on both browser side and server side uploading using the sdk.

I opened up the S3 CORS (for debugging) to make sure nothing weird was going on there:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <MaxAgeSeconds>0</MaxAgeSeconds>
        <ExposeHeader>ETag</ExposeHeader>
        <ExposeHeader>x-amz-server-side-encryption</ExposeHeader>
        <ExposeHeader>x-amz-request-id</ExposeHeader>
        <ExposeHeader>x-amz-id-2</ExposeHeader>
        <AllowedHeader>*</AllowedHeader>
        <AllowedHeader>x-amz-acl</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

S3 policy I've opened up (again for debugging):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "[REMOVED]"
            ]
        }
    ]
}

Any ideas?

eetee
  • 125
  • 1
  • 5

1 Answers1

0

Turns out the missing configuration was the ACL on the bucket itself, the original ACL allowed my root account to make all changes, I'm guessing the IAM account where the code worked was inheriting some sort of permission.

Adding this extra line for upload/delete worked.

Screenshot of the configuration change

eetee
  • 125
  • 1
  • 5
  • 4
    **WARNING BEWARE** Authenticated Users—This group consists of any user that has an Amazon AWS Account. When you grant the Authenticated User group permission, any valid signed request can perform the appropriate action. The request can be signed by either an AWS Account or IAM User. **In short, you have opened access to your S3 bucket for ANY USER with an AWS Account** –  Jul 24 '17 at 22:35
  • I don't think this answer solves the question. You just opened up your bucket. STS/assume role has no point now – chickenman May 10 '18 at 18:10