Orbit-db security, how to prevent illicit docstore updates - orbitdb

I have a specific use case for orbit-db but I am a bit fuzzy about a certain security implication.
I'm developing a web app where a user logs in through a Tronweb wallet account.
People can post questions, whereas other people can answer them and get paid for it.
In order to do so, I add the public key of the respondent to the question and save it to Orbit db.
Now it is my understanding that default access to any orbit-db instance is given to the app (identity) that creates it per default, or you can add custom access controllers. Let's say, if I want to create a db to manage tags, I could create an identity based on my own tronlink account and require a login to create those tags. Nobody else would be able to access that db.
Now what I am a bit fuzzy about is what happens when:
An OP creates a question, and a respondent registers an answer.
When the OP accepts the answer, and payment through the Tronlink plugin will be executed.
But since OrbitDB can run without a server (i.e. p2p based on a local IPFS node), what prevents anybody to set a breakpoint in the client-side Javascript code, get a handle to the db instance, and execute an update call to update the respondent's address locally in that question document, after which it will be synced to other nodes?
I store the public key of the respondent in orbitdb, but the transaction is still confirmed by the OP through Tronlink wallet plugin of course. But still, you cannot assume all users to check it every time.
Since there is no server involved, I don't see how you can prevent corruption of the db client-side by unwanted parties.
Could you enlighten? Let me know if my question is not clear.

what prevents anybody to set a breakpoint in the client-side Javascript code, get a handle to the db instance, and execute an update call to update the respondent's address locally in that question document
Nothing.
after which it will be synced to other nodes?
This is what makes OrbitDB secure. Each document that is synced to a new node, needs to pass through the validator function of this node. So, honest (the ones that have a correct AccessController) nodes will filter out malicious changes.
What that means? A node can be "corrupted" but it can't "corrupt" other nodes in the network.

Related

How does CM & CD server communicates in sitecore?

I am new to sitecore and just trying to understand its architecture/design. Just curious to know how Intranet and Internet server communicates and how does the data flow happens between these two layers in on-prem and on AWS EC2 environment? I have surfed enough in the web and couldn't find the appropriate explanation.
Really appreciate if anyone can help me understand.
When u do a publish from CM, it puts a record in eventqueue table in Web Db.
all CD servers will hit the eventqueue table table for update and proceed.
default is 2 seconds once this hit happens.
In short, they communicate via events in the database(s). Note: This is very simplified but seeing it this way helped me understand how the events work and troubleshoot issues.
For example, when publishing an item, the publisher (running on CM or on a dedicated role) reads its data from the master database and writes it to the web database. When done, it raises an event by writing a row in the EventQueue table in web database. The CD server(s) picks up this event and clears its corresponding caches etc. causing a reload of that data from the web database.
All Sitecore databases have the EventQueue table and events goes to the table in different databases, depending on the type of event. An events is basically just a class name and a set of serialized data. Events can be raised "locally" and "globally" indicating if several instances should pick up the event. Think of a scenario where you have two CD servers sharing one web database, both CD's would have to pick up the event.
To keep track on what events has been processed, a "EQSTAMP" value is stored in the Properties table. It's named [database]_EQSTAMP_[InstanceName]. It's therefore essential that not two Sitecore instances share the same instance name. If not set, Sitecore will make an instance name by combining the hostname and IIS site name. The decimal Value of this timestamp corresponds to the hexadecimal Stamp column in the EventQueue table.
Normally, you should never have to play with these tables yourself, but I find it good to have some insights in how they work and keep an eye on them. They can grow in size and cause some issues. The CleanupEventQueue scheduled task is responsible for removing old processed events from the EventQueue tables. You may want to play with the scheduling of this agent if your EventQueue grows too large between cleanups.
Note: This is the most common way of communication between the servers. Later versions of Sitecore have other techniques as well, such as Rebus.
Event Queues. Why? How? When? article that explains it in detail, it also describes the pitfalls of using this mechanism in real life as well.
Please also be aware that Sitecore.Link project is a good place to get more knowledge regarding Sitecore functionality.
It accumulates Sitecore knowledge all around the web.
Thanks.

Architecture/Technical Challenges in Handling Authentication/Permissions in Elixir Channels/Sockets

