I have set up a REST web service in using Services 3.4 module to upload a file with an apikey. I have tried the following methods to check valid apikey to permit upload request.

1)check the apikey in the POST data during create process and upload happens.

2)tried the Services API Key Authentication Module which implements the hook_services_authentication_info() which checks for the apikey.

3)implemented hook_services_request_preprocess_alter($controller, &$args, $options) to check for apikey both in POST headers as well as in the POST payload and it works.

However, in all the above method the file is uploaded to the server (/tmp) regardless of right or wrong apikey. The request is denied once the apikey check happens in all three methods above. This is concerning as it opens the server for easy ddos . Is there a way to intercept the and check apikey before the file is uploaded to the server and deny the request?

All my communication is over https so I would not like to go via session authentication mechanism.

Could this be because of apache server settings? If so, how to restrict uploads to authenticated users?

Please advise.

Comments

toamit’s picture

Issue summary: View changes
toamit’s picture

Title: Files upload to /tmp on wrong credentials » Files upload to server whether right or wrong credentials

I am suspecting that this is a bug in Services? Could someone provide any hints or atlernative to avoid this.

toamit’s picture

Comments please anyone?

kylebrowning’s picture

Project: Services » Services Key Authentication
Version: 7.x-3.4 »
toamit’s picture

kylebrowning this is a major issue in Services, not sure why this has been moved to this sand box project. Could you please comment!

kylebrowning’s picture

Because you're using an authentication module that hooks into services and goes around Services authentication.

toamit’s picture

As described in option 1 and 3 above, the checks are being done purely using the methods offered by services not other module.

Option 2 used the module for completeness sake and demonstrate that indeed this is a limitation.

I suggest, this issue be moved back to services as it needs attention from folks who are contributing patches. Moving this away from discussion to a nearly dead sandbox is not a good solution.

kylebrowning’s picture

Services doesn't use API Keys in core. Option #1, #2, and #3 discussed api keys...

Maybe you can provide a little more information, or dig deeper to prove its services?

When I try to upload a file as anonymous I get access denied.

toamit’s picture

>Services doesn't use API Keys in core.
I know, but I am implementing the apikey based on available functionality exposed by services.

>Maybe you can provide a little more information, or dig deeper to prove its services?
>When I try to upload a file as anonymous I get access denied.
The problem is not that the anonymous access gets denied (this is correct), but you will find that the file was uploaded then deleted on your server before being kicked out.
Take another fresh read at the issue an then try to upload a large file and look at your /tmp or other upload location of your web server. You will notice that the file first get uploaded then gets tossed out, this is a waste of resources and weak point for DDOS attacks

This indicates that the server will consume both CPU and storage resources regardless of access privileges. Perhaps this may be a a design problem the way services are implemented.

kylebrowning’s picture

Does the user have perms to

case 'create':
case 'create_raw':
return user_access('save file information');

kylebrowning’s picture

So, I just tested this again, Standard drupal 7, services 3.10.

No file is created in my tmp directory which is set to /tmp, no file is uploaded to my sites/default/files.
I attempted to upload a 500 meg file, and it didn't exist in either of these directories
And the response from the server...

(
    [request] => GET /api/file HTTP/1.0
User-Agent: Drupal (+http://drupal.org/)
Host: local.drupal7.acquia.com


    [data] => ["Access denied for user anonymous"]
    [protocol] => HTTP/1.0
    [status_message] => : Access denied for user anonymous
    [headers] => Array
        (
            [date] => Thu, 02 Oct 2014 18:38:32 GMT
            [server] => Apache
            [x-powered-by] => PHP/5.3.28
            [expires] => Sun, 19 Nov 1978 05:00:00 GMT
            [last-modified] => Thu, 02 Oct 2014 18:38:32 +0000
            [cache-control] => no-cache, must-revalidate, post-check=0, pre-check=0
            [etag] => "1412275112"
            [vary] => Accept
            [content-length] => 36
            [connection] => close
            [content-type] => application/json
        )

    [code] => 403

Heres the php code i used.

function stest() {

  $image_path = '/tmp/tmp.iso';
  $file = array(
    'filesize' => filesize($image_path),
    'filename' => basename($image_path),
    'file' => base64_encode(file_get_contents($image_path)),
    'uid'  => 1  // This should change it by the user who use the service.
  );

  $data = http_build_query($file, '', '&');
  $response = drupal_http_request('http://local.drupal7.acquia.com/api' . "/file", array('Accept' => 'application/json'), "POST", $data);

  if ($response->code == 200) {
    return json_decode($response->data)->fid;
  }


  $error =  $response->status_message;
  print_r($error);
  return false;
}

Can you disable your APIkey setup and try again?

toamit’s picture

I will try that out and chime back.
Any chance you could check your test for anonymous user, as that is my case?
Thanks