Amazon cloudfront how to set signed url outdated if used one time - security

I need to protect my videos to be downlouded using "Internet Download Manager - IDM/IDMan"
i used
1. rtmp stream
2. signed URL
3. expiration date of signed URL (60seconds)
4. i set player(jwplayer)to *autostar*
AND i need to set signed url outdated if it used one time
using this solution IDM will get an url that is already used then blocked
Is there any way to configure cloudfront to use signed url just one time;
Or any solution that can protect videos to be uploaded and used in other web sites.
Please can you help?
Thanks in advance

Cloudfront does not support the ability to only play a url once and they never will. The reason is that the only way to do this will be for all their edge servers to share the information - they currently do not share state which means scaling is much easier and performance is much better.
Unfortunately, if you're looking for fine grained control over how your videos are played, you're going to need more fine grained code, which you can't do in cloudfront - you'll need to host content directly on your server.
Idea 1: Limit by count
You can implement the idea that you have - once the url has been used once, you no longer serve up that file.
Idea 2: Limit by referrer
You can look at the referrer header and if it's from your website, then allow the content to be downloaded. Otherwise, reject it. Note: this can be spoofed and a user can set the referrer header manually.
Preventing a video from being downloaded and later uploaded is technically impossible. By letting them display the video, there really isn't any way to do that without them being able to record those bits and replay them later. There are probably things, like preventing right clicks or using an odd proprietary format or something else but I'm not familiar with DRM techniques.

Related

Block the access of Aws cloudfront url from chrome, safari and all browsers

Had Done:
I had done uploading Kyc documents and attachments in s3 bucket
Integrated S3 with CloudFront
Blocked all public access in S3 bucket.
Only way of accessing content is 'CloudFront url'
My requirement is:
Any one can access the documents if 'CloudFront Url' known
So i want to restrict the access of URL except my application
Mainly block the access of that url in chrome, safari and all browsers
Is it possible to restrict the URL ? How ?
Lambda#Edge will let you do almost anything you want with a request as it's processed by CloudFront.
You could look at the user agent, then return a 403 if it doesn't match what you expect. Beware, however, that it's not difficult to change the user-agent string. Better is to use an authentication token.
To be honest, I don't understand your question well and you should make an attempt to describe the issue again. From a bird's eye view, I feel you are describing an IDOR vulnerability. But I will address multiple parts in my response.
AWS WAF will allow you to perform quite a bit of blocking on a wide variety of request content.
Specifically for this problem, if you choose to use AWS WAF, you can do the following to address this issue:
Create a WAF ACL, it should not be regional and should be global, set the default action of the WAF ACL to auto allow
Build regex pattern sets of what you would like to block or you can hard code specific examples
Create a rule that will block requests which have a User-Agent header that matches your regex pattern set
But at the end of the day, you might just be fighting a battle which should not necessarily be fought in the first place. Think about it like this, if you want to block all User-Agent headers which symbolize a browser, that is fine. But the problem is, the User-Agent header can easily be overwritten and spoofed such you won't see the typical browser User-Agent header. I don't suggest you to block requests based on this criteria because at the end of the day, I can just use a proxy and have it replace that request content before forwarding the traffic to the server and bypass the WAF or even Lambda#Edge.
What I would suggest is to develop some sort of authorization/authentication requirement to access these specific files. Since KYC can be sensitive, this would be a good control to put in place to be sure the files are not accessed by those who should not access them.
It seems to me like you are running into a case where an attacker can exploit an IDOR vulnerability. If that is the case, you need to program this logic in the application layer. There will be no way to prevent this at the AWS WAF layer.
If you truly wanted to fix the issue and you were dealing with an IDOR, I would use Lambda#Edge to validate that the Cookie included in the request should be able to access the KYC document. You should store in a database what KYC documents can be accessed by which specific user and you should check that the Cookies header includes the Cookies of the user who uploaded the KYC document. This would be effectively implementing authorization/authentication, but instead at just at the application layer, it would be also at the Lambda#Edge (or CDN) layer.

How to block rawgit.com to access my website server

