My use case is that I want to stream a video which was uploaded to firebase storage.
My understanding is that when the video is first uploaded a firebaseStorageDownloadToken is created.
Then whenever in the client app I call getDownloadUrl a user gets access to the secret token and can technically share the url with others to watch or download.
I don't really need the long lived access or the videos to be shareable.
Isn't it then more secure to periodically refresh firebaseStorageDownloadTokens with a new value?
That would prevent the stolen urls from working.
And then if a user wants to watch same video again a new url through getDownloadUrl is obtained containing a new token.
Do you think it makes sense as a security measure?
What would happen if a firebaseStorageDownloadTokens is changed while I'm watching the video? Would the stream stop emitting?
While you can definitely revoke the default token, it isn't automatically shared with any users - so the chances of it being abused by them are pretty small. But: users that can upload through the Firebase SDK for Cloud Storage can also call getDownloadURL on the objects they upload and thus generate new tokens. If this is a significant concern for your use-case, you should probably not allow uploads through the Firebase SDK.
There (currently) is no way in the Firebase SDK to generate a URL that automatically expires. If you want that, consider using one of the Cloud SDKs for Cloud Storage, which have the option to generate so-called signed URLs that do precisely that.
Related
I'm trying to create an apple watch only app besides our app. This would be a standalone app without ties to the base app.
I can't use Firebase SDK-s, or other Google SDK-s as none of them support the watch.
I am trying to use the REST API-s and I hit a road block.
I can successfully retrieve a token for a user/password account with the identitytoolkit domain "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key="
which gives me a token I am trying to use for the endpoint:
https://www.googleapis.com/upload/storage/v1/b/mybucketid/o?uploadType=media&name=test233
however this endpoint tells me that I'm unauthorized. When I use the token I get with from OAuth 2.0 playground it works.
The problem is that that one expires and I cant build the app with a new token every time obviously.
Could you tell me what I'm doing wrong? I can't open webviews on the watch to approve a sign in, also can't communicate with an iPhone as this is a standalone app. I need something thats just hardcoded pure code. This is still an experiment and wont go out to real users. A non-expiring token would also work for my use-case.
I changed my buckets policy in a way that my user should be able to write into it but its still giving me authorization issues.
I don't think you can upload to a Cloud Storage bucket that is secured by Firebase through the REST API with a Firebase Authentication user. Essentially the REST API doesn't know how to execute Firebase rules, and only accepts operations that come with an OAuth2 token from a collaborator on the project.
Can you authenticate with the iPhone app and get a token from there when the old one expires? I know you are building a standalone watch app, but maybe this is a compromise worth making. Then you could use Firebase Functions to upload the image, validate the token (admin.auth().verifyIdToken(token)) and push the image to Cloud Storage. I have not tried this with an image but have successfully submitted authenticated payloads to the Firebase Realtime Database REST endpoints from a watchKit app.
I have an app with SwiftyDropbox that function correctly, but I need to insert email and password for Dropbox every time that I use the app.
The app it's only for my use, it's not a security problem if the app auto-login in my account.
I don't find examples or documentation to make an auto-login with SwiftyDropbox. It's possible?
While the Dropbox API was designed with the intention that each user would link their own Dropbox account, in order to interact with their own files, it is technically possible to connect to just one account. We generally don't recommend doing so, for various technical and security reasons, but those won't apply if you're the only user anyway.
So, there are two ways to go about this:
1) Implement the normal app authorization flow as documented, and log in and authorize the app once per app installation. The SwiftyDropbox SDK will store the resulting access token for you, which you can programmatically re-use after that point each time using authorizedClient.
2) Manually retrieve an access token for your account and hard code it in to the app, using the DropboxClient constructor shown here under "Initialize with manually retrieved auth token".
I'm building an app that will allow users to upload videos to my Youtube channel. I have checked online about using Google Api to access the data/upload videos, but all references and examples seem to assume videos will be uploaded to the user's youtube channel, hence the process always involves using OAuth to gain approval from the user.
However, in my case the only youtube channel all users will access is mine. And I'm not even asking them to create an account on my app to upload the videos. Is there a way to do this directly from the app.
My app is an iOS app, but if you have a solution in any other language, I welcome your suggestion.
Thanks in advance
I had the same problem not so long ago. Youtube Documentation doesnt make it easy. Even though you getting access to your own Youtube channel, You still need to be authenticated using OAuth. Google makes hard for you to be vulnerable to attacks.
My solution is using a server side(API) application. What you can then do is make your iOS app hit the API.
So the tricky thing is getting the refresh token. Its hardly documented anywhere. What you can then do is follow documentation of your preferred language for the API.
The documentation can be found here https://developers.google.com/youtube/v3/guides/auth/server-side-web-apps
Get the Refresh token:
Step 1 : Hit this url in the browser https://accounts.google.com/o/oauth2/auth?client_id=ClientID_Here&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://gdata.youtube.com&response_type=code&access_type=offline
It will make you log in using your youtube credential which is your google account.
You will then have to agree for google to access your account by clicking allow.
At the end it will give you a code.
Step 2 : You should then authenticate using a clientless platform.
(eg instead of browser) Use curl instead. (There plenty of 3 minute tutorials on how to use curl)
Hit this url endpoint :
curl https://accounts.google.com/o/oauth2/token -d "code=CodeFromGoogleOAuth&client_id=ClientIDHere&client_secret=ClientSecretHere&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code"
You should then get a refresh token in the response.
There are alot of examples of how to upload from then on like
https://developers.google.com/youtube/v3/code_samples/dotnet
In the example above you have to avoid using the GoogleWebAuthorizationBroker use Googles one instead. Look for RefreshToken Field
It is not possible to allow third parties to upload videos to a single YouTube account with the YouTube Data API, and that is by design. See this Google Blog, explaining "It’s tempting to design a system in which all videos are uploaded to a single “master” YouTube account, but this is always the wrong approach."
A potential workaround is to use YouTube Direct Lite, which allows you to easily build and moderate a playlist on your YouTube account comprised of videos uploaded by your users on their accounts.
I have a REST api that list me all files in a bucket. I show this list in a webview on a ios device.
It's not possible to make this file public.
So to my question, how can i access the files in my ios app?
My idea is, i create a read stream in my api that open a read stream to the file in the gcloud bucket.
Is there a better way to do this?
The canonical way to expose a private file is to used signed URLs. Basically, your iOS app would request access to a file from your app. If your app decides to grant this access, it generates a URL, signs it with a private key, and then provides that signed URL to the iOS app. The app then fetches the URL provided like any other URL, the body of which will be the object's contents.
Signed URLs have some nice security advantages. They can only be used for exactly one thing, and they're only valid for a few minutes (you can configure exactly how long they're valid).
The signing logic is a little tricky, but the gcloud libraries have functions to sign URLs for you.
Documentation is here: https://cloud.google.com/storage/docs/access-control/signed-urls
I am building a paid iphone application which
- shows some premium content videos to the user.
- app loads a page from my webserver in UIWebView
- but the videos are hosted at some other video hosting site.
I realize that, in order for me to be keep this app paid, I need to keep the video links protected/secure (else if the urls are leaked, no one is going to want to pay for it).
I can easily password protect the webpage (pointing to the actual video) and make the user name and password available to the iphone app to access this webpage. But when the user selects the video link, the app will load that url. If user sniffed the packets on the iphone at this time, they could get access to the url and just run it from there directly.
I dont believe mod_sec_download or mod_xsendfile can work in this scenario because the video link is external. Right?
Is Amazon S3 a possible solution?
Would appreciate any insight/solution.
Thanks!
Don't point directly to a video file. That'll make it trivial to steal. instead, point at a proxy script that can check the source of the request and verify that it's coming from a registered purchaser.
With appropriate one-time tokens, tracking of usage, etc... you can keep most people from sucking your site dry. And of course, the best practice is to embed a watermark into the video as it plays, so that even if it gets stolen, you can track it back to the first person to release it.
You might want to take a look at the OWASP Top 10 and in particular, number 8 about failure to restrict URL access. This is effectively your scenario: you have resources which need to be secured at the server level. You can't just do this from the device end, the location of resources requested by the device is easily discoverable.
So it comes down to access controls on the resources, in this case, your videos. How you do this will depend in part on your server stack. For example, IIS7 has an integrated pipeline which can apply access controls to resources of any type such as PDFs, images and videos (more on this in OWASP Top 10 for .NET developers part 8: Failure to Restrict URL Access). Alternatively, you'll need some form of application proxy which can take responsibility for the authentication then delivery of the video content.
This is really more of a webserver issue than an iPhone issue. Focus on getting the access controls right on the server then the iPhone end will be a much more straight forward process.