Pithos 0.3.3: fix SignatureDoesNotMatch when opening a bucket
The SigV4 encoder kept '/' unescaped in object paths by swapping in a "never matches" regex (/$^/) for query values, but that regex matches the empty string, so every empty query value went out as "/": prefix= became prefix=/ and ?policy became ?policy=/. The request then no longer matched what was signed, and listing any bucket or reading its policy failed against s3d. Bucket listing and creation carry no query, so they worked. Verified end to end against s3d (list, folders, upload, download, public policy, folder delete) and against the aws cli; two regression tests.
This commit is contained in:
parent
c09872122a
commit
735482d3b6
4 changed files with 24 additions and 5 deletions
|
|
@ -14,9 +14,11 @@ const hmac = (k, s) => crypto.createHmac('sha256', k).update(s).digest();
|
|||
|
||||
// RFC 3986 encoding as SigV4 wants it; '/' kept for object keys in paths.
|
||||
function uriEncode(str, keepSlash) {
|
||||
return encodeURIComponent(str)
|
||||
.replace(/[!'()*]/g, (c) => '%' + c.charCodeAt(0).toString(16).toUpperCase())
|
||||
.replace(keepSlash ? /%2F/g : /$^/, '/');
|
||||
const out = encodeURIComponent(str)
|
||||
.replace(/[!'()*]/g, (c) => '%' + c.charCodeAt(0).toString(16).toUpperCase());
|
||||
// (A "never matches" regex like /$^/ is not one: it matches the empty
|
||||
// string, which turned every empty query value into "/".)
|
||||
return keepSlash ? out.replace(/%2F/g, '/') : out;
|
||||
}
|
||||
|
||||
function canonicalQuery(query) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "pithos",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.3",
|
||||
"description": "A control panel for s3d, the Sia S3 gateway: daemon, users and keys, buckets, upload pipeline.",
|
||||
"license": "MPL-2.0",
|
||||
"type": "module",
|
||||
|
|
|
|||
|
|
@ -77,3 +77,20 @@ test('presigned URL matches aws cli', { skip: !hasAws && 'aws cli not installed'
|
|||
assert.equal(ours.pathname, t.pathname);
|
||||
assert.equal(ours.searchParams.get('X-Amz-Signature'), t.searchParams.get('X-Amz-Signature'));
|
||||
});
|
||||
|
||||
// Regression: empty query values (prefix=, policy) were sent as "/" and
|
||||
// every bucket listing failed with SignatureDoesNotMatch against s3d.
|
||||
test('empty query values stay empty and match the aws cli', { skip: !hasAws && 'aws cli not installed' }, async () => {
|
||||
let port;
|
||||
const req = await capture((p) => { port = p; return runAws(['s3api', 'list-objects-v2', '--bucket', 'my-bucket', '--prefix', '', '--delimiter', '/', '--endpoint-url', `http://127.0.0.1:${p}`]); });
|
||||
const { theirs, ours } = resign(port, req, 'my-bucket');
|
||||
assert.equal(ours, theirs);
|
||||
});
|
||||
|
||||
test('client sends empty values as empty', async () => {
|
||||
const seen = await new Promise((resolve) => {
|
||||
const server = http.createServer((req, res) => { res.end('<ListBucketResult><IsTruncated>false</IsTruncated></ListBucketResult>'); server.close(); resolve(req.url); });
|
||||
server.listen(0, '127.0.0.1', () => new S3Client({ endpoint: `http://127.0.0.1:${server.address().port}`, accessKeyId: AK, secretKey: SK }).listObjects('b').catch(() => {}));
|
||||
});
|
||||
assert.match(seen, /[?&]prefix=(&|$)/);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "pithos",
|
||||
"name": "Pithos",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.3",
|
||||
"description": "Run s3d, the Sia S3 gateway, from the Theseus sidebar: connect it to a Sia indexer, create S3 users and access keys, browse and share buckets, and watch uploads reach Sia.",
|
||||
"author": "Silent Mode",
|
||||
"icon": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJnIiB4MT0iMCIgeTE9IjAiIHgyPSIwIiB5Mj0iMSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjM2RkYzk3Ii8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMWU4ZjZhIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHBhdGggZD0iTTIyIDZoMjB2NWMwIDItMiAzLTIgNSA4IDMgMTQgMTEgMTQgMjEgMCAxMi05IDIxLTIyIDIxUzEwIDQ5IDEwIDM3YzAtMTAgNi0xOCAxNC0yMSAwLTItMi0zLTItNXoiIGZpbGw9InVybCgjZykiLz48cGF0aCBkPSJNMTQgMzBoMzZNMTMgNDBoMzgiIHN0cm9rZT0iIzBiMWYxOCIgc3Ryb2tlLXdpZHRoPSIzIiBzdHJva2UtbGluZWNhcD0icm91bmQiIG9wYWNpdHk9Ii41NSIvPjwvc3ZnPgo=",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue