The architecture of client-side Zenome application. Current state.
This time we will show you no new screenshots because changes we have done are rather architectural.
Basically our client can be viewed as two separate parts:
1. The main (windowsless) process that does all the hard work: processes files, communicates to blockchain and so on.
2. The renderer process that takes care of providing user interface.
These two are isolated from each other and communicate with each other through secure IPC (by sending text messages, simply speaking)
There are several reasons to do so:
1. Security: By isolating critical parts of the system we greatly reduce the attack surface. The sensitive data (such as encryption keys) will be stored and processed only on the main process.
2. Modularity: When API is stable enough, alternative UIs will appear. We understand that different users have different needs and will provide ways to customize software to the core. Console-based user interface will be useful to node maintainers (miners), for example.
3. Separation of concerns: these parts provide different levels of abstraction. At the main process the low-level operations take place and front-end process requests the main process to run a sequence of operations to do a complex task.
An example:
Let’s suppose an attacker managed to fully control user input (and can make unlimited nuber of requests) and aims to compromise sensitive data such as genetic results (about 900 000 of SNPs). But when a number of request reaches a really huge number, the main process switches to sending random data instead of real, doing so without any notification. It switches back if no requests are made for some time (10 mins).
Consideration:
- Full control over the front-end is not enough to compromise considarable amount of data.
- The attacker recieves complete garbage instead of data dump and does not know about it
- Legitimate user can never make that much requests and will never encounter random data
- Data used for other purposes (such as using at genetic services and to get genetic result) must always be real.
- To enforce that different subsystems involved in handling data request for rendering using interface and other purposes.
- The threshold can be chosen randomly to some extend. That prevents the attacker from dumping data by chunks. Having no clue what threshold is, the attacker is forced to use the smallest possible size of chunk to avoid getting garbage instead of data, making this attack vector pointless.
So, what was improved:
- Main process now has internal database and stores all configuration in a file.
- User can select configuration file in settings. This is the first step of implementing account management.
- 2 different APIs for data requesting implemented in IPC: queries and dataviews.
- Both are now asynchronous (i.e. working without blocking interface or other tasks)
- Query based approach: all basic operations work, but no security limitations are implemented so far. We have a lot of ideas how to enforce security
- Dataview implemented. If the query is saved on the main process to be executed multiple times, it’s called dataview.
- Database reactivity for dataviews. Whenever data in database changes, the main process checks if dataview has changed and resends it if so.
We are carefully annotating our source code. To make sure that after the first public release those who want to audit, test or contribute to it, could easily do it.
Still there are a lot of work to be done:
[ ] Optimizing code
[ ] Refining APIs
[ ] Enforcing sequrity for database requests
[ ] Incremental update for database reactivity
[ ] Consistency checking for database reactivity update
[ ] Continue with developing account management
[ ] …