<?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: Vulcanus</title>
    <description>The latest articles on DEV Community by Vulcanus (@vulcanus).</description>
    <link>https://dev.to/vulcanus</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%2F742357%2F7cfa1f44-ee53-4ac0-b2dd-49fdfea779a0.jpg</url>
      <title>DEV Community: Vulcanus</title>
      <link>https://dev.to/vulcanus</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vulcanus"/>
    <language>en</language>
    <item>
      <title>Why a High Code Coverage Is Nothing Worth and Leads Only to False Conclusions</title>
      <dc:creator>Vulcanus</dc:creator>
      <pubDate>Sun, 09 Jan 2022 00:04:30 +0000</pubDate>
      <link>https://dev.to/vulcanus/why-a-high-code-coverage-is-nothing-worth-and-leads-only-to-false-conclusions-48li</link>
      <guid>https://dev.to/vulcanus/why-a-high-code-coverage-is-nothing-worth-and-leads-only-to-false-conclusions-48li</guid>
      <description>&lt;p&gt;Code coverage shows the degree in percentage to which an application is executed by a testing framework. It is used for quality assurance and "helps" to increase quality of software.&lt;/p&gt;

&lt;p&gt;In this article I will demonstrate why code coverage will not help increasing quality, can be faked and what you can do instead to ensure quality.&lt;/p&gt;

&lt;p&gt;Most tools show the percentage of code coverage by the executed lines of code. Normally unit, integration and end to end tests help to increase the coverage, which means that by theory you have to write the test by yourself to get the code tested. But is that really the only way? Let's see if that is really the case with an C# example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;ConsoleApp1&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleClass&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;SimpleProperty&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;SimpleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"simple yes"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"simple no"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;SimpleMethod2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;SimpleMethod3&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have created a small class that has a property and three methods doing basic things. When a test is written for a class like this, it might look like in the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Test1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;SimpleClass&lt;/span&gt; &lt;span class="n"&gt;simpleClass&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SimpleClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;simpleClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SimpleMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"simple yes"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple test executes one method and asserts the output.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9r0x6zqow1utfk2tdu5.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9r0x6zqow1utfk2tdu5.PNG"&gt;&lt;/a&gt;&lt;br&gt;Code coverage of Test1
  &lt;/p&gt;