I think my website is injected with some script that is using rawgit.com. Recently my website runs very slow with browser lower bar notification "Transferring data from rawgit.com.." or "Read rawgit.com"..." . I have never used RawGit to serve raw files directly from GitHub. I can see they are using https://cdn.rawgit.com/ domain to serve files.
I would like my website to block everything related to this domains, how can I achieve that ?
As I said in the comments, you are going about this problem in the wrong way. If your site already includes sources you do not recognise or allow, you are already compromised and your main focus should be on figuring out how you got compromised, and how much access an attacker may have gotten. Based on how much access they have gotten, you may need to scrap everything and restore a backup.
The safest thing to do is to bring the server offline while you investigate. Make sure that you still have access to the systems you need to access (e.g. ssh), but block any other remote ip. Just "blocking rawgit.com" blocks one of the symptoms you can see and allows an attacker to change their attack while you are fumbling with that.
I do not recommend to only block rawgit.com, not even when it's your first move to counter this problem, but if you want you can use the Content-Security-Policy header. You can whitelist the urls you do expect and thus block the urls you do not. See mdn for more information.

S3 bucket policy via a particular application

I am trying to utilize S3 to let my clients download my software package. What I envision is creating a simple web app with authorization For example (download.mysoftware.com) Once the user is authenticated, they will be presented with a S3 url used to download the software. I will create user accounts based on my customers.
My concern is, what happens if the user copies the S3 URL link and then gives it to someone who isn't authenticated to download the software?
Is it possible to create an S3 policy that would prevent this and work for my usecase? I looked at allowing only specific IPs, however, I won't have a way to find out IP of my customers and wouldn't want to ask them first and then add it to the policy each time.
One way allowing specific IPs would work is if I allow downloads only from the IP that is linked to (download.mysoftware.com) but then the downloads will really be happened from my web application as opposed to from S3. Which seems like double effort.
When a user makes a request to download your application, generate a pre-signed URL for them with a short expiration. It only needs to be valid for as long as it takes them to start downloading your file, so even a few minutes of validity is likely to be plenty.
While it's technically possible for a user to share one of these URLs, they would have to convey the URL to someone else and get them to download it very quickly, which is probably sufficient to deter them from trying to share the URL. (A perfect defense is more difficult, and is probably unnecessary anyways; there's no way to prevent a user from personally transferring a file they downloaded to someone else.)

What's a good approach to securing MP3 files for a private podcast with Amazon S3?

