How to generate a firebase download token [closed] - firebase

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
How do we go about generating a firebase download token within the admin SDK, knowing it can easily be done with the client SDK.
I understand the client SDK acts as a wrapper on the storage SDK, therefore it adds this functionality, but then, why not giving the admin SDK the same option. I just want to know how to generate that token myself, with the current SDK, because I need the URLs to have the same format as the ones generated within the client, and using getSignedURL, the format is way different and does not abide to the firebase storage rules, nor it is permanent, as it expires after a set amount of time.

It sounds like you're mistaken on one point. The download URLs created by the Storage SDKs on the client do not actually "abide by security rules". Anyone who has that download URL can read the object. This is no different than signed URLs generated by the server SDKs.
Both types of URL are functionally equivalent. The obvious exception is that signed URLs have an expiration, but you can set that expiration arbitrarily far in the future that it makes no difference.
To put it in short - client download URLs can't be generated by the server SDKs, and signed URLs can't be generated by the client SDK, but it doesn't matter because they serve the same purpose.

In order to get an URL exactly like the one getDownloadURL from the client SDK, while using the admin SDK, all you need to do is to update the object's metadata with a key called firebaseStorageDownloadTokens. Contrary to what everyone else says, you don't need that signedUrl.
$uuid = someUuidMethod();
$object->update([ 'metadata' => [ 'firebaseStorageDownloadTokens' => $uuid ] ]);
The moment you run the above, you'll get an error as follows:
serviceaccount does not have storage.objects.update access
In which case, you need to go to the IAM section in GCP Console, select your service account ( the one mentioned in the error ), Edit roles, and add another role Storage > Owner.
Run the update command again, and job is done. You can now generate your own tokens. It's needed when you rely on cloud services to work on your storage files.
Hope it helps :)

Related

