A few days ago, I added a download link in a page that calls a file download procedure within an URL. It quickly came to my mind that there was a security issue with this method. Indeed, nothing prevented me from downloading a file even if I wasn't logged into my APEX application.
I thought that the solution would be to add security in the procedure itself so it would check an application item value (userid) with the v() function. Unfortunately, this function cannot read apex items when it's being executed in a procedure called from an URL.
With some quick research, I found a solution on Denes Kubicek demo website. The solution is to call, with an URL, an on-demand application process which runs the file download procedure. This way, you absolutely have to be logged into the application to use the procedure since you need a valid session id in this URL.
You can find a document on Denes Kubicek demo website named "application_process - download.pdf". It explains step by step how to apply the secure method :
Reminder: Don't forget to revoke the execute privilege on the download procedure to apex_public_user if you granted it previously.