In a CakePHP3 application that requires Authentication/Authorization, I have the possibility of images being uploaded. Now I would like to avoid Users being able to see other users images by e.g. guessing image names or such. Also I would like to use the ids of the entities as filenames which would make it also easy to guess.
So how would you implement authorization for assets?
I would prevent the "guessing" of filenames just by generating a random long enough unguessable string of chars as the new filename, like Facebook does with uploading photos:
Because we shouldn't bother at all with the original name of files, we could rename the file that a user uploads. For example User 24976 uploads a file that is called tomato12.png. The upload script will then rename the file to (for example) the following name:
1481540475_24976_iDewM51NYrBYgnIh.png
It consists out of four parts:
[timestamp]_[userId]_[randomString].[suffix]
And then, save the filename into the database. If you would look into the uploads directory, you could be able to see which user has uploaded which file, but an outsider that has no rights to see the directory index would never be able to guess the name of a file. No authentication needed.
Related
I’m looking to hopefully write a function that protects WordPress media files (or more specifically pdf files).
I would like this function to run when a user attempts to access a specific file.
What I would like to happen is:
User attempts to access url of specified file/files
Function/Action runs the following checks
Check to see if user is logged in
Checks to see if user is either subscribed to a specific WooCommerce product, or has purchased a specific product.
If user meets the requirements, access is granted to files
If user does not meet the requirements they are directed to 404.
I realise WooCommerce already has a system for connecting files to products however having a function like this would be easier, as I plan to tie it in to ACF. I have a variation of this code working on the front-end however this does not protect the media files. Any help would be greatly appreciated.
<?php if (is_user_logged_in()) {
if (wc_memberships_is_user_active_member($user_id, 'gold-membership') || ( wc_customer_bought_product( '', get_current_user_id(), 999 ) ) ) {
} } ?>
Better upload pdf to outside uploads folder of the Wordpress.
In the wp-content/uploads the files will stay public access.
Only read and offer files via script, this mode you can control the access of files.
My application uses the google realtime API to define a custom document type, and includes a feature that allows you to create a copy of a document, using the API's document.saveAs. One purpose of this is to allow users to make and edit personal copies of document templates that have been shared with them as read-only files. I create a new document then use saveAs to copy the realtime document into it, something like this:
gapi.client.drive.files.create({
resource: {
mimeType: 'application/vnd.google-apps.drive-sdk',
name: NEWNAME
}).then((response) => {
MYDOCUMENT.saveAs(response.result.id);
});
This works perfectly with read-write files, but if the original file is read only it does not appear to save the realtime document into the new file. No error is reported but the resulting new file is empty.
Is this is a bug or known limitation, or am I doing something wrong?
You may want to check Collaborators and sharing wherein it was stated that the Realtime API uses Google Drive to manage permissions and sharing.
Reading further,
Access to files & folders is determined by an access control list (ACL). An ACL is a list of permissions that determine whether or not users can perform actions on a file such as read or write. See the permissions guide for additional details about permissions and roles.
The role gives these users the ability to do something to the file, like read it. As far as I've read, here are the permitted operations for read-only:
Read the metadata (e.g. name, description) of the file or folder
Read the content of the file
Read the list of items in the folder
With DotNetNuke, I discovered the option to use secure folders. How can we keep the full URL of a file within a given security folder normal? (i.e. without the token process attached to the URL and displaying the full path to the folder).
There are a number of reasons why I would need the path/name of a file readable to it's original location. Yes I want the folder to be only accessible to members privileged to that location, but not at the expense of changing the path / file name with a token.
So regardless if you are logged in or not, you should notice the existance of
http://dnnsite.com/my-secure-folder/my-file.pdf
If you are logged out, then an action occurs saying you are not permitted to view this file.
If you are logged in, then you have full view access to this URL
Thanks
It would not be secure then. To access a file in the way your url is formed, you have to use a "normal" folder, but you cannot achieve your goal to restrict access.
To explain: Files that are uploaded to a secure folder get an extra extension (".resources") to their original file name. Files with this extension will not be delivered by IIS (at least not in the default settings), and DNN provides a file handler ("LinkClick.aspx") that delivers the file with this extension, and also ensures that the user who tries to access the file hat the required permissions in the secure folder.
What you can do on your site is something like a link in an HTML module that is available to everyone, but uses the file handler to access the file, and the folder is restriced to a specific role (http://dnnsite.com/my-secure-folder/my-file.pdf). This leads to the login screen when a user is not logged in.
I have Yii2 application where users can upload and share files of different types. Once a file is uploaded, it could be downloaded only by certain other users and there are a whole bunch of checks that go behind this process.
My problem is that the files are stored on the server and if someone has the link directly to the file then they can easily be downloaded without going through any kind of authorization or security checks. How can I prevent this?
P.S. It could be any kind of solution, not one related to Yii2.
The following approach comes to my mind.
Store the files at a location in file system that is not made publicly accessible by a web server.
Make them available by reading them from file system and sending them to browser when the user retrieves the URL that also does the security checks. A redirect to another URL that does not do security checks has to be avoided.
If you give more details about a more specific problem or question people can give you more specific information.
I am allowing users to upload a profile picture of themselves. It involves these steps:
User chooses an image file to upload
Server receives the file through AJAX and stores with a name of temp_userid.jpg
Server returns the image location to the page so the user can see it and make adjustments
The user clicks Save Changes which posts back to the server as final confirmation of the image update
Server loads the temp_userid.jpg, makes the adjustments e.g scale and crop, overwrites any existing profile image, and then finally deletes the temp_userid.jpg image
This works fine as long as the user saves his changes. If the user decides to leave the page, then the temp_userid.jpg file is still on the server and is never deleted. Some of the images can be over 5MB in size which I don't want on the server.
How could I go about cleansing the folders of temp files in a safe manner? I was thinking I could:
Attempt to delete the temp image file whenever the user logs in to his account. The only slight issue here is that the user may never log-in again. But that could be dealt with using some kind of account expiration check.
Attempt to delete all images with a prefix of 'temp_' from the server periodically. The risk here is that it deletes it while a user is still making adjustments to his image which would be terrible!
Are there any better ways of doing this? I'm tagging this as ColdFusion because thats the application server I'm using.