#4 Authentication and Authorization

Xuntos
Building a Dapp on Ethereum
4 min readSep 7, 2018

--

In our last blog(#3 Loading a smart contract in a smart way in Nethereum) we discussed loading data using the example of a person with a name, street name and house number. If were to actually save personal data on an Ethereum blockchain we would have to make it secure. We would need the ability to protect parts or the entirety of of our Dapp from intruders and snoopers. We need authentication and authorization.

The problem we need to solve stems from the fact that our blockchain, though private, is not secured by itself. If someone has the address and ABI (Application Binary Interface) of a contract, they can call all functions on said contract. Therefore anyone would be able to get all the personal data stored on the blockchain. Obviously this is not desirable, thus we need to create a system that allows and disallows users access to pieces of data.

Since the communication with an Ethereum blockchain happens through a client, in our case Geth, we won’t have control over how the blockchain is accessed. The main reason is the fact that we cannot stop an attacker from accessing our blockchain directly with an Ethereum client, completely bypassing our C# application. Seeing that we cannot make sure that a function call received on a smart contract stems from our application, sorting out authentication and authorization in our web app is out of the question. As the movie Inception stated: “We need to go deeper”.

We followed our first intuition and looked into using Ethereum’s own account system for authentication and build an authorization system that uses the account address of the user. The account address that is sending a transaction or a call is readily available inside every function in Solidity, so that looks promising. However when we worked this out further we found out that the address is the only data about the user that is sent to the contract. Which makes it so that you need to check it against something in which the authorization is stored. This can be within the contract itself. Which is actually a viable option if the Dapp is small, but it becomes problematic when the amount of data grows. Needing to set permissions per user per contract quickly becomes undoable, especially if take the time to mine the transactions setting the permissions into account.

Having the check in another contract seems to have it’s merits, in that contract you can assign roles to addresses and with that check whether a user has the required role to access the data. Then again we couldn’t figure out how to make this work, due to the fact that the address of the contract that stores the roles needs to be known in the contract that stores the data. We thought of three ways this can be made available, two of which are inflexible and the other is insecure. Firstly you could just set the address of the authorization contract in stone and write it in the solidity code. However if for some reason you need to change to a new authorization contract, everything breaks. The same happens when you make it a read only state variable that is set in the constructor of the contract. The last method, giving the contract the address for the authorization in the function parameters is very insecure. An attacker only needs to be able to push a new authorization contract on the blockchain and he can authorize himself for anything.

The problems stated in the paragraph above also applied to our second attempt at an authentication and authorization system. However we want to explain it and some further problems with it anyway. Our second system involved creating a complete user authentication system within smart contracts. So an user could be authenticated and authorized by username and password all stored within the blockchain. Other than the already mentioned problems we encountered the gaslimit on our blockchain with this system.

The amount of gas needed for this system

To securely hash and salt passwords, check whether a user already exists when creating and a login system was so gas intensive that our gaslimit of 100,000,000,000 (100 billion) wasn’t enough to properly execute all the tasks needed.

Our last option was DS-Auth and DS-Roles from the DappSys pack by Dapphub.com

This again looked promising role checking without the high amount of gas needed. However this had many of the same problems that arose with the other methods. Either we needed to set permissions on a per contract level or we needed to somehow securely pass the contract that can check the permissions. Also a dead end.

Since our application needs the security of authorization with Ethereum we are currently at an impasse. These three options showed some flaws we were not able to overcome ourselves. So we’re asking our readers to reach out to us. Have you figured this out in a multi contract situation? If so, how? Please let us know in the comments because that would give us the possibility to advance the development of our Dapp with huge strides!

Also if you finally read why authorization in bigger Dapps is hard or found this post in any way useful, give us a clap!

--

--