As already announced at the end of last year, Lisk SDK 5.0.0 and Lisk Core 3.0.0 have both successfully undergone an external security audit by Least Authority, a reputable security auditing company with a lot of experience in the blockchain industry. In this blog post, we want to share the motivation for the security audit, give more details on the overall audit process and explain the results given in the Security Audit Report by Least Authority.
Motivation for a Security Audit
Lisk SDK 5.0.0 and the upcoming mainnet release Lisk Core 3.0.0 mark a major milestone for the Lisk project. Apart from a large number of non-protocol improvements, 28 Lisk Improvement Proposals (LIPs) have been implemented as part of Lisk Core 3.0.0. We covered most of these in detail in the research blog post series last year and also summarized them here. Due to the large number of changes and our commitment to the highest security standards, it was important to us that the new Lisk protocol, Lisk SDK 5.0.0 and the upcoming mainnet release Lisk Core 3.0.0 are additionally reviewed as part of an external security audit.
A software security audit is a review of an implementation in order to check whether it adheres to security standards, best-practices and it satisfies the corresponding specifications and security claims. In particular, this includes looking for vulnerabilities or bugs in the software. For public blockchains such as Lisk, software security is of utmost importance as anyone can interact with the blockchain via sending transactions or forging blocks and therefore any vulnerability existing in the software can be easily exploited. The large monetary values involved in blockchains also provide a huge incentive for attackers to be constantly looking for vulnerabilities. For these reasons, independent security audits of major releases have become a common practice in the blockchain industry, and many auditing companies have been established specializing in blockchain-focused security audits.
With this in mind, we already started preparing for a security audit well before the completion of Lisk SDK 5.0.0 and Lisk Core 3.0.0. Having evaluated and talked with several companies specializing in blockchain security audits, the Lisk Foundation eventually decided to contract Least Authority due to their experience and strong team with diverse expertise. Their positive feedback and the audit result give confidence in our security standards, our research and development processes, and the next steps towards releasing Lisk Core 3.0.0 to the mainnet.
The first important part of the audit process was to clearly define the scope of the audit. For the security audit by Least Authority this was the Lisk protocol design and implementation:
- Lisk SDK 5.0.0: https://github.com/LiskHQ/lisk-sdk/tree/v5.0.0-alpha.3
- Lisk Core 3.0.0: https://github.com/LiskHQ/lisk-core/tree/v3.0.0-alpha.4
- Lisk Protocol:
Hence, the audit covered the full protocol and therefore all security-critical parts of the node software. This includes, for instance, the peer-to-peer layer, transaction pool, Lisk-BFT consensus algorithm, signature algorithm as well as the encoding and processing of transactions and blocks. You can find the detailed description of the scope in the Coverage section of the Security Audit Report.
Shortly after completing development of Lisk SDK 5.0.0 and Lisk Core 3.0.0, we had a meeting with Least Authority to kickstart the audit, discuss the scope and clarify the overall audit process. From then on, the security specialists from Least Authority were reviewing our documentation, specifications and code using a variety of security tools and techniques such as static code analysis, fuzz testing, security checks against dependencies or manual reviews. You can find more details about their approach and methodology in the audit report. During the whole review we were regularly communicating, answering any questions that came up and we already had the opportunity to directly address any findings they shared with us.
After five weeks of protocol and code review, we received an initial version of the audit report. We then thoroughly analyzed the documented findings and discussed them with Least Authority. For some of the findings we prepared a fix already before receiving the initial audit report. Regarding other findings, we eventually decided not to change the implementation, as we did not see them as a security issue and a change of implementation would have implied other disadvantages. For all the findings in the initial audit report we also drafted a detailed response that was also partly incorporated into the final published audit report. In the next section, we summarize the general feedback in the report and also explain the different findings. In particular, we want to give the reasons why we did or did not address the issues or suggestions given in the report.
The audit reported the overall high quality of the Lisk code base and complimented the Lisk project on following best practices in regards to security, software design and code writing. The Lisk team has always aimed to follow the highest standards in those areas and uses multiple tools to guarantee high code quality.
"The code is well-written and consistently follows industry best practices for TypeScript."
A very important part of any software project is documentation. As Blockchain is a relatively new field, this is especially true. Having a well-written documentation allows us to welcome new members into our community, either as node operators or sidechain developers. In that regard, the audit found our documentation to be well-written and covering all important aspects of our project.
"The documentation is comprehensive, helpful and accurate. We commend the Lisk team for providing thorough coverage of system design choices and the reasoning of the design decisions."
Simplicity and transparency are chief values in the development of the Lisk project. We aim to be open and communicate decisions in the clearest and most objective manner. The audit team complimented the documentation and LIPs in providing insight into the design choices. Lastly and maybe most importantly, the audit highlighted the strong security approach that we follow. The research team is working hard to propose protocol updates that are safe and ensure the security of the Lisk blockchain.
"We found the work of the Lisk team highly security-conscious: they had already anticipated several potential attacks and applied mitigations."
Specific Issues and Suggestions
In this section, we explain the three issues and two suggestions remarked in the audit report and our standpoint for each of them.
Issue A: Lisk-codec Unexpected Error
The first issue that was found regarded a problem with Lisk codec. The default encoding would assign an empty object to arrays when no valid element for the array was given, resulting in an invalid return value which was not handled by Lisk codec. Therefore, if the error was not handled properly by the function calling Lisk codec, it may have resulted in unwanted side effects. There was no direct security threat resulting from this issue in the SDK, and it was already fixed by the end of the security audit.
Issue B: Lisk-core CLI Mnemonic Encryption
The second issue focused on the password-based key derivation function used to create the encryption key for the mnemonic passphrase at the client side. For forging blocks, delegate nodes need access to the delegate's passphrase in order to sign the block. For security reasons, the passphrase is not stored on the hard disk in plain text, as otherwise anyone with access to the hard drive could easily steal it. Instead the passphrase is encrypted with a password that has to be entered by the node operator to forge. That is why Lisk Elements implements a function to encrypt the passphrase based on PBKDF2 and AES. PBKDF2 is a well-known scheme for password-based key derivation due to its key stretching properties.
As the audit report rightly points out, nowadays there are newer algorithms for this purpose that have better properties than PBKDF2. In particular, Argon2, which was the winner of the Password Hashing Competition a few years ago, has superior ASIC-resistant and memory-exhausting properties than PBKDF2. However, PBKDF2 is extensively used in many security-critical software, as for example 1Password. Moreover, for the attack described in the report to be possible, it is assumed the attacker has access to the encrypted passphrase, and even in this case, it would be infeasible to brute force it if the delegate node uses a strong password. Hence, after considering the pros and cons of the current scheme, we decided to continue supporting the PBKDF2 algorithm as the default scheme for deriving an encryption key in Lisk Elements.
That being said, the extra option of Argon2 together with PBKDF2 will definitely be a good thing to have for node operators and delegates. That is why we have added the support of this algorithm to the future tasks for our development team.
Issue C: Account Key Derivation
The third issue raised by the audit report concerned the account key derivation algorithm used in Lisk. This algorithm computes the private key for signing blocks and transactions from the passphrase provided by the user. The current method for deriving the private key of an account is to hash the passphrase using hash function SHA-256. The report pointed out that other key derivation methods like HKDF have better proven properties and recommended that the Lisk products use such an algorithm. The audit team also recommended that all users change their passphrase in case this algorithm change is implemented.
The report notes that the method currently used is not at risk from any known attacks and that modifying this process would be a breaking change. After having examined the proposed option, the Lisk team has decided to keep the current key derivation method. Changing the key derivation would imply that every Lisk user would need to generate a new passphrase and transfer all funds from the previous account to the new one. For backward compatibility, all Lisk wallets would also need to support both key derivation methods with the option to change between them. We considered that the loss of user experience and the risks in foregoing this migration outweighed the gains of the proposal.
On a technical note, third party wallets could implement a different key derivation mechanism and use HKDF as proposed by the audit report. However, such an implementation would not be compatible with the Lisk official wallet as it would generate a different private key for the same passphrase.
Suggestion 1: Correct Typos in Documentation
Least Authority found a few typos in our documentation which we promptly fixed.
Suggestion 2: Use a Separate Address Key and Signing Key
Finally, Least Authority suggested separating the key pair used to compute the address from the keys used to sign transactions or forge blocks. Currently, there is no distinction in the Lisk protocol between these two use cases, and if the keys are compromised the user has to create a new account to try to save their funds. To mitigate this, Least Authority suggested to use a new set of keys, along with the original public key, to sign transactions. The original private key is then used to sign a key revocation transaction, in case the new keys are compromised.
We carefully considered this suggestion and finally decided to not implement it at the time of responding to the security audit. We believe that the suggestion only brings an actual security gain if it does not greatly complicate the user experience. For instance, if normal users would have to handle multiple passphrases with different permissions as default, they may be overwhelmed by the complexity, lock themselves out of their accounts or just store all passphrases in the same place. Therefore, we prefer the current simple approach with one passphrase per account as default and the possibility of registering a multisignature account for extended security. Nevertheless, we are evaluating to introduce more advanced key management as a possible feature for the Lisk SDK.
In conclusion, the positive results of the security audit conducted by Least Authority demonstrate the high quality of our code base, which allows us to safely and securely release the upcoming Lisk Core 3.0.0 to the mainnet. Now that the security audit has been completed, the development continues on the Lisk SDK 5.1.0. One of the goals of this release is to add commands to generate a blockchain application template including modules, assets, plugins, configuration, and a genesis block in order to start developing a blockchain application. Another objective of this release is to add a dashboard plugin with the goal of providing developers with an integrated blockchain explorer, which allows users to list accounts, blocks, transactions. One other goal of this release is to add an application testing framework that will enable developers to test critical parts of their application. Therefore, as seen in the release goals, the Lisk SDK 5.1.0 release is coming with an improved developer experience.