&lt;p&gt;There is a more complex way to "test" a class but it automates the execution of the methods which means that this code will automatically "test" other classes too. The code is very basic and more of an example. It should only help to show my point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Test2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Assembly&lt;/span&gt; &lt;span class="n"&gt;assembly&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ClassLibrary1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;objectTypes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;assembly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetTypes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;parameterInstances&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Dictionary&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;objectType&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;objectTypes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objectType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsClass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ConstructorInfo&lt;/span&gt; &lt;span class="n"&gt;objectConstructor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objectType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetConstructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EmptyTypes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;objectInstance&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objectConstructor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;methodInfos&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;objectType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetMethods&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;methodInfo&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;methodInfos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;parameterInfos&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;methodInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetParameters&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;methodParameters&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;();&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;parameterInfos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;parameterType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parameterInfos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;ParameterType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;parameterInstances&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ContainsKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameterType&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameterType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValueType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="n"&gt;parameterInstances&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameterType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;CreateValPossibilities&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameterType&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                        &lt;span class="k"&gt;else&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="n"&gt;parameterInstances&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameterType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;CreateRefPossibilities&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameterType&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="n"&gt;methodParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameterInstances&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;parameterType&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;parameterPermutations&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetAllPossibleCombinations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;methodParameters&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;parameterPermutation&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;parameterPermutations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;methodInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objectInstance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parameterPermutation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To explain what this code does with the power of &lt;a href="https://en.wikipedia.org/wiki/Reflective_programming" rel="noopener noreferrer"&gt;reflections&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It loads the "ClassLibrary1" assembly and collects all types it contains&lt;/li&gt;
&lt;li&gt;It iterates through the type collection and creates an instance of the ones being a class&lt;/li&gt;
&lt;li&gt;It iterates through the methods of that class, creates parameters with specific values of certain types and creates a list of permutations to pass them to those methods for execution (working kind of like a &lt;a href="https://en.wikipedia.org/wiki/Fuzzing" rel="noopener noreferrer"&gt;Fuzzer&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Guess the code coverage of &lt;em&gt;SimpleClass&lt;/em&gt; …&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyia5d7zkcqhc3vkej97d.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyia5d7zkcqhc3vkej97d.PNG"&gt;&lt;/a&gt;&lt;br&gt;Code coverage of Test2
  &lt;/p&gt;

&lt;p&gt;This code sample will not be able to execute every code line in other scenarios since there are branches you can not cover that simply. Sure you can tailor the code to have some higher degree of line coverage, but this does not enhance quality. By theory we now have achieved "quality" when reading this KPI. Executing code without real context to just execute it does not make any sense. But what should you strive for instead?&lt;/p&gt;

&lt;p&gt;Context! We need context to know about the environment, the users, the input and the processes. To explain you, why we need context, let's make an example with &lt;em&gt;SimpleClass&lt;/em&gt; and have a look on &lt;em&gt;SimpleMethod2&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;SimpleMethod2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method takes as parameter a string and returns the length of it. When executing a test with a string, we covered the complete method and reached 100% here. Cool? Well, when you look more closely, you will notice it. Do we really ensure "quality"?&lt;/p&gt;

&lt;p&gt;The int here is a Int32 &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/struct" rel="noopener noreferrer"&gt;struct&lt;/a&gt; where the lowest possible value is &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.int32.minvalue?view=net-6.0" rel="noopener noreferrer"&gt;-2147483648&lt;/a&gt; and the highest &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.int32.maxvalue?view=net-6.0" rel="noopener noreferrer"&gt;2147483647&lt;/a&gt;. Since the Length property of string is a type of  Int32 the theoretical length of a string is the highest possible value of Int32. Practically you will not really reach this number even close since the Common Language Runtime (CLR) limits the size of single objects by 2GB (well, you could in fact change that in the &lt;a href="https://docs.microsoft.com/en-us/dotnet/core/run-time-config/garbage-collector#allow-large-objects" rel="noopener noreferrer"&gt;config&lt;/a&gt; but normally there is no reason for that). By default a string uses UTF-16 which needs two bytes for a single character and in fact this means you probably reach a length of 1073741823. &lt;br&gt;
Ok, the length of the string will not cause any problems but what can? Strings are reference types which means we have the power of null! When the parameter is null, the code will crash.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fproohp4o3tr7g1x57uj8.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fproohp4o3tr7g1x57uj8.PNG"&gt;&lt;/a&gt;&lt;br&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/api/system.nullreferenceexception?view=net-6.0" rel="noopener noreferrer"&gt;NullReferenceException&lt;/a&gt;
  &lt;/p&gt;

&lt;p&gt;My point? Exactly this. Even though we have a high code coverage in this method, we still have the possibility that the application crashes. &lt;br&gt;
We need context to understand what can happen and model our test cases that way. Instead of caring much about the code coverage KPI, we should cover the different &lt;a href="https://en.wikipedia.org/wiki/Use_case" rel="noopener noreferrer"&gt;use cases&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Misuse_case" rel="noopener noreferrer"&gt;misuse cases&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fufvz0fptu7cwlnu9j6ur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fufvz0fptu7cwlnu9j6ur.png"&gt;&lt;/a&gt;&lt;br&gt;&lt;a href="https://commons.wikimedia.org/wiki/File:Misuse_restaurant_model.svg" rel="noopener noreferrer"&gt;Use case and misuse case combined&lt;/a&gt;
  &lt;/p&gt;

&lt;p&gt;Shortly explained, while a use case defines the interactions between an actor and a system that contains a set of steps to accomplish a certain goal, does the misuse case describe the process of malicious acts against a system. But how can we ensure quality with context?&lt;/p&gt;

&lt;p&gt;We have to take one step back and define what quality is and what quality characteristics are going to be needed to ensure "quality."&lt;br&gt;
Quality is conditional, subjective and is understood differently by different people. While a consumer focuses on &lt;a href="https://en.wikipedia.org/wiki/Acceptance_testing" rel="noopener noreferrer"&gt;specification quality&lt;/a&gt;, producers have &lt;a href="https://en.wikipedia.org/wiki/Conformance_testing" rel="noopener noreferrer"&gt;conformance quality&lt;/a&gt; in mind. Knowing the different focus of each group, we can dig deeper more specifically. To do this we can use the quality models defined in &lt;a href="https://www.iso.org/obp/ui/#iso:std:iso-iec:25010:ed-1:v1:en" rel="noopener noreferrer"&gt;ISO 25010&lt;/a&gt; which is part of the 25000 series also known as SQuaRE (Systems and software Quality Requirements and Evaluation).&lt;br&gt;
The first model is quality in use. It shows how the product meets the needs of the users to achieve specific goals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbkhe1vicvjh5l1y2su3p.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbkhe1vicvjh5l1y2su3p.PNG"&gt;&lt;/a&gt;&lt;br&gt;Quality In Use model
  &lt;/p&gt;

&lt;p&gt;The second one is product quality and consists of eight characteristics which are composed of sub characteristics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9u4f1ihxoryjuxlcism6.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9u4f1ihxoryjuxlcism6.PNG"&gt;&lt;/a&gt;&lt;br&gt;System/Software Product Quality model
  &lt;/p&gt;

&lt;p&gt;Knowing now these quality models helps to see the usage and the product through different perspectives. With those characteristics in mind, we can enhance the requirements and refine them to be more specific about the needs. Now together with the use cases and misuse cases, we can test the code against different scenarios and functional as well as non-functional requirements. Knowing the different scenarios allows you also to build your own KPIs. With a high context coverage, you will also inherently reach a high code coverage, but this does not work the other way around.&lt;/p&gt;

&lt;p&gt;Testing your code automatically is important and working with effective KPIs helps you to focus on blind spots. Some KPIs are more effective than others so keep in mind what data is collected and processed to display you the result since a KPI can lead to false conclusions.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>testing</category>
      <category>codequality</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Critical Security Areas That Software Engineers Have To Know To Secure Their Solutions</title>
      <dc:creator>Vulcanus</dc:creator>
      <pubDate>Sat, 01 Jan 2022 12:44:16 +0000</pubDate>
      <link>https://dev.to/vulcanus/critical-security-areas-that-software-engineers-have-to-know-to-secure-their-solutions-3pkc</link>
      <guid>https://dev.to/vulcanus/critical-security-areas-that-software-engineers-have-to-know-to-secure-their-solutions-3pkc</guid>
      <description>&lt;p&gt;Societies in industrialized countries depend more and more on software. The rising impact of cyber-physical systems on the real world as well as the amount of personally identifiable information collected and processed shows that systems must be secure. This is not easy to achieve due to rising complexity of those systems.&lt;/p&gt;

&lt;p&gt;Organizations have information security departments that support securing business functions and train employees in a variety of security topics to show how to react on certain events and how to handle classified information. While there are trainings for administrators to show them how to secure a system, often little to none effort is put into teaching software engineers and developers on how to develop a secure software solution. This is quite a big issue I'd like to address and raise awareness about.&lt;/p&gt;

&lt;p&gt;The Open Web Application Security Project (OWASP) created the "&lt;a href="https://owasp.org/www-project-proactive-controls/" rel="noopener noreferrer"&gt;OWASP TOP 10 Proactive Controls project (OPC)&lt;/a&gt;" to encourage developers starting with application security. This blog entry summarizes the content of it and adds hints and information to it too. Please keep in mind that this should only raise awareness and is a starting point to help get deeper into this topic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define Security Requirements
&lt;/h2&gt;

&lt;p&gt;Security falls under the category non-functional requirements. It should define the needed security functionality the software has to satisfy. To save up time and not re-invent the wheel on each new project, you can select security requirements from a catalog. There is a general one called "&lt;a href="https://owasp.org/www-project-application-security-verification-standard/" rel="noopener noreferrer"&gt;Application Security Verification Standard (ASVS)&lt;/a&gt;" and one for the mobile named "&lt;a href="https://github.com/OWASP/owasp-masvs" rel="noopener noreferrer"&gt;Mobile Application Verification Standard (MASVS)&lt;/a&gt;". They contain a collection of requirements which are best practices for each listed category. Fortunately they have mapped those requirements with CWE (common weakness enumeration which is basically a list of software and hardware weaknesses). Depending on the used tools, those CWEs can be automatically scanned in your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leverage Security Frameworks and Libraries
&lt;/h2&gt;

&lt;p&gt;Normally third-party libraries/frameworks are included into the project to re-use already written code. You should only use those from trusted sources, which are actively maintained and used by many applications. Keep them up to date and encapsulate the library, so you only expose the required need into your software. There are quite some dependency checkers out there to help you select dependencies and keep them up to date.&lt;/p&gt;

&lt;h2&gt;
  
  
  Secure Database Access
&lt;/h2&gt;

&lt;p&gt;This has some subitems, but we'll go through them quite quickly. Secure your queries. We all know those funny SQL injection jokes, but you can solve this problem quite easily with query parameterization. You can find a cheat sheet from OWASP &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Query_Parameterization_Cheat_Sheet.html" rel="noopener noreferrer"&gt;here&lt;/a&gt; and another one from Bobby Tables &lt;a href="https://bobby-tables.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
Database management systems are not always "secure by default" configured. There are guidelines and benchmarks available out there which you should check out like &lt;a href="https://www.cisecurity.org/cis-benchmarks/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
Access to the database should be properly authenticated. This should take place over a secure channel, and your credentials should be properly secured. Besides authenticating with credentials, you should also check out if it's possible to access it instead with your managed identity.&lt;br&gt;
The last point is secure communication. Encrypting your data in transit by having a end-to-end communication security when sensitive data is transmitted over any network. This can be done via TLS. There are guides there helping you choose the minimum allowed TLS version and choosing a cipher suite.&lt;/p&gt;
&lt;h2&gt;
  
  
  Encode And Escape Data
&lt;/h2&gt;

&lt;p&gt;And here we reach injection attacks again. By encoding characters we ensure that special characters are not processed for malicious intends. This means that the content will be displayed but not executed. For example, instead of sending &lt;code&gt;"&amp;lt;script&amp;gt;"&lt;/code&gt; we encode special characters inputted by the user and send &lt;code&gt;"&amp;amp;lt;script&amp;amp;gt;"&lt;/code&gt; which will be displayed on the browser like &lt;code&gt;"&amp;lt;script&amp;gt;"&lt;/code&gt; but will not be executed. This output encoding should be applied before the content is passed to the target interpreter, to defend against XSS. There are some examples for &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/security/cross-site-scripting" rel="noopener noreferrer"&gt;C#&lt;/a&gt;, &lt;a href="https://owasp.org/www-project-java-encoder/" rel="noopener noreferrer"&gt;Java&lt;/a&gt; and &lt;a href="https://github.com/zendframework/zend-escaper" rel="noopener noreferrer"&gt;PHP&lt;/a&gt;. There are also other types of encoding and injection defenses like "shell escaping" for os command input. Forms of escaping are not limited to those examples listed here. Look for guidelines and best practices when using user input for certain operations.&lt;/p&gt;
&lt;h2&gt;
  
  
  Validate All Inputs
&lt;/h2&gt;

&lt;p&gt;You might have already noticed that you can't trust input from clients which means that the data has to be validated before usage.&lt;/p&gt;


  &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnux3sea4j58pmp9lue9g.png"&gt;&lt;a href="https://xkcd.com/327/" rel="noopener noreferrer"&gt;Exploits of a Mom&lt;/a&gt;
  


&lt;p&gt;Data should be checked that its syntax and semantic is valid. &lt;br&gt;
Syntax validity ensures that data are in a expected form and should not allow any deviations. If three digits are expected, it should be checked that the input consists only of digits and has three digits in length.&lt;br&gt;
Semantic validity accepts input only in an acceptable range specified by the applications functionality and its context. For example a start date has to be before an end date.&lt;/p&gt;

&lt;p&gt;Those validations can be performed both on the client and server side, but security related validations always have to be done on the server side, since the validation on client side can be bypassed.&lt;/p&gt;

&lt;p&gt;There are in general two approaches for syntax validation: blacklisting and whitelisting. While blacklisting blocks exact texts (e.g. &lt;code&gt;"&amp;lt;script&amp;gt;"&lt;/code&gt;) to prevent injections, is whitelisting checking for data set matches. In general it is recommended to use whitelisting on a minimal approach, instead of blacklisting since it is prone to bypasses. In other words, whitelisting limits attack surface, while blacklisting detects and stops obvious attacks.&lt;br&gt;
Bear in mind that those validations have limits. Since complexity allows more variations and posibilities, valid data cann still be dangerous.&lt;/p&gt;

&lt;p&gt;Another way to check whether data matches a specific pattern is the usage of &lt;a href="https://en.wikipedia.org/wiki/Regular_expression" rel="noopener noreferrer"&gt;regular expressions&lt;/a&gt;. This should be used with caution since expressions can get quite complex as well as hard to maintain. It also enables a &lt;a href="https://en.wikipedia.org/wiki/ReDoS" rel="noopener noreferrer"&gt;regular expression denial of service attack&lt;/a&gt; (ReDOS) which produces a denial of service due to the exploitation of the exponential time worst-case scenario.&lt;/p&gt;

&lt;p&gt;There are plenty validation libraries that can be leveraged to validate data. PHP has &lt;a href="https://www.w3schools.com/php/php_ref_filter.asp" rel="noopener noreferrer"&gt;filter functions&lt;/a&gt;, and Java has the &lt;a href="https://hibernate.org/validator/" rel="noopener noreferrer"&gt;Hibernate Validator&lt;/a&gt; and C# the &lt;a href="https://github.com/FluentValidation/FluentValidation" rel="noopener noreferrer"&gt;FluentValidation&lt;/a&gt;. You can also sanitize your data to erase not needed data in your input. Please keep in mind that input validation should not be your primary method to prevent injections and other attacks.&lt;/p&gt;

&lt;p&gt;Another problem you might encounter is the validation of serialized data. &lt;a href="https://owasp.org/www-project-top-ten/2017/A8_2017-Insecure_Deserialization" rel="noopener noreferrer"&gt;Avoid deserializing data from untrusted sources&lt;/a&gt;. If this is not possible, you might want to implement integrity checks or encryption to prevent tampering. Enforce strict type constraints and possibly run code in a low privilege environment like in a temporary container to deserialize data. Log exceptions and failures such as the not expecting  incoming type or failure in deserialization.&lt;/p&gt;

&lt;p&gt;Apart from serialized data, there is also the problem with autobinding. Some frameworks support automatic binding of HTTP request parameters to server-side objects consumed by the application. Those bindings enable an attack vector to exploit a vulnerability called "Mass assignment". For example the user can set a parameter like "isAdmin" to true to elevate privileges. There are two ways to handle this, by either avoid autobinding and use Data Transfer Objects (TDOs) which are basically POCOs, or setup whitelist rules to define which fields are allowed to be auto-bound. There is a cheat sheet by OWASP you might to check out &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html" rel="noopener noreferrer"&gt;here&lt;/a&gt; to get more information on how to resolve this issue.&lt;/p&gt;
&lt;h2&gt;
  
  
  Enforce Access Controls
&lt;/h2&gt;

&lt;p&gt;Access Controls manages the access to systems as well as resources and ensures that only authorized users/systems have access. It should be forced that all requests go through the access control to ensure that every request is checked and authorized to pass. You may already come across of the terms privilege, right and permission. Those are not interchangeable terms! For more information, read Wentz Wus &lt;a href="https://wentzwu.com/2020/07/21/privileges-rights-permissions/" rel="noopener noreferrer"&gt;article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This topic should be thoroughly designed up front and taken early into account in the designing phase.&lt;br&gt;
There are different types of access controls that should be considered (but not limited to):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Discretionary_access_control" rel="noopener noreferrer"&gt;Discretionary Access Control&lt;/a&gt; (DAC): lets people manage content by their own.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Mandatory_access_control" rel="noopener noreferrer"&gt;Mandatory Access Control&lt;/a&gt; (MAC): restricts access based on sensitivity (by a label) of the information and the authorization of the user to access such sensitivity.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Role-based_access_control" rel="noopener noreferrer"&gt;Role Based Access Control&lt;/a&gt; (RBAC): controls access to resources based on defined rules. Performed actions are identified with roles rather than with individual subject identities.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Attribute-based_access_control" rel="noopener noreferrer"&gt;Attribute Based Access Control&lt;/a&gt; (ABAC) manages the request based on policies which combines attributes of the user and object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are two principles that you should embed when using access controls. The first is deny by default. This means that if a request is not specifically allowed it must be denied. The second is the principle of least privilege. Ensure that only the least and only necessary access is possible. Often when time passes, it can happen that &lt;a href="https://www.techtarget.com/searchsecurity/definition/privilege-creep" rel="noopener noreferrer"&gt;privilege creep&lt;/a&gt; occurs. This means that an identity accumulated access rights and has higher privileges than necessary, so keep that in mind and check regularly if certain permissions and rights are needed.&lt;/p&gt;

&lt;p&gt;Linked to a granular access control is the programmed check of permissions. Many applications use access controls that are role based. This limits the developers and adds dangers to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SuperUser"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Admin"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;doAction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead your should implement rights and check for them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasRight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RightX"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;doAction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, you don't need to re-deploy everything if new roles are added that should have the privilege to perform actions and it is easier to maintain. It also enables for a more granular access control which helps administrators to configure the system more securely.&lt;/p&gt;

&lt;p&gt;Furthermore, you should ensure that all access control failures should be logged to ensure &lt;a href="https://en.wikipedia.org/wiki/Non-repudiation" rel="noopener noreferrer"&gt;non-repudiation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Protection
&lt;/h2&gt;

&lt;p&gt;Data can contain sensitive information which requires more protection, since it may fall under laws and regulations. It is important to classify data in your system to determine sensitivity. Depending on those classifications it may also add security requirements to the system/infrastructure that collects, processes or stores this data.&lt;/p&gt;

&lt;p&gt;Data can be in three states. At rest, in transit or in use. Depending on the classification you have to secure the data in each state to avoid information disclosure.&lt;/p&gt;

&lt;p&gt;Application secrets should never be stored in code, configs or other files. Keep them in a secret vault like Azure KeyVault or Amazon KMS. Besides security this also gives more flexibility on configuring your solution.&lt;/p&gt;

&lt;p&gt;I would like to add here to also think about &lt;a href="https://en.wikipedia.org/wiki/Data_retention" rel="noopener noreferrer"&gt;data retention&lt;/a&gt; as well as backup strategies. For data retention you have to keep laws and regulations in mind. Consult with a specialist or lawyer to know what the requirements are. &lt;/p&gt;

&lt;p&gt;Backup strategies should not only be planned and executed, but also the results tested. There is a saying that you do not have a backup when you did not test it. In the end, you do not want to be on several tech blogs because of some &lt;a href="https://techcrunch.com/2017/02/01/gitlab-suffers-major-backup-failure-after-data-deletion-incident/" rel="noopener noreferrer"&gt;deletion incident and backup failure like GitLab&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implement Security Logging and Monitoring
&lt;/h2&gt;

&lt;p&gt;The concept of Security logging is to log security information during runtime. It can be used for forensic analysis and investigations, as well as satisfying regulatory compliance requests. Monitoring is the live review of logs using various forms of automation.&lt;/p&gt;

&lt;p&gt;Logging solutions must be designed, build and managed in a secure way. Encode and validate dangerous characters before logging to prevent &lt;a href="https://owasp.org/www-community/attacks/Log_Injection" rel="noopener noreferrer"&gt;injections or forging attacks&lt;/a&gt;. Ensure log integrity to protect against tampering. When logging, remove any sensitive information to avoid information disclosure. There should also be a common logging format to be consistent. Keep also an eye on time syncing across systems to have consistent timestamps in your logs. Furthermore, you should forward logs to a central, secure logging service to allow centralized monitoring and securing log data.&lt;/p&gt;

&lt;p&gt;To identify potentially malicious activties, following activies can be logged as high severity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Submitted data that is outside of an expected range&lt;/li&gt;
&lt;li&gt;Submitted data that contains changes that should not be modifiable&lt;/li&gt;
&lt;li&gt;Requests violating access control rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a more comprehensive list, check out OWASPs AppSensor Detection_points tab here.&lt;br&gt;
When encountering those activties, the application should respond to possible attacks and shut them down.&lt;/p&gt;

&lt;p&gt;There is also a small cheat sheet related to application security logging here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handle all Errors and Exceptions
&lt;/h2&gt;

&lt;p&gt;Exceptions can happen in various ways and should be handled accordingly. This handling occurs in all areas of the application including business logic and security features. It is also important for intrusion detection. Certain attacks against the application may trigger errors which can help detect attacks in progress.&lt;/p&gt;

&lt;p&gt;Manage exceptions in a centralized manner to avoid duplicated try/catch blocks and ensure all unexpected behavior is correctly handled. When displaying the error message to the user, be sure that you do not leak any critical information but still provide enough information to respond properly.&lt;br&gt;
When logging error messages, provide enough information so that the support, forensics and incident response teams understand the problem.&lt;/p&gt;

&lt;p&gt;To help discover possible failures early, you can also use Netflix's &lt;a href="https://github.com/netflix/chaosmonkey" rel="noopener noreferrer"&gt;Chaos Monkey&lt;/a&gt;. It randomly terminates VMs and containers to show how resilient your services are.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some more Information
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Code Review
&lt;/h3&gt;

&lt;p&gt;Besides the mentioned areas, you should also have a look at OWASP's &lt;a href="https://owasp.org/www-project-code-review-guide/" rel="noopener noreferrer"&gt;Code Review Guide&lt;/a&gt;. It is quite comprehensive but also raises awareness on different topics, containing code examples and figures to illustrate in an easy way to show what has to be considered when reviewing code besides clean code practices and business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do not write your own encryption
&lt;/h3&gt;

&lt;p&gt;Some developers are tempted to rollout their own encryption. &lt;a href="https://www.schneier.com/blog/archives/2011/04/schneiers_law.html" rel="noopener noreferrer"&gt;Schneir's Law&lt;/a&gt; states&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Anyone, from the most clueless amateur to the best cryptographer, can create an algorithm that he himself can't break.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since those persons believe that they can not break their cipher, they use it as evidence that it is unbreakable. This is a good example of the &lt;a href="https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect" rel="noopener noreferrer"&gt;Dunning-Kruger effect&lt;/a&gt;. There is a &lt;a href="https://crypto.stackexchange.com/questions/43272/why-is-writing-your-own-encryption-discouraged" rel="noopener noreferrer"&gt;discussion&lt;/a&gt; on why it is discouraged to write your own encryption on Stack Exchange.&lt;br&gt;
Therefore use existing solutions that are recognized by the industry and follow their best practices.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>security</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