So I have decided to rewrite an application I have been writing in Node.js to Elixir because of all the extra complexity working with Node that Elixir comes with out of the box.
My issue was something I didn't have quite right in Node and is becoming just as complex in Elixir and I am not entirely sure how to go about approaching it.
I am trying to recreate a lot of how Discord does permissions. I am essentially building a CRM system, with different roles like "Sales Manager", "Sales", "Customer Service Rep" etc... But they all are able to do different things based on their "role".
Some things I need to do is be able to update a permission on the fly for a person or role. Maybe the "Sales Manager" role can't look at company financial data like an "Accountant" but we need to give that specific person access for a few days. Or I have a "Customer Service Rep" and we give that entire role the ability to add things to a calendar. I also would like to have the ability to kill sessions.
So there are a few ways I've seen said around Elixir forums, like:
Using Guardian, I really want to like tokens and think not having to hit the database every time sounds wonderful, but I don't think it's practical for this. Unless there is a good solution to updating tokens on the fly which I haven't found.
Giving each person their own process and just kill and start the process on changes with new changes. This seems pretty neat, but I'd rather not kill processes unless there is an actual error, I think this solution will come with big problems, like tracing problems. Although I am not familiar enough to know if this might actually cause problems, or if this is a bad solution for other reasons.
Use Guardian with Guardian_DB, which then defeats the purpose of using tokens, but at least I'd have a trackable session. My only problem with this is I do plan on using a load-balancer so that if a socket connection dies I can reconnect it to the same server and I am not sure there is a way to do that with tokens or if the socket itself has a session attached to it. This is not really that big of an issue though and is pretty close to what I had with Node.js.
Use Redis which I'd like to stay away from, and then update session data in Redis based on user_id when updates occur and hit Redis on every request to see if the user has permissions. I plan to put this across multiple servers eventually which means ETS is not viable unless I can load-balance socket connections like I could in Node.js.
So I guess my questions are,
Can I attach sessions to sockets? Is this a bad idea?
Should I still use a token, and just use Redis to check the token on every request?
Is a token still a better choice than a session?
Is there a much better/easier solution that I have not even mentioned?
I'm sorry this was pretty drawn out and long, I've never had to do something as permission bound as this project professionally and am pretty new to Elixir.
Phoenix channels are stateful. You can put data in the assigns field and it stays there for the duration of the connection. That is where you normally put your user_id after authenticating the user on join.
I also use the channels assigns to store client state that I need on the server.
WRT to the role to permissions question, I'm doing exactly this. What I do is load the load the role permissions from the database on startup and build an ETS store with them. You can do the same with a Task or a GenServer. If the permissions change for a given role, i update the database and the ETS table.
My user model supports a list of roles for each user.
When in need to validate the permissions for a given user, I call the Permission model api like Permission.has_permission?("create-room", user, scope). I have two level of permissions, global and per room. That is what the scope is used for.

Storing sensitive data in mySql

I am lookin to harden security on one of my client sites. There is no payment provider set up so sensitive Direct Debit information needs to be on a mySql server. This Direct Debit information needs to be human readable by users from accounting department.
Testing server is set up as follows:
At present, main site is sitting on a wordpress blog.
Customer completes HTTPS encrypted form with an EV SSL certificate.
Data is stored in a separate database to the wordpress database.
Direct debit details are currently stored as plain text
Now part 4 is what bothers me... but it's ok at the moment, because only on the testing server!
This is really difficult to answer, as it depends on how far you need to protect this data.
First step is obviously encrypting all details stored in mysql, incase someone gets a dump of your database.
This solution is good, but it introduces the vulnerability as if someone gets the decryption keys from your application server, they would be able to decrypt the dump of the database anyway.
There are many solutions to consider from here, i'm sure with some research you should be able to find some decent ones, but one way that comes to mind is:
You could encrypt the data on the application servers with a public/private key encryption algorithm. Public key can only be used to encrypt the information for storage, which lives on your application server. If that gets hacked, the only thing that they will be able to do is to add more data to your database =/. The private key in this case will be a password that would need to be entered every time a human needs to see this information.
This has the obvious disadvantage that you can't do any machine processing on your data, as its traveling completely encrypted all the way until its displayed.
(And you still have vulnerabilities of someone gaining access to your application server and simply dumping the session files/memcache where the key would have to be stored temporarily)
To be honest, first thing i'd do is encrypt the entire database one way or another. That alone adds a decent layer of protection. Dumping the database is easier than getting access to the file system of a server in most cases.
Are you talking about bank account details / credit card details or both?
Be aware storing credit card details brings attached fulfilling PCI requirements.
Also, if you are planning to store confidential details, NEVER store them unencrypted.
Any questions, just let me know.
Fabio
#fcerullo

