<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tomasz Kopacki</title>
    <description>The latest articles on DEV Community by Tomasz Kopacki (@0xtko).</description>
    <link>https://dev.to/0xtko</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F282607%2F766fadca-61b4-4e72-92c3-db81716c94de.jpg</url>
      <title>DEV Community: Tomasz Kopacki</title>
      <link>https://dev.to/0xtko</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/0xtko"/>
    <language>en</language>
    <item>
      <title>Parse, don't validate — correctness in smart contract development</title>
      <dc:creator>Tomasz Kopacki</dc:creator>
      <pubDate>Mon, 05 Dec 2022 09:40:53 +0000</pubDate>
      <link>https://dev.to/0xtko/parse-dont-validate-correctness-in-smart-contract-development-1h5f</link>
      <guid>https://dev.to/0xtko/parse-dont-validate-correctness-in-smart-contract-development-1h5f</guid>
      <description>&lt;p&gt;Just couple of days ago, there was a discussion on the &lt;a href="https://rib.rs/"&gt;Rust in Blockchain&lt;/a&gt; group. It was about another smart contract exploited by a hacker. Some missing role checks allowed arbitrary token minting.&lt;/p&gt;

&lt;p&gt;I've been a software engineer for multiple years, and I know that it's easy to forget about an important line in the code.&lt;/p&gt;

&lt;p&gt;However, there are techniques which make it harder to forget! That's what, dear reader, I'd like you share with you about 🙃&lt;/p&gt;

&lt;h2&gt;
  
  
  Ensuring input correctness
&lt;/h2&gt;

&lt;p&gt;Accepting input from outside world requires checking if this input is actually what we need it to be. There is one common way of achieving this. It's called &lt;em&gt;validation&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validation
&lt;/h3&gt;

&lt;p&gt;It is about taking the input and checking if it &lt;em&gt;does include&lt;/em&gt; expected values and &lt;em&gt;does not include&lt;/em&gt; harmful values.&lt;/p&gt;

&lt;p&gt;If the check is successful, the input is considered valid by the internal part of our system. Otherwise, the input is rejected as invalid and is not further processed.&lt;/p&gt;

&lt;p&gt;However, validation does not require using new types to capture information about the input correctness. &lt;/p&gt;

&lt;p&gt;Have a glance at &lt;a href="https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2021&amp;amp;gist=0b85758a7eb9ef3a91f63b01749c1d8b"&gt;this Rust playground example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It is covered by unit tests, which definitely help, but the same &lt;code&gt;Addr&lt;/code&gt; type is shared by both, the valid and invalid address. That's where the real danger is! 🙊&lt;/p&gt;

&lt;p&gt;What can be done to make a mistake even harder to make? We can use... types!&lt;/p&gt;

&lt;h3&gt;
  
  
  Parse, don't validate
&lt;/h3&gt;

&lt;p&gt;I'll start by linking to &lt;a href="https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/"&gt;an awesome article by Alexis King&lt;/a&gt; which   includes all details about this technique.&lt;/p&gt;

&lt;p&gt;In short, we want to parse an input into a known set of internal types. These internal types can only be constructed via functions that include validation.&lt;/p&gt;

&lt;p&gt;The main difference is creating a wrapping type for a given valid value. Now, the valid admin address can be expressed by using the &lt;code&gt;AdminAddr&lt;/code&gt;. All other addresses are still expressed with our basic &lt;code&gt;Addr&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;Take a look at &lt;a href="https://play.rust-lang.org/?version=stable&amp;amp;mode=debug&amp;amp;edition=2021&amp;amp;gist=108a50a21930cab90043d22ee51f8177"&gt;the playground here&lt;/a&gt; — it's a modification of the previous code example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;p&gt;According to the &lt;a href="https://www.cybersaint.io/blog/nist-cybersecurity-framework-core-explained"&gt;NIST Cybersecurity Framework&lt;/a&gt;, there are five main areas of focus: Identify, Protect, Detect, Respond, and Recover.&lt;/p&gt;

&lt;p&gt;A simple technique like using types to ensure software correctness can be helpful with the following security areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify

&lt;ul&gt;
&lt;li&gt;assessing risk is easier if values can carry information about their own correctness&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Protect

&lt;ul&gt;
&lt;li&gt;it's harder to forget using a correct type in an authenticated method [1]
&lt;/li&gt;
&lt;li&gt;the compiler helps with catching the mistakes 🚀&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;All in all, mistakes are unavoidable. They are part of the risk. Keep in mind:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The risk can't be avoided — it has to be managed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Strong types are one of the ways to manage risk in software development. Smart contracts included.&lt;/p&gt;




&lt;ol&gt;
&lt;li&gt;
&lt;a id="auth-ref-link" href="https://www.nicholashairs.com/posts/musings-on-auth-definitions/"&gt;Musings on Auth: Definitions&lt;/a&gt; by Nicholas Hairs&lt;/li&gt;
&lt;/ol&gt; 

</description>
      <category>rust</category>
      <category>security</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
