Title | Author | Date | FIle | |
---|---|---|---|---|
Decentralized Digital Identity Model |
Alberto Ballesteros Rodríguez |
August 2018 |
ballesterosbr@protonmail.com |
Avoiding Common Attacks |
- Race Conditions
- Transaction-Ordering Dependence (TOP) /Front Running
- Timestamp Dependence
- Integer Overflow and Underflow
- DoS with (Unexpected) revert
- DoS with Block Gas Limit
- Forcibly Sending Ether to a Contract
- Recommendations
The design of the smart contracts of this project doesn't use any Ether.
Race conditions can occur across multiple functions and contracts. It's recommended finishing all internal work first.
To prevent that a function could be called repeatedly, like our "newIdentity()" function. The function set one value to the User struct that is checked at the beginning of the function, only allowing to create one PersonalIdentity contract.
Without setting the value of the Struct before the creation of the new contract, the call would be vulnerable to a race condition.
Another possible similar attack exist when two different functions share the same state.
In this project there are no functions that share the same state.
The alteration of the order of the transactions, as the documentation shows, it's more critical to decentralized markets. In this project require conditions are enough.
Frontend is designed in such a way that it's not possible to alter the order of the Identity attributes, even at the time to update those attributes.
It's known that the that the timestamp of the block can be manipulated by the miner.
In this project the timestamp is only used to show the user a date when the Identity has been created. So, is nothing critical, only a simple parameter used in events that doesn't affect the use of the application.
The user is enough smart to know that if the timestamp does not match with the creation date of the Identity, it has been manipulated but this won't affect the use of the application.
If a balance reaches the maximum uint value (2^256) it will circle back to zero. This checks for that condition
In this project, uint are used to access to the array index where the attributes are stored (getters). It's not necessary to implement a Math Library because the implementation used in the project is really simple.
The require conditions test that the uint value introduced exist and if not, it will fail.
In this project there isn't an implementation of a "leader" system. In this project there aren't loops.
Even though a dynamic array is used in this project, is not necessary to loop over it. Getter will handle the access to the array information.
In this project there is not a fallback function. The code does not need to make calculations based on the contract's balance.
The DApp developed in the project manage information that can be considered sensitive.
Now, you can find what solution has been proposed to make the sending of information more secure despite the public nature of the blockchain.
As commented before, this DApp manage information about the users.
To protect this information, in the client side has been implemented the node.js Crypto module.
Before the user can push his information to the blockchain, is necessary to encrypt the attributes of the Identity using a password.
Some rules have been set for password, based on brute force attacks protection:
- Contain at least one number
- Contain at least one lower case
- Contain at least one upper case
- Contain at least 10 characters
This password is used to cipher and decipher the information. To protect the password is used Keccak256.
The algorithm used is the AES-256. If the algorithm were cracked, the application can use another one. All the process is transparent for the user. To better understand:
encryptedValue = AES256(keccak256(password), value)
This is not a project related with strong security fundamentals, so I considered AES-256 enough for this purpose.
To input validation. In all the code you will find require conditions that use a library created (Library.sol
) to test the input values.
To make clear who can call the functions or access to a variable, all the functions and state variables are marked.
For security, the pragma is locked to the last release of Solidity version: 0.4.24.
The pragma of the Library float because could be used for other developers.
For functions, always start with the action: new, delete, update, get, enable, remove...
For events, always start with the object: Identity or Data.
All functions that requires, use msg.sender. Avoided to use tx.origin.