aws / aws-sdk-js

AWS SDK for JavaScript in the browser and Node.js
https://aws.amazon.com/developer/language/javascript/
Apache License 2.0
7.59k stars 1.55k forks source link

Unable to sign AWS IoT MQTT/WSS url #1456

Closed prestomation closed 4 years ago

prestomation commented 7 years ago

Hi,

I set out with the intention of submitting a simple PR to allow simple presigning of a IoT websocket url. Using the sample code in the IoT docs is..not something I want to continue to do :) http://docs.aws.amazon.com/iot/latest/developerguide/protocols.html#mqtt-ws

Problem is, the JS sdk always signs the x-Amz-Security-Token header, but AWS IoT does NOT accept this header if it's signed. CPP SDK also has this issue: https://github.com/aws/aws-sdk-cpp/pull/338

  1. Is it acceptable to modify the SDK to never sign this header?(I don't really see security implications as it's an encrypted blob, but I dunno if other services expect it to be signed)
  2. If not 1, what is the best way to ask AWS IoT to allow this header to be signed?
  3. What other options do we have here?

Thanks!

jeskew commented 7 years ago

Hi @prestomation,

From the sample code in the developer guide you linked to, signed websocket URLs shouldn't include any headers but should instead hoist everything that would normally be a header to the query string. That's pretty close in spirit to the way the SDK's S3 and Polly presigners work, but different enough that I think we would need a custom signer.

carlnordenfelt commented 7 years ago

I'm running on Lambda and doing just what you want to do I think:

var v4 = require('aws-signature-v4');
function signEndpointUrlAwsV4(endpointAddress) {
    var signedUrl = v4.createPresignedURL(
        'GET',
        endpointAddress,
        '/mqtt',
        'iotdevicegateway',
        signatureV4Hash,
        {
            key: process.env.AWS_ACCESS_KEY_ID,
            secret: process.env.AWS_SECRET_ACCESS_KEY,
            region: process.env.AWS_REGION,
            protocol: 'wss',
            expires: WSS_URL_EXPIRY_SECONDS
        }
    );
    return signedUrl + '&X-Amz-Security-Token=' + encodeURIComponent(process.env.AWS_SESSION_TOKEN);
};
prestomation commented 7 years ago

Err, yes, in the query parameters of course.

Thanks @carlnordenfelt, makes sense. I just wish this sort of interface was more cleanly available in the SDK so I don't need to have multiple copies of the signing code. I hacked something together using the SDK, it's pretty ugly though! https://gist.github.com/prestomation/b0f15b4492146a64b9deffaf7ef011eb#file-iot_presign-js

rianwouters commented 5 years ago

Also see this AWS SDK extension: https://gist.github.com/rianwouters/17605cdb84a28ab59c89f2a46a7a36be

ajredniwja commented 4 years ago

Closing this issue, please open it at https://github.com/aws/aws-iot-device-sdk-js-v2/issues.

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.