I'm wondering if we need to add a token to the file/%file/download callback. Otherwise an anonymous user could easily write a script to run through each possible integer, and attempt to download every single file from the website. This has me thinking that a token would be good to add. If we do this, we also need to add a file and image field formatter for a download link since we'd need an easy way for users to link to download without having to worry about calculating the token themselves.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Dave Reid’s picture

Issue tags: +Security improvements
Dave Reid’s picture

Status: Active » Needs review
FileSize
1.25 KB

Initial patch, likely to fail tests.

Dave Reid’s picture

With added field formatters now.

Status: Needs review » Needs work

The last submitted patch, 1995154-download-token.patch, failed testing.

Dave Reid’s picture

Status: Needs work » Needs review
FileSize
5.53 KB

Fixing tests to account for the token string. Needed to add a workaround for core bug #1555862: DrupalWebTestCase::drupalGetToken() does not add hash salt as well in our test helper class.

Dave Reid’s picture

Added a [file:download-url] token and a helper function to retrieve the URI for download/token.

gmclelland’s picture

Related issue that could influence this one - #2003216: Support file/%/download/%disposition-type

Dave Reid’s picture

Status: Needs review » Fixed

Committed #6 to 7.x-2.x with an additional file_entity_allow_insecure_download variable that can be enabled, but the download protection is enabled by default.

http://drupalcode.org/project/file_entity.git/commit/e73f063f190a3a11214...

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

alunyov’s picture

Component: User interface » Code
Status: Closed (fixed) » Needs work

Hi,
I'm using 7.x-2.0-unstable7 (but was trying 7.x-2.x-dev from 2013-Jul-18 as well) and I have a really annoying issue related with using token. It happens only for anonymous user when goes to download link (like: http://example.com/file/13301/download?token=-Jyb62es4dDrmNGcgfDXWRDmSDi...) and it gives "Access Denied" page. Reason of that is dynamic session id for anonymous user. It fails in file_entity.pages.inc on line #40.

    if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], "file/$file->fid/download")) {
      return MENU_ACCESS_DENIED;
    }

So drupal_valid_token($_GET['token'], "file/$file->fid/download") for anonymous user always give FALSE because session ids on previous page (where was generated token for download link) and current page (where is checking of token) are different. I hope it makes sense.

Did I miss anything? Any suggestion?

Dave Reid’s picture

@alunyov: Can you please file a new follow-up issue to figure out how we should handle it with anonymous users?

Dave Reid’s picture

Automatically closed -- issue fixed for 2 weeks with no activity.

mindgame’s picture

This line in class views_handler_field_file_link_download is problematic:

$this->options['alter'] += $uri['options']

In my view I get the same token for each download link because the concatenation operator does not overwrite the previous options['alter']['query']['token'] value.
Will open a new issue.

sheldonkreger’s picture

Issue summary: View changes

The patch that was committed is problematic. For example:

1. User inserts a link to a public file download with a token into a node body.
2. Another user with correct permissions visits that node, and follows the link with the token.
3. User gets accessed denied when they follow the link to download, even though they should have permission to download the file, because the token is invalid *for them*.

Anybody who uses CKeditor Link File, with the current method will run into this problem.

This restrains file downloads using /file/fid/download?token=xxx method to ONLY be allowed for the user who originally uploaded the file. This seems extreme. In fact, it essentially overrides all of the config that is in place for file download permissions, and also any field level permissions on attachment fields.

In addition, access to the file without the token (file/fid/download) also results in access denied after this patch - regardless of the private/public status of the file and the permissions of the users.

This patch needs to be reworked unless we want to completely work against Drupal's permission architecture.

sheldonkreger’s picture

Priority: Normal » Major
Status: Closed (fixed) » Needs work
Dave Reid’s picture

Priority: Major » Normal
Status: Needs work » Closed (fixed)

Please file a new issue about the download link being incompatible with text formats.

sheldonkreger’s picture

Status: Closed (fixed) » Needs work

Hi Dave,

This is not an issue with text formats. It does not matter which text format configuration is used when the node body is saved.

The reason the tokenized download links don't work is because the tokens are generated based on user-specific information. Therefore, other users who try and follow a download link another user has posted will always get access denied, regardless of whether or not they have permissions to download the file.

In the current stable release, the token is generated with drupal_get_token():

https://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_...

"The generated token is based on the session ID of the current user. Normally, anonymous users do not have a session, so the generated token will be different on every page request. "

Later, there was an attempt to fix this problem for anon users, but it did not address the root cause I explain above. The token is still generated using the session ID. This means only the user who generates the download token will ever be able to use it.

https://drupal.org/files/2062663-fix-the-token-on-callback-for-anonymous...

Would you like me to file a separate issue, or keep it here?

Dave Reid’s picture

Status: Needs work » Closed (fixed)

I understand the problem, but I will kindly ask for the last time: there is no need to re-open a closed issue, especially for something like this. You would get the exact same behavior with *any* link that uses drupal_get_token() pasted in to a body field. The problem is the text format caches the URL using the token of the person who created the content, which will not work for other users, or anonymous users. Again, this problem is not unique to the file download URL, it's a problem of pasting URLs that use drupal_get_token() in text formats.

Dave Reid’s picture