diff --git a/nodejs/s3/s3handler.js b/nodejs/s3/s3handler.js index 19435ec..92da09e 100644 --- a/nodejs/s3/s3handler.js +++ b/nodejs/s3/s3handler.js @@ -36,6 +36,7 @@ var express = require("express"), // Set these two values to match your environment expectedBucket = "fineuploadertest", + expectedHostname = "fineuploadertest.s3.amazonaws.com", // CHANGE TO INTEGERS TO ENABLE POLICY DOCUMENT VERIFICATION ON FILE SIZE // (recommended) @@ -96,8 +97,9 @@ function signRequest(req, res) { // Signs multipart (chunked) requests. Omit if you don't want to support chunking. function signRestRequest(req, res) { - var stringToSign = req.body.headers, - signature = req.query.v4 ? signV4RestRequest(stringToSign) : signV2RestRequest(stringToSign); + var version = req.query.v4 ? 4 : 2, + stringToSign = req.body.headers, + signature = version === 4 ? signV4RestRequest(stringToSign) : signV2RestRequest(stringToSign); var jsonResponse = { signature: signature @@ -105,7 +107,7 @@ function signRestRequest(req, res) { res.setHeader("Content-Type", "application/json"); - if (req.query.v4 || isValidRestRequest(stringToSign)) { + if (isValidRestRequest(stringToSign, version)) { res.end(JSON.stringify(jsonResponse)); } else { @@ -119,8 +121,11 @@ function signV2RestRequest(headersStr) { } function signV4RestRequest(headersStr) { - var matches = /.+\n.+\n(\d+)\/(.+)\/s3\/.+\n(.+)/.exec(headersStr); - return getV4SignatureKey(clientSecretKey, matches[1], matches[2], "s3", headersStr); + var matches = /.+\n.+\n(\d+)\/(.+)\/s3\/aws4_request\n([\s\S]+)/.exec(headersStr), + hashedCanonicalRequest = CryptoJS.SHA256(matches[3]), + stringToSign = headersStr.replace(/(.+s3\/aws4_request\n)[\s\S]+/, '$1' + hashedCanonicalRequest); + + return getV4SignatureKey(clientSecretKey, matches[1], matches[2], "s3", stringToSign); } // Signs "simple" (non-chunked) upload requests. @@ -166,7 +171,11 @@ function signV4Policy(policy, base64Policy) { // Ensures the REST request is targeting the correct bucket. // Omit if you don't want to support chunking. -function isValidRestRequest(headerStr) { +function isValidRestRequest(headerStr, version) { + if (version === 4) { + return new RegExp("host:" + expectedHostname).exec(headerStr) != null; + } + return new RegExp("\/" + expectedBucket + "\/.+$").exec(headerStr) != null; }