I hope i get help soon :)
The Problem simply is this:
I built a custom component(php software) which will soon be listed on Joomla Extension directory for users to download. In this component, images and videos are linked to via urls (hotlinked).
Now on my website, users are made to pay for subscription.
Want i want to achieve is simply to allow the component i built to be granted access to images and videos to users who have an active subscription on my website, and restrict the component access to images and videos to users whose subscription has expired.
I just need an idea of how to go about this.
Your responses are Highly anticipated, thank you.
So I understand you would allow the component to be downloaded freely, but it won't display the hotlinked media to expired suscribers or not registered users.
I guess you would have to keep your registered user host in a table, and instead of hotlinking to the image directly serve it through a php script that would check subscription status (based on the request host url) before displaying the image or a "unsuscribed" fallback image.
The other way would be to restring the content in your webserver, either in .htaccess or in the vhost definition of nginx. But this would mean to manually add or remove suscribers constantly.
Very loose example: your suscriber request the image as
<img src="http://yoursite.com/image.php?img=akdbnrieodoidnsd"/>
from his site http://suscribersite.com
Your image script is the following
$imghash=$_GET['img'];
//strip non alphanumeric characters, to avoid malicious requests
$cleanhash =preg_replace('/[^a-z_\-0-9]/i','', $imghash);
header('content-type: image/png');
if(valid_suscriber($_SERVER['HTTP_REFERER'])) {
$img = file_get_contents("/non-public-directory/$cleanhash.png");
} else {
$img = file_get_contents("/non-public-directory/unauthorized.png");
}
echo $img;
You'll have to implement the valid_suscriber function to check the http_referer suscribersite.com against your suscriber table. Be warned, though, the http_referer can be easily spoofed.
The real solution to your case would be to perform an oauth handshake prior to any request, and append the oauth token to each subsequent request. This is much more cumbersome but less prone to tampering.
Related
I'm working on an application where I have a web interface for a screen on my wall, and the goal is to allow my friends to upload images to it.
Right now I have a basic web interface with a login, which authenticates a session and has a page which allows uploading an image and changing some of the parameters of the screen. The parameters are stored in a MySQL database, as well as the login details. This part I've heavily based off the approach detailed in this link:
https://phppot.com/php/secure-remember-me-for-login-using-php-session-and-cookies/
Ideally I can allow my friends to upload images to this screen in a secure way that is as simple as possible. What I am imagining is a unique URL link that can be sent to them, which takes them to a page where they can upload an image but do not have access to change any of the screen parameters and so on. This URL would allow anyone who has it to upload pictures, but I want the owner of the screen to also be able to deactivate the URL if it is no longer secure. The owner could ideally generate a number of URLs that they could share with different people, which would all upload to the same screen.
My question is firstly, is this a good approach and is there a way to do this securely (without opening access to the screen parameters and so on)? I would prefer to avoid giving these "guest" users login details, as that is one more account to remember and reduces the simplicity of uploading to the screen.
My next question would be how to do it? My current idea is to have a new database with columns for the screen ID (to allow it to work when I have multiple screens) and link URL. The screen owner would generate some kind of random string as the URL and save it to the database. The "guest" upload page would only allow uploads if the redirected URL is found in the database. Right now I'm looking at affiliate link examples to get ideas on how to implement this, but if anyone has better suggestions of what to search for or other examples it would help a lot.
I'm very new to web development so I'm not sure if I'm describing my approach clear enough or if my goal even makes sense. I'm also very uncertain of any possible security issues I may be introducing with this approach, so anyone has suggestions or possible pitfalls please let me know. I don't know how much I don't know.
You can use Tokens :
generating tokens with php
You generate an URL with the token inside then send it to your friends:
www.myULR/token
After, you create a table token with all tokens with a jointure with user's id,
and you should easily verify with PHP, if tokens exist and user is not an impostor, allow him to upload files.
I have to build an application where users can download videos from a site but cannot share them. My first solution is to save these files in a hidden location on the users computer since one of the requirements is that the user should be able to watch the downloaded videos offline.
Please how do I go about saving a file in a location the user cannot see using php.
Thanks.
One solution is to generate token for each request for a video. That token would have its lifetime. Php script should be serving the content instead of giving direct access to resource to user. The script should check if the token is still active before serving the content.
It is up to you how to pass the token. The simplest way is to make it contained in uri.
No matter where you put your videos in your directory structure, you always send the data as a partial request. Once data is acquired by the user, it could be saved an reproduced.
There are techniques, however, to protect your video from direct download through curl, wget or other ways of download. And this is using a secure token and an expiration, passed as parameters. This way your video download window will be limited and generating the token manually would be pretty hard.
Chidiebere Onwunyirigbo, its a Great Question. One solution for your requirement is Steganography. It is the process of concealing your data (videos) behind other files (multimedia files like image, audio, video), in your case preferable would be Image Steganography. It is quite a old technology but new to many, you can get several ready tools/code for it on the internet which you can customize as per your need. From your side you have to provide the file that is already embedded inside the image for download. Only the tool coded for retrieval and rendering the hidden video can render your video. So, for this part all the users of your site have to first download this desktop application from your site for viewing the video. This will keep your videos safe on the users computer offline, because every user who takes the video will require the reverse steganography tool to be downloaded from your site. You can even embed secret info like users IP inside the Stego image along with the video and for each tool download, associate user computer's IP with the tool. If IP embedded inside Stego image matches with that of tool only then you allow to play else redirect application to get it registered. But the limitation would be that, the users will have to download your application and will be able to view videos only on your desktop application which will render the Steganographed video.
You cannot hide information on the user computer. Even if your process are running on a windows comp as SYSTEM user, a power user can take ownership of the files.
The only solution you have, are developing or using a known DRM system, for allowing only playing the video on a determined computer or another specifications (for example, if the program have the authentication token of some user).
At any case, you need to do two things for this:
- You need a custom application to play the video, if you want to check DRM.
- You need to recode / modify something on the video before download, for adding on them a code for allow only play on the destination computer or data used for authenticating DRM.
When I go to the url of my bucket file it downloads straight away. However I only want users that are logged into my application to have access to these files.
I have been searching for hours but cannot find out how to do this in php from my app. I am using laravel to do this so the code may not look familiar. But essentially it just generates the url to my bucket file and then redirect to that link which downloads it
$url = Storage::url('Shoots/2016/06/first video shoot/videos/high.mp4');
return redirect($url);
How can i make this file only accessible for users logged into my application?
We ran into a similar issue for an application I'm working on. The solution we ended up working with is generating S3 signed URLS, that have short expiration times on them. This allows us to generate a new signed link with every request to the web server, pass that link to our known auth'd user, who then has access for a very limited amount of time, (a few seconds). In the case of images we wanted to display in the DOM, we had our API respond with an HTTP 303 (See Other) header and the signed URL, that expired with-in a couple of second. This allowed the browser time to download the image and display it before the link expired.
A couple of risks around this solution: We know a user could possibly request a signed URL and share it with another service before the expiration happens programmatically, or an un-auth'd user who was intercepting network traffic could potentially intercept the request and make it themselves, we felt these were edge case enough that we were comfortable with our solution.
I'm playing around with an CakePHP site based around the following principles:
An admin can upload images and tag models in them.
The admin can choose to make certain photos public, for a publicly visible portfolio.
The admin can invite people to join the site by using a key to register which will associate the user with a certain model. The user will then be able to see all photos of him/her on a private part of the site requiring login, kind of like a private portfolio for each individual model.
All images are placed in a folder with deny from all .htaccess file blocking off access.
A media controller takes care of serving the images, and when a request for a file is made, a database table lookup is done and access is given if: the user is logged in and an admin; the user is logged in and is tagged in the photo; or of the photo is marked as public. If not a status code of 403 is returned.
To make the whole experience more snappy and avoid unnecessary downloads, caching is used, where the edit timestamp of the file is checked and a corresponding status code of 304 is sent (through setting $this->response->modified to the file timestamp and checking $this->response->checkNotModified($this->request) on requests).
The image is sent via the $this->response->file in the controller MediaController.
All in all this works as expected, but there's one problem: If for some reason a photo which isn't supposed to be public is exposed by an error, the caching poses a problem.
Say someone who do have access to the file logs in and they are able to view/download the photo as expected. This user then logs off, and someone else takes over the PC. They go to the public portfolio page where the same private photo is exposed by some error (basically a bug or human admin error), but since the last user who logged in did have access to it, it's in the cache, and even though the server returns a status code of 403, the browser will ignore that and serve the image from cache.
If I haven't lost you, my question is this: Is there any way around this problem? Can I force the browser to take into account the 403 status code? Or is there some other flaw in my media controller setup/design which makes it unusable?
Or is this problem too unlikely to ever pose a problem for a small, amateur photographer? Would it be considered a (severe) security flaw for a professional well known photographer?
Any insight is greatly appreciated! :)
On a actual project (dating site) i have the following scenario:
Member can upload photos (main profile) and create albums and assign photos to it. Now the member can choose only to allow registered members, premium members or members in his favorites to access the album.
The easiest solution is to hide the album, but if someone who has access post the src url to the photo it would be accessible to everyone who has the url.
I see flickr and facebook secure them in a good way, but how i can implement that without to need to query many times the DB and replicate the user auth/session. The photos will be stored on a own server (varnish/nginx).
Has anyone a idea how this can be done in mind of high traffic and to use less resources as possible?
The solutions needs to can handle the actual 20m members and around 30m photos.
Well, one possibility would be to run something like Lighttpd's mod_secdownload.
Basically you set a "secret" string in the configuration section. Then when you generate the links, instead of making a link to the resource, it's a temporal link (so it's only valid for $x number of seconds). That way the user needs to visit the page again (and hence pass access control again) before being allowed to view that image...
Apache has a similar module: mod_auth_token...
The best solution is to store the image outside the web accessible part of your server. Then, instead of referencing the photo directly, you would reference a php page pointing to the image as so:
http://www.example.com/image.php?imageid=1234567
Then in your php script, you can check if the logged in user has access to the photo, and if so, you stream the image out to the user in the response.
As an idea...
You could create a mapping table where you "prepare" the access permissions for pairs user->photo based on favorites, friends etc.
Then you return the images based on these permissions but cached per user. This will lower the stress on your servers but there will be some delay in applying restrictions due to cache timeouts.