When/where is the best moment to check for Firestore document ownership (service or middleware) [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 months ago.
Improve this question
When implementing security rules to ensure a user can only fetch/update their own documents in Firestore, where should I put the logic?
(Before you say 'in Firestore Security Rules file', please note that I am using the Firebase Admin SDK which bypasses these security rules rather than the frontend Firebase SDK.)
For more context:
I have built a CRUD REST API using a Koa server implemented in Firebase Cloud Functions which documents stored in Firestore.
API calls are authenticated using Firebase Auth, and I decode the authorization token to get the User ID of the person calling it.
I created a FirestoreService class which can fetch and read data from Firestore.
I use custom Koa middleware to check the user has relevant roles and permissions (uses AccessControl library) but this middleware doesn't check for document ownership, only that someone has the permission to 'getOwn' or 'getAny'.
But where should I put the logic to check, for example, that a document being fetched has a 'userId' property set to the ID of the currently logged in user.
It seems I have 3 options:
In middleware. Before passing responsibly to controller to do the work, middleware should perform a 'get' operation then check the userId attribute of the document returned matches the logged in user. Downsides of this approach is that I am fetching the document twice - once to check permissions and then again in the controller.
In controller. Once the data has been fetched from the database I do the userId check. Downsides of this are code replication as I'll have to write this logic in each controller function.
In service. Perform the check in the FirestoreService class once the data has been fetched. Downside of this approach is that it feels like I'm adding additional logic to a service which should remain generic. The service get method would need to be called with details about what attributes to check and know the userId.
What's the best approach to this puzzle in terms of architecture?
Bear in mind it should work for all CRUD operations, not just the 'read' operation.
Any help much appreciated!
I started with the logic in the service but it feels clunky.
You have not provided much details on what queries you are running, or what resources can be deleted so I'll take a general CRUD example of TODOs.
First, you'll need the user ID in every controller/service before querying so it makes sense to verify user's token in a middleware and add it to request context. Then you just have to ensure you query that user's data. For example, if you have a list TODOs API, your query will be:
const snap = await todoCol.where('userId', '==', ctx.user.id).get();
If you don't add the query constraint, then Firestore SDK will return all the documents in the collection.
The same applies for update and delete operations. If you have a DELETE /todos/:todo_id API, it'll be best to query the document first and check if the request user ID matches the user ID in the document data. If not, return an error.

Can anyone view a website source code through browser? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 months ago.
Improve this question
So, I am trying to safely store an authentication token using Angular, processed with additional encryption on top (in front end) and put it in browser local storage (so that not anyone can de-code it).
Many people recommend this method, but I came across several opinions that say even in such case one can access your source code through your browser and get your secret key to decrypt the Auth Token (for example experienced hacker).
Many people claim that Access + Refresh tokens are the best in terms of security.
So, my question is - what are standard practices for serving/ storing authentication token? Is token encryption in local storage good implementation or should we use refresh tokens (although, they are harder to implement)?
I think you should use both a refresh and access token for maximum security...the access token should have an expiration date and should be blacklisted after rotation(when you use the refresh token to get an access token)...if you need even more security,after rotation,the user should get a new refresh and access token

Firebase Storage URL format instead of using References

I wanted to know how long lived the firebase storage URL's are.
I'm using firebase storage to host some static images. Currently using the file references to get the url's in app.
But would like to skip this step and just use the URL's instead. Does anyone know what if anything will cause first part of the URL to change?
(https://firebasestorage.googleapis.com/v0/b/)
Total URL
https://firebasestorage.googleapis.com/v0/b/{Project_ID}.appspot.com/o/{FILE_PATH}?alt=media&token={TOKEN}
The first part of the URL (https://firebasestorage.googleapis.com/v0/b/) will only change if the Firebase Storage API ever changes. Since this hasn't happened since its release in May 2016, and isn't planned to happen at any point at the moment, we can be certain it is a really infrequent occurrence.
The {Project_ID}.appspot.com/o/ will only change if you have a different project. For an existing project this will never change.
The {FILE_PATH} is the path to your file, so will only be different when referring to a different file.
And token={TOKEN} will only stop working if you revoke the token, as answer here: Firebase Storage getDownloadUrl's token validity
A download URL will last forever, or until its specific token is rejected from the Firebase console.

How to create stripe standard account with flutter and firebase [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have this amazing flutter app and I managed to set up a payment system with Stripe. My app is a marketplace so I have many vendors and I am able to collect money from the users and transfer the money to vendors. I have create a test vendor and it all works fine in testing mode. Now I would like to let prospective vendors to create a Stripe standard account and connect with my platform. Here are the instruction I would need to follow: link to stripe
I read the instructions but I am not able to understand or implement it. I would like to know if I can implement the steps within my Flutter app or not. I am not familiar with servers but I have managed to use firebase to create charges. My first problem is the redirect URI (what is this?). The second problem is how to handle the response from stripe (step 3) and lastly get the vendor data with a POST request... Is there anything simple to use in flutter? I have seen this and this but I am not sure they can be used...
Can you please clarify what should I do here. Many many thanks in advance
Here is what I did
in firebase: I created an http function, ie exports.createStripeAccount = functions.https.onRequest((req, res)
in stripe: set that function as redirect uri
in flutter: launch(url_to_connect_the_account)
in firebase inside the httpfunction:
return stripe.oauth.token({
grant_type: 'authorization_code',
code: req.query.code,
})
and that's all folks!

Meteor - What is the best process for securing forms and storing sensitive data [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I'm building my first app with Meteor and I'd like to know the best security measures to take in a couple of situations...
How do I ensure users are not submitting commands like drop table to my forms? Do I have to manually sanitize somehow or is this automatically handled?
Normally I would use a GET on forms if it asks the user for sensitive information, however I'm confused how Meteor handles inserting items to the db. Is the info submitted through forms secure or is it being passed over somewhere people can it?
If I have removed the autopublish and the insecure packages it means users cannot just query for other user information, is that correct?
Sorry, if these are noob questions. I haven't quite wrapped my head around how the security of an app all fits in but any help would be much appreciated :)
Here is a quick rundown of the basics of securing your meteor app:
Transmit everything over HTTPS.
Separate your client and server code into their own directories. A great way to keep your server-side secrets safe is to never send them to the client in the first place.
Remove the insecure package.
Remove the autopublish package.
Add the audit-argument-checks package and add checks to all methods and publish functions.
Add the browser-policy package (after completing all of the above).
Here are some answers to your questions:
If insecure is removed and you don't have any allow rules, then users can't remove anything. Regardless, documents on the client can only be removed or updated by id, so you can't drop a collection with a single command.
With the proper allow rules specified, then the client can execute an insert/update. Otherwise, you can use a meteor method to have the server perform an insert/update for you. e.g. you can specify a method like postsInsert on the server. Messages will be passed between the client and the server in the clear unless you use SSL.
Correct. With autopublish off, you need to specify which documents are published to the client - otherwise the client will not have read access to any documents.
If you don't want your users to perform certain operations, you don't allow them to do so. The only commands your users are able to perform on the database are those you specify : when you remove the insecure package, typing Collection.remove({}); in the browser console won't drop the entire collection, users will have to Meteor.call certain allowed operations (through Meteor.methods) to perform authenticated-only stuff.
Generally, you want the OWNER of a resource to be able to edit/delete it, but other people shouldn't be able to modify it.
If you have an edit form for one of your collection, you will likely have corresponding Meteor.methods to edit/delete it.
Inside a Meteor.method, you can check the passed arguments received from the client to validate data correctness, you can also verify if the call was issued from an allowed user (typically the owner of the document).
Hopefully, Meteor comes with a Match framework to test parameters sent to Meteor.methods.
// define a test to check if a document is editable by a certain user
EditableDocument=function(userId){
return Match.Where(function(documentId){
var document=Collection.findOne(documentId);
if(!document){
throw new Meteor.Error(500,"Document doesn't exist !");
}
if(userId!=document.creator._id){
throw new Meteor.Error(500,"Can't update a document you don't own.");
}
return true;
});
};
Meteor.methods({
updateCollection:function(documentId,fields){
check(documentId,EditableDocument(this.userId));
check(fields,{
field1:Match.Optional(String),
field2:Match.OneOf(Number,Boolean),
field3:Match.Any
});
// if the tests pass, do your thing
...
}
});
To communicate form data between the client and the server, Meteor uses DDP (Data Distributed Protocol) with a technique known as Remote Method Invocation.
A client can Meteor.call a Meteor.method declared in the server and get a response asynchronously.
This is different from classic form submition manipulation techniques which is done using HTTP, and can use its secure counterpart HTTPS, to encrypt data between a client and the server, avoiding data sniffing issues.
DDP supports data encryption and every *.meteor.com hosted sites are using meteor.com certificate to ensure that all traffic is properly encrypted using SSL.
On your own hosting solution, you will have to handle this yourself though.
https://groups.google.com/forum/#!topic/meteor-core/a9dPA1-mgXA
After removing autopublish, every server resources won't be published to all clients no more, meaning that one can't just query your collections to get other users documents access.
Be sure to read the docs at least once to fully understand Meteor related aspects of web development.

Resources