1

I made a project with php and symfony. My problem is the following:

in my application I can upload an object (with a file associated) and I can download it.

The download can be done from the following routing:

symfony/app_dev.php/download/product/{id}

where {id} is of course the id of the product.

How can I obtain the same result without showing the {id} in the routing?

This is very important, because each user can download only some determinate products, but if the id is shown in the routing, every user can download every products without being authorized.

Actually the problem consists into "passing the {id} information within two action without show it in the routing".

Thank you for your help

random_user_name
  • 25,694
  • 7
  • 76
  • 115
Gianni Alessandro
  • 860
  • 6
  • 11
  • 28
  • 3
    What you are actually asking is how to protect downloadable digital goods. The ID in the URL should not relied on to protect the product - you also need to make some database checks to see if the user is authorized to view that product. If in fact it is a downloadable product (like a PDF, etc), then check this answer: http://stackoverflow.com/questions/5412328/php-protecting-digital-downloads – random_user_name Feb 24 '14 at 15:33
  • I don't rely only on this, but at least I shouldn't show the id into the routing, and I don't know how to do. Thank you for your help, I will add also this functionality, but before I have to set my routing system! – Gianni Alessandro Feb 24 '14 at 15:40
  • If situation requires you can always employ `ACL` (http://symfony.com/doc/current/cookbook/security/acl.html) although it could be too much. Basically, as @cale_b suggested, you need to check with database if user is allowed to download the file and if he's not return the appropriate "Not authorized" message :) – Jovan Perovic Feb 24 '14 at 15:44
  • If the ID being hidden from your route is important, then you will have to do it either by passing as a $_POST variable (same potential injection concerns), or a $_SESSION variable. You cannot pass an ID in a URL but have it "hidden" – random_user_name Feb 24 '14 at 16:36
  • 1
    Since you already check that *user can download only some determinate products*, do it in the controller before sending the file. – A.L Feb 24 '14 at 17:01
  • Yes, actually I changed my controller. Now the route is visible, but the controller limit the access to the resource. – Gianni Alessandro Feb 24 '14 at 17:19

1 Answers1

0

Don't know if it's really recommanded for security in your case but this is what i usually do to use POST instead of GET

twig :

<script>
$.post( "{{ path('download_product')}}", {
                id: 1,
            })
</script>

OR

    <form action="{{ path('download_product')}}" methode="POST">
    <input type="hidden" id="id" name="id" value="00000001"/>
    <button role="submit">
    </form>

routing :

<route id="download_product" pattern="/download/product">
        <default key="_controller">Vendor:Bundle:downloadProduct</default>
    </route>

controller :

public function downloadProductAction()
    {        
        $request = $this->get('request');
        $id = $request->query->get('id');

        return new Response($id);
    }
Chopchop
  • 2,899
  • 18
  • 36