strapi-provider-upload-azure-storage
strapi-provider-upload-azure-storage copied to clipboard
[Question] Why SaSToken is presented in every image url?
Hello guys! First of all thank you for amazing work, the plugin is so useful.
Overview
Once image (media) is loaded into the strapi, it can be returned by requesting some data which is using that image. In the result I can see the SaS token which was passed initially into the plugin setup.
Question
Was it done intentionally or I did something wrong in the setup ?
Why I am asking? If I get correctly, It is pretty easy to steal this token in this implementioan and get an CRUD access to the blob storage.
This is intentional. Following the Azure blob storage docs. We use an anon client when the sas token is present in the service url
example here: https://github.com/Azure/azure-sdk-for-js/blob/7e0cdab9146df801c3111e1d93b35aafd471084b/sdk/storage/storage-blob/samples/javascript/anonymousCred.js#L18C1-L26
ah i see @jakeFeldman actually it can create a security issue for people who use it then
const { BlobServiceClient } = require("@azure/storage-blob");
async function main() {
try {
const sas = ""; // SAS TOKEN which can be token from url
const account = ""; // account name
const containerName = ""; // name
const blobServiceClient = new BlobServiceClient(
`https://${account}.blob.core.windows.net?${sas}`
);
const containerClient = blobServiceClient.getContainerClient(containerName);
const blobName = "assets/image.png";
const blockBlobClient = containerClient.getBlockBlobClient(blobName);
const content = "Hello world!";
// Upload new content to the blob (this will overwrite existing content)
const uploadBlobResponse = await blockBlobClient.upload(
content,
Buffer.byteLength(content)
);
console.log(
`Upload block blob ${blobName} successfully`,
uploadBlobResponse.requestId
);
} catch (e) {
console.log(e);
}
}
main()
.then(() => console.log("Done"))
.catch((ex) => console.log(ex.message));
it seems to me that plugin should work at least with two keys:
- Internal token for crud;
- Public token for reading;
Some possible solution:
async isPrivate() {
return true;
},
async getSignedUrl(file) {
return {
url: file.url.replace(
process.env.STORAGE_ACCOUNT_SAS_TOKEN,
process.env.STORAGE_ACCOUNT_SAS_READ_TOKEN
),
};
},
@daniiltkach-ms Thanks for flagging. At this time, I'm unable to work on this. I'm open to a PR if this is something you want to take on
I think this is a big security risk. We are using SAS Token approach to get plugin authenticated. And we are seeing same token appended in url of the uploaded file which has risk of being exposed. Luckily I catched this on my end early as this lead to SQL error as the url including SAS token exceeds the default url field max size of 255 chars.