I use Flutter/Firestore/Cloud Functions.
Say I want to update a users balance via a transaction. I will call my Firebase function from the client with the help of Googles cloud_functions package:
Future updateBalance(amount)async{
dynamic resp = await balanceUpdate.call(<String, dynamic>{
'amount': amount
});
return resp.data;
}
Is it possible for a attacker to middle man the function call and change the parameters? amount in this case. (ex: the attacker submits a $5 transaction and edits the call to the function changing it to $500).
If it isn't possible, should encryption be used anyways just to be safe, or it that not necessary?
Callable functions are just public HTTP functions that anyone can invoke using the documented HTTP protocol. Anyone can invoke them and pass any parameters they want.
Additional encryption will not help here. The API of the function is effectively public and easy to reverse engineer from the app's own code and behavior. If you don't want someone invoking your function using arbitrary values, your function should have some code that validates the user and the parameters being passed.
Related
I have a logs endpoint rest url that I want to call and get the contents by calling a function. In a simplified way, create function like below.
create function getData(url:string)
{
let data = curl GET url;
print data
}
//Call it.
getData("<some rest url here>")
The documentation from Microsoft seems to talk about Kusto's own APIs not not how to call an external API. Am I missing something?
The documentation you reference relates to calling Kusto service REST APIs.
Kusto query language is a query language, not a open-ended programming platform.
Call-outs to external sources such as SQL Azure are possible, but subject to certain restrictions, primarily security-oriented by nature.
See external data operator, sql_request plugin, and callout policy articles.
I am trying to connect my Adobe Captivate XApi course to the LRS (YetAnalytics). I have very less information as to what should i add in this code of tc-onfig.js in the course files:
// Pre-configured LRSes that should receive data, added to what is included
// in the URL and/or passed to the constructor function.
//
// An array of objects where each object may have the following properties:
//
// endpoint: (including trailing slash '/')
// auth:
// allowFail: (boolean, default true)
// version: (string, defaults to high version supported by TinCanJS)
//
TC_RECORD_STORES = [
{
endpoint : "",
auth : "",
allowFail: ,
version: "",
}
];
Generally you should avoid using that functionality. That code is leveraged by an underlying library in Captivate (Rustici Driver) for packages with a tincan.xml file. That package will be launched with an LRS endpoint and authentication credential which is where it will send the statements that it generates. Generally it is a much better idea to send all statements to that configured LRS and then figure out a way to get those statements either forwarded from or pulled from that LRS into your additional LRS(s).
This is for two main reasons. First by using this functionality you have to hard code a credential into the package which makes it insecure and indistinguishable during requests, this is generally just bad. Second, there is little to no error handling around calls that leverage this functionality, so if you set allowFail to false exceptions will go uncaptured and the content will likely behave in strange ways (or break completely), if you set allowFail to true then you will have no recourse when a call fails and you potentially will not know that you've lost data.
(Unfortunately, I know this because I implemented the functionality originally a very long time ago before fully understanding all of the ramifications.)
But just so I've answered your actual question, if you wish to not heed my advice, then the values that should go there will be passed through to the constructor for a TinCan.LRS object which is documented here: http://rusticisoftware.github.io/TinCanJS/doc/api/latest/classes/TinCan.LRS.html
The auth being the most tricky, it should be a value that is a full Authorization header value as needed to connect to the LRS, very often a Basic Auth header.
I'm using Firebase as a simple game-server and have some settings that are relevant for both client and backend and would like to keep them in RemoteConfig for consistency, but not sure if I can access it from my cloud functions in a simple way (I don't consider going through the REST interface a "simple" way)
As far as I can tell there is no mention of it in the docs, so I guess it's not possible, but does anyone know for sure?
firebaser here
There is a public REST API that allows you to read and set Firebase Remote Config conditions. This API requires that you have full administrative access to the Firebase project, so must only be used on a trusted environment (such as your development machine, a server you control or Cloud Functions).
There is no public API to get Firebase Remote Config settings from a client environment at the moment. Sorry I don't have better news.
This is probably only included in newer versions of firebase (8th or 9th and above if I'm not mistaken).
// We first need to import remoteConfig function.
import { remoteConfig } from firebase-admin
// Then in your cloud function we use it to fetch our remote config values.
const remoteConfigTemplate = await remoteConfig().getTemplate().catch(e => {
// Your error handling if fetching fails...
}
// Next it is just matter of extracting the values, which is kinda convoluted,
// let's say you want to extract `game_version` field from remote config:
const gameVersion = remoteConfigTemplate.parameters.game_version.defaultValue.value
So parameters are always followed by the name of the field that you defined in Firebase console's remote config, in this example game_version.
It's a mouthful (or typeful) but that's how you get it.
Also note that if value is stored as JSON string, you will need to parse it before usage, commonly: JSON.parse(gameVersion).
Similar process is outlined in Firebase docs.
We can define methods on Meteor server and call them from clients, is there any way to call client defined methods from server?
As per official Docs there is no direct way to call client side methods from server but you can achieve that by using a smart package called anti:methods
You need to set the clientId which will be used to communicate to this particular client.
Tracker.autorun(function() {
Meteor.ClientCall.setClientId(Meteor.userId());
});
Defining a method
Meteor.ClientCall.methods({
'chatMessage': function(username, message) {
...
},
});
Calling a method
Meteor.ClientCall.apply(clientId, method, arguments, callback)
Note: This package is not fully functional. Check the readme for more information.
Alternatively if you just want to re-use some code in both server and client, you can create a global function in common folder and call it from anywhere you want. Just make sure it does not contain any browser specific code and it loads before the function where you calling it.
I don't want just all of my users being able to insert/destroy data.
While there is no documented way to do this yet, here's some code that should do what you want:
Foo = new Meteor.Collection("foo");
...
if (Meteor.is_server) {
Meteor.startup(function () {
Meteor.default_server.method_handlers['/foo/insert'] = function () {};
Meteor.default_server.method_handlers['/foo/update'] = function () {};
Meteor.default_server.method_handlers['/foo/remove'] = function () {};
});
}
This will disable the default insert/update/remove methods. Clients can try to insert into the database, but the server will do nothing, and the client will notice and remove the locally created item when the server responds.
insert/update/remove will still work on the server. You'll need to make methods with Meteor.methods that run on the server to accomplish any database writes.
All of this will change when the authentication branch lands. Once that happens, you'll be able to provide validators to inspect and authorize database writes on the server. Here's a little more detail: http://news.ycombinator.com/item?id=3825063
[UPDATE] There is now an official and documented Auth Package which provides different solutions to secure a collection.
On a CRUD level :
[Server] collection.allow(options) and collection.deny(options). Restricts default write methods on this collection. Once either of these are called on a collection, all write methods on that collection are restricted regardless of the insecure package.
And there is also insecureto remove full write access from the client.
source : Getting Started with Auth (thanks to #dan-dascalescu)
[OLD ANSWER]
Apparently there are working on Auth Package(?) that should avoid any users taking full control on the db as it is now. There is also someone suggesting that there is an existing solution (workaround) by defining your own mutations (methods) and make them failed if they attempts to perform an unauthorized action. I didn't get it much better but I think this will often be necessary since I doubt the Auth Package will let you implement the usual auth logic on a row level but probably only on the CRUD methods. Will have to see what the devs have to say.
[EDIT]
Found something that seems to confirm my thoughts :
Currently the client is given full write access to the collection. They can execute arbitrary Mongo update commands. Once we build authentication, you will be able to limit the client's direct access to insert, update, and remove. We are also considering validators and other ORM-like functionality.
Sources of this answer :
Accessing to DB at client side as in server side with meteor
https://stackoverflow.com/questions/10100813/data-validation-and-security-in-meteor/10101516#10101516
A more succinct way:
_.each(['collection1', 'collection2'], function(collection){
_.each(['insert','update', 'remove'], function(method){
Meteor.default_server.method_handlers['/' + collection + '/' + method] = function(){}
});
});
or to make it more idiomatic:
extend meteor:
_.extend(Meteor.Collection.prototype, {
remove_client_access: function(methods){
var self = this;
if(!methods) methods = ['insert','update','remove'];
if(typeof methods === 'String') methods = [methods];
_.each(methods, function(method){
Meteor.default_server.method_handlers[self._prefix + method] = function(){}
});
}
});
Calls are simpler:
List.remove_client_access() // restrict all
List.remove_client_access('remove') //restrict one
List.remove_client_access(['remove','update']) //restrict more than one
I am new to Meteor, but what I have come across so far are these two points
You can limit what a client can access in the database by adding parameters to the find command in the server-side publish command. Then when the client calls Collection.find({}), the results that are returned correspond to what on the server side would be, for example, Collection.find({user: this.userId}) (see also Publish certain information for Meteor.users and more information for Meteor.user and http://docs.meteor.com/#meteor_publish)
One thing that is built in (I have meteor 0.5.9) is that the client can only update items by id, not using selectors. An error is logged to console on the client if there is an attempt that doesn't comply. 403: "Not permitted. Untrusted code may only update documents by ID." (see Understanding "Not permitted. Untrusted code may only update documents by ID." Meteor error).
In view of number 2, you need to use Meteor.methods on the server side to make remote procedure calls available to the client with Meteor.call.