I'm trying to create a private podcast feeds. Each user of my service gets an account and depending on what they pay, they will receive different content. Some content is sensitive so security is reasonably important; if any of the enclosed audio files made the rounds around the internet, it could be catastrophic for our business.
I am currently prototyping the service and MP3s are stored on S3 and they are not secured. It's time to secure them. From my research, I understand that I can, in fact, secure files on S3 with an access expiry period. But, because I have many users, signing the request with my "global" key and have an expiry probably isn't a good idea because
If I need to revoke access, I'll need to do it for everyone
Since I don't know when, exactly, their podcatcher will request the file, I don't know when to set the expiry. Sometimes, the podcatcher downloads the feed XML, but only later fetches the MP3 file so the URLs could expire before the client has a chance to fetch them (I'm thinking about iTunes, but there could be others).
The way I see it, I have two options and I'm not sure if either are workable:
Edit Another potential way, I suppose, would be to role my own security, and simply redirect to an MP3 on S3 with a short expiry if the user is good to go. This seems most sensible.
I can create user accounts on Amazon for ALL of my users and link them to an Amazon token in my database. Everyone's MP3 urls are signed with their secret token and expiry a long time from now. I don't like the idea of storing their tokens on my database, and I'm not sure if the Amazon ACL was designed for this scenario. It also means the files can still be shared if you know the URL.
I can proxy every request through my server. This means I only have one Amazon account, and I can role my own security system. But proxying every MP3 download through my server sounds slow, wasteful and expensive.
Any ideas on the best way to do this.
P.S. I'm not married to S3. Other solutions could be considered. And I'm on Heroku using Ruby, in case you care.
I am going with the redirect solution suggested elsewhere. This seems to give me the most flexibility and very low overhead. What you definitely should not do is is using links directly to S3 in your feed, because they likely expire before they are downloaded by the client.

How to serve videos in a website somewhat securely

I am asking a question that's somewhat related to these:
Secure way of serving videos
secure streaming of videos
However, no one provided an answer that seems relevant to my situation.
My situation is as follows:
I'm building a very simple Learning Management System. Students have access to Video lessons if they have paid for it. I would like to prevent:
bots/spiders from finding these videos and downloading it
for people to simply view source, copy the url of the video, and share it with other people
I doubt very much people will try to hack the site to steal the videos.
What is the best way to secure these videos from being shared? Do i have to store the videos on my webserver? Can i leverage video platforms like youtube or vimeo?
Long story short, there is no simple solution.
I will say straight up that if there was a way to stop people from downloading videos, every video website would be doing it.
I have thought of a few ways, listed out below, of what you could do to make it not worthwhile for the student/viewer to download the videos.
obscure the URL
change the URL frequently
restrict the number of downloads per IP address/subnet
make them view it in a custom-built "custom-served" video player
use a video streaming service already available
Each are discussed in greater detail below.
Obscuring the URL
You could obscure the URLs like so:
http://mylearningmanagementsystem.com.au/e12d8cd38f00f204e9801998ecc8427e/video.flv
You could calculate a hash of the name of the file itself (or salt and hash, the above is just an example) and use that in a URL.
This could be achieved in such a way that they would be obscure enough, but still bookmarkable and user-friendly for the viewers.
If you wanted to go one step further, you could have video broken up into parts - this is discussed in the custom built section.
Change the URL frequently
With some code, you could set the videos to change URLs every Sunday night at 11.59pm for your timezone. However, any page that you link to would have to be either automatically or manually updated, and that is a hassle in itself (how do you test the code/what if it falls over and you don't realise/things like that).
Even if you get all of that working, any user that bookmarked the page would suffer from link rot.
Restricting the number of downloads per IP address/subnet
With some funky server-side code, you could limit the number of times a video can be downloaded to an IP address (or depending on the user case, a subnet of the IP).
This is not my strong point, but you could look at articles on Dynamic IP Restrictions. The below is an excerpt from the website
Dynamically blocking of requests from IP address based on either of the following criteria:
The number of concurrent requests.
The number of requests over a period of time.
There is also the possibility of doing the same with Drupal.
Make them view it in a custom-built "custom-served" video player
You can go the extra mile and make your own video-management system (which it seems like you are), and serve the videos from your own server (which is what I meant by custom-served) but some programs that have attempted this were flawed like Sony's CD management software or were punishing honest users, like Apple iTunes' FairPlay DRM software.
If you do end up going the route of giving users a program/web service to watch videos and restrict them to an password/encryption key, you could annoy the customers who paid for your content in good faith. This is essentially what all copyright protection systems tried and utterly failed with, because either the program wasn't secured well enough or people simply stopped using it because it was awkward to work with.
When you serve the videos to the users, you could break them up and separate them by chapters, as in the first chapter is one video, the second is another, and so on (like below):
http://mylearningmanagementsystem.com.au/video_title/chapter_01/video.flv
http://mylearningmanagementsystem.com.au/video_title/chapter_02/video.flv
http://mylearningmanagementsystem.com.au/video_title/chapter_03/video.flv
... and you could combine that with the hashing idea in the first section (Obscuring the URL):
http://mylearningmanagementsystem.com.au/e12d8cd38f00f204/8fd3611c40e74c3d/video.flv
http://mylearningmanagementsystem.com.au/e12d8cd38f00f204/92d7f54d09c80436/video.flv
http://mylearningmanagementsystem.com.au/e12d8cd38f00f204/27bd98792bea3103/video.flv
This could have its downsides though:
low internet users who pause the video at the start to let it load, will experience issues (less common a problem now, as the internet is now much faster and easier to access)
if one video is missing, the whole video will be unplayable
how will you manage each link? Will each video name have the same hash or a different hash?
will you have to manually break up each video?
The key point here is that this does make a lot of unnecessary work for you. The next option would be to use a video streaming service that is already available.
Use a video streaming service already available
There are plenty of options out there to host and share your video. YouTube and Vimeo are two of these options. I will explain why I prefer the latter.
Password protection
If you wanted to share the videos only with a specific number of paying people, you can protect your videos with a password on Vimeo. AFAIK, YouTube does not offer this service - it only allows you to select members to view the video.
Not only that, but you can add a bunch of videos to an album (in Vimeo), and password-protect the album, so you only have to change the password for the album.
Keep in mind that you may run into increased support messages like "But is this the current password or the one for last week?"
Set embed settings
You can make the video unable to embed on any page, so that users would have to go to Vimeo directly, type in the password (if you set one above), and view it inside their web browser. AFAIK, you can embed any video from YouTube that you can view.
You will have to keep in mind that a quick Google search revealed that there are heaps of online sites that allow you to download videos from these video-hosting websites. There are even browser addons for Firefox and Chrome.
If your business depended on your videos for monetising purposes and you wanted to go one step further, there are paid streaming services that specialise on content distribution with proper access right management and content protection. One of these services is Brightcove. Excerpts from Brightcove follow:
Brightcove Video Cloud securely delivers the highest quality on-demand and live video experiences to reach your audience—no matter where they are. We simplify delivery to an increasingly complex ecosystem of devices and standards across the web, mobile and connected TVs
... and ...
Protect your valuable content
Ensure your video is safe. Use RTMPe stream encryption and SWF verification to prevent video stream ripping and content theft and ensure that your video stream plays back only in your authorized players.
Fine-grained Access Control
Pinpoint exactly when and where your content is displayed to comply with content licensing restrictions, global launch roll-out schedules or secure behind-the-firewall delivery. The user-friendly graphical interface allows you to restrict access by date, domain, geography, player or IP address. For even greater control restrict access to sensitive materials by IP address range and ensure content is accessible only from within approved networks.
At the end of the day...
If you can view it, you can download it, no matter how much you obscure it.
If there was a way to stop people from downloading videos, every video website would be doing it.
If you had unlimited resources, you could combine all of the techniques listed above to make it not worth anyone's time. But, after all the effort you put in, a viewer could always set up one of many screen capture programs to record all the videos onto their hard drive.
It's up to you, and how vigilant you want to be with your videos. Remember that the effort and time you spend making it harder to rip a video, is proportional to making it harder for regular paying customers to get and use the content as well.
More information:
How can I make a video not downloadable?
Vimeo privacy settings
Video streaming service | Online Streaming Video | Brightcove
Maybe it's a bit too late, but I'm putting this here so that it would help others.
As others have stated, there's no way to secure contents once they reach someone's computer. But we can prevent uncontrolled sharing of the content by putting some barriers in place.
One such method that I've noticed many websites including linkedin, pluralsight, and many others use is a resource url with authorization information secured with hash. Such tokens include enough information for identifying the content to be served and a time-frame between which the url is valid.
Suppose the video you want to secure is :
example.com/videos/1234.mp4
Here's an example of how you'd generate a token on first request of the resource (after you've authenticated the user and done other verfications) :
validFrom = unixTimestamp
validTo = unixTimestamp
video = 1234.mp4
privateKey = yourSecretKey
token = HASH(validFrom.validTo.videoUrl.privateKey)
Now, create a url with all the above information excluding the private key. Your final url would be something like this :
example.com/video?validfrom=1566831998&validto=1566839198&path=1234.mp4k&hash=HhgcWmRViYeQLn4AZoQvkVXotPU
Now, whenever a request is made for a video at the path /video, you'd take all the parameters from the url (excluding the hash), and create a hash as you did earlier from the parameters and your private key in the same order. The url can be said to be valid and untempered if the hash that you just generated matches with the one that was included in the URL. This same technique is used in JWT authentication and is really efficient. As you don't have to store or retrieve information to and from any database. This makes it very quick and easy to implement.
Once you've validated the token, you can return the FileStream to the media that was requested in the url.
If it is a small and not too dynamic group then youtube or vimeo might be a possible option. But it is not scalable.
If you have a dynamic audience where members may join and leave at different times then you need to have the videos encrypted on your own server.
The biggest challenge now would be the key distribution. You need to have the key scheme such that each user has a unique key but the key used to encrypt the video is the same.
Here is one possible method: https://sparrow.ece.cmu.edu/group/pub/old-pubs/elk.pdf
other algorithms you might want to look at are : MARKS, LKH, etc.

Resources