Tomcat Session Replication

I am trying to develope an application with tomcat running in several computers of same LAN trying representing several nodes and each of them runs an application with a single shared session(Ex. shared document editor such as google docs.). in my understanding so far I need a single shared session and several users need to update the doc symultaneously and each others updates are reflected on each others we interfaces almost imidietly. Can I acheve this with with tomcat's clustering feature. http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html#Configuration_Example or is this just a faluir recovery system.
Tomcat's clustering feature is meant for failover - if one node fails, user can carry on working while being transparently sent to another node without a need to log in again.
What you are trying to achieve is a totally different scenario and I think using session for this is just wrong. If you go back to Google Doc example, how would you achieve granting (revoking?) document access to another user? What do you do when session times out - create the document again? Also, how would you define which users would be able to access selected documents?
You would need to persist this data somewhere (DB?) anyway so implement or reuse some existing ACL system where you could share information about users and document permissions.

Guidance for storing state in a database for a web application

I have some questions here and here the management of state in an ASP.NET MVC3 application. One of the answers mentions that an option for this is to simply store the state of each step in the database.
I was wondering if anyone had any advice on how this is usually achieved as I had some thoughts when this was first suggested to me.
Invalid entities
Consider a multi-step form (wizard) that has 3 steps. I could save each step in the database to maintain state but a user could close the web application midway through the process leaving my database containing entities that are in an invalid state.
To overcome this I could add a field to the table which indicates if the wizard has been completed. Any inconsistent items could be reviewed on a periodic basis and automatically deleted if required e.g. if any invalid entities are found in the database at the end of the day they will be automatically deleted.
The problem with this is that I have to add fields to the tables to store metadata about the application. Every table that stores information that is entered in a multi-step form needs to have these fields. This seems wrong to me somehow. One solution might be to create a specific table for managing this rather than polluting each entity table with metadata.
Intermediary database
I thought of having a database that sits in between my application and the 'real' database.
The intermediary database would have tables that stored the state information for each 'step' and only when the last step was completed would this information be transferred over to the 'real' database (and the temporary data deleted from the intermediary).
This also sounds similar to one of the session state options offered by ASP.NET already so personally I think this would be a waste of time.
Use in other application (E.G. Desktop)
At this moment in time my application is purely web based, but I have plans for having desktop programs that can interact with the same database. If the database has a load of meta-data used by the web application for storing state my desktop application is going to need to be aware of this in order to avoid any errors (I.E. my desktop application would need to know that it has to set an entity state as 'valid' so that the web application does not delete the entity at the end of the day because it thinks it is invalid).
Summary
So does anyone have any information or tips on how to best use a database for storing application state?
Is the database option that common?
Is it suitable for large applications with a lot of entities?
Are there any performance implications?
Edit
Just to be clear, I am aware that other options exist for managing state in an ASP.NET MVC application (TempData, cache and session) but I am specifically interested in information about using a database to manage state.
Please refrain from down-voting anyone that has mentioned the other options as my original question may not have been clear about this.
Why not store data in a session state? You just need to come up with a mechanism that would allow you to uniquely identify and store items in the session state.
To start with, you can use InProc session state mode. As the system grows, you can look into storing your session state on a state server or on a SQL server.
This is a hard one to answer, but basically, I'd see two routes.
If the data in a given step in the wizard is logically right, and meets all the constraints you've imposed, you could write it to your "main" database. For instance, if you've got a multi-step process for managing orders, and step one is to create a customer record if one doesn't already exist, write the customer record to the database when the user completes the form.
This means that if the user goes away, closes the browser or whatever, the data will be there when they come back - which is probably what they expect.
If the data in a given step is NOT coherent, does not meet constraints etc., use session state to manage it until it's ready for writing to the database. Session state in MVC is a bit of a pain, and you should use it sparingly - it makes it hard to write unit tests.
The purpose of session state is to store data that is relevant to the user session, but that isn't (yet) intended to go into the database.

Resources