<?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: Syed Mohammad Ibrahim</title>
    <description>The latest articles on DEV Community by Syed Mohammad Ibrahim (@iamibi).</description>
    <link>https://dev.to/iamibi</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%2F827671%2Fe5eaed89-3acc-4ef3-923c-9e5fa8fb841c.png</url>
      <title>DEV Community: Syed Mohammad Ibrahim</title>
      <link>https://dev.to/iamibi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iamibi"/>
    <language>en</language>
    <item>
      <title>Code Review Exercises That Actually Work: Python Edition (Junior to Senior)</title>
      <dc:creator>Syed Mohammad Ibrahim</dc:creator>
      <pubDate>Thu, 08 May 2025 15:00:00 +0000</pubDate>
      <link>https://dev.to/iamibi/code-review-exercises-that-actually-work-python-edition-junior-to-senior-57kf</link>
      <guid>https://dev.to/iamibi/code-review-exercises-that-actually-work-python-edition-junior-to-senior-57kf</guid>
      <description>&lt;p&gt;In the last post, we focused on Java and how to evaluate code review skills across different levels of engineering experience. In this post, we shift gears to &lt;strong&gt;Python&lt;/strong&gt;, a language known for its simplicity—and sometimes the unintended complexity that follows.&lt;/p&gt;

&lt;p&gt;This post includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;Python code review style guide&lt;/strong&gt; to share with candidates
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Three code review examples&lt;/strong&gt; (junior, mid, and senior)
&lt;/li&gt;
&lt;li&gt;Key things for interviewers to evaluate beyond syntax&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Code Reviews in Python Interviews Matter
&lt;/h2&gt;

&lt;p&gt;Python is deceptively simple. Bad code often works, until it scales or needs to be maintained. A good Python developer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writes &lt;strong&gt;readable, idiomatic code&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Avoids hidden performance issues&lt;/li&gt;
&lt;li&gt;Uses standard libraries effectively&lt;/li&gt;
&lt;li&gt;Knows the tradeoffs of dynamic typing&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Python Style Guide for Code Review Exercises
&lt;/h2&gt;

&lt;p&gt;This style guide should be shared with interviewees at the beginning of the exercise:&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Code Style &amp;amp; Structure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Follow PEP 8 for naming, spacing, and line length&lt;/li&gt;
&lt;li&gt;Use meaningful variable/function names&lt;/li&gt;
&lt;li&gt;Avoid deep nesting and large functions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔒 Error Handling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use specific exceptions&lt;/li&gt;
&lt;li&gt;Avoid bare &lt;code&gt;except:&lt;/code&gt; blocks&lt;/li&gt;
&lt;li&gt;Log or re-raise errors when appropriate&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📦 Code Organization
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Separate logic from I/O&lt;/li&gt;
&lt;li&gt;Avoid hardcoded values&lt;/li&gt;
&lt;li&gt;Minimize global state&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🧪 Testability
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use functions with clear input/output&lt;/li&gt;
&lt;li&gt;Write code that can be unit tested easily&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🧼 Clean Code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Remove unused imports/variables&lt;/li&gt;
&lt;li&gt;Prefer list comprehensions over manual loops (when readable)&lt;/li&gt;
&lt;li&gt;Use built-in functions where appropriate&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Junior-Level Code Review Example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Code Snippet:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data_list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data_list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;@&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Email:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&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="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Number:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Other:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issues to Spot:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Bare &lt;code&gt;except&lt;/code&gt; block (catches everything)&lt;/li&gt;
&lt;li&gt;No input validation&lt;/li&gt;
&lt;li&gt;Uses print statements instead of return/log&lt;/li&gt;
&lt;li&gt;Function is not reusable/testable&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Follow-up Prompt:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Refactor this into smaller functions. Replace print with return values or logging. Improve exception handling.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Mid-Level Code Review Example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Code Snippet:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save_user_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;file_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issues to Spot:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No error handling for file I/O&lt;/li&gt;
&lt;li&gt;Could use &lt;code&gt;json.dump()&lt;/code&gt; instead of &lt;code&gt;write(json.dumps(...))&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Filename construction could be unsafe (injection risk)&lt;/li&gt;
&lt;li&gt;No file existence or overwrite handling&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Follow-up Prompt:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Refactor with exception handling and safer filename logic. How would you make this testable and secure?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Senior-Level Code Review Example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Code Snippet:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReportGenerator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;report_type&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM users&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;report_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;summary&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_summarize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;report_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;full&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_generate_full_report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid report type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_summarize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;total&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_generate_full_report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issues to Spot:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No input validation or report_type enforcement&lt;/li&gt;
&lt;li&gt;Logic for DB query is tightly coupled&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;print()&lt;/code&gt; for error, instead of raising/logging&lt;/li&gt;
&lt;li&gt;No logging or observability hooks&lt;/li&gt;
&lt;li&gt;Could use &lt;code&gt;Enum&lt;/code&gt; or constants for &lt;code&gt;report_type&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Follow-up Prompt:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;How would you improve separation of concerns here? How would you test the report logic without a real DB?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Interviewer Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use open-ended prompts: &lt;em&gt;"What assumptions did you make?"&lt;/em&gt;, &lt;em&gt;"Would this scale?"&lt;/em&gt;, &lt;em&gt;"How would you test this?"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Look at how they reason through refactoring — not just what they fix&lt;/li&gt;
&lt;li&gt;Focus on communication, understanding of tradeoffs, and clarity of explanation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;In the next posts, we’ll dive into JavaScript, Go, and other languages to show how to scale this model across stacks and seniority.&lt;/p&gt;

&lt;p&gt;This series is about designing interviews that feel like &lt;strong&gt;working with a great teammate&lt;/strong&gt; — not jumping through academic hoops.&lt;/p&gt;

</description>
      <category>pythonhiring</category>
      <category>techinterviews</category>
      <category>codereview</category>
      <category>engineeringpractices</category>
    </item>
    <item>
      <title>Code Review Exercises That Actually Work: Java Edition (Junior to Senior)</title>
      <dc:creator>Syed Mohammad Ibrahim</dc:creator>
      <pubDate>Tue, 06 May 2025 15:00:00 +0000</pubDate>
      <link>https://dev.to/iamibi/code-review-exercises-that-actually-work-java-edition-junior-to-senior-2lp1</link>
      <guid>https://dev.to/iamibi/code-review-exercises-that-actually-work-java-edition-junior-to-senior-2lp1</guid>
      <description>&lt;p&gt;In Part 1 of this series, we explored a practical, respectful approach to engineering interviews - focusing on real-world skills like code reviews, GitHub project walkthroughs, and collaborative coding.&lt;/p&gt;

&lt;p&gt;In this post, we'll dive deeper into the &lt;strong&gt;code review portion&lt;/strong&gt; of the interview. You'll get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;neutral Java code style guide&lt;/strong&gt; to use during interviews
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Three code review examples&lt;/strong&gt;, tailored for junior, mid-level, and senior candidates
&lt;/li&gt;
&lt;li&gt;Tips for interviewers on how to run this part effectively&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Code Reviews Belong in Interviews
&lt;/h2&gt;

&lt;p&gt;Code reviews aren't just about syntax or formatting. They uncover how a candidate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thinks about &lt;strong&gt;design and readability&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Communicates &lt;strong&gt;technical feedback&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Prioritizes &lt;strong&gt;bugs, maintainability, and best practices&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Balances &lt;strong&gt;tradeoffs and pragmatism&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's one of the most real-world ways to assess software engineers - and works across all levels of experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  Java Style Guide for Code Review Exercises
&lt;/h2&gt;

&lt;p&gt;This is a &lt;strong&gt;neutral guide&lt;/strong&gt; to share with candidates during the exercise. It helps structure their review without giving away the "answers."&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Code Style &amp;amp; Structure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use descriptive class and method names&lt;/li&gt;
&lt;li&gt;Break down large methods into smaller, testable pieces&lt;/li&gt;
&lt;li&gt;Follow consistent indentation and spacing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔐 Exception Handling
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Catch only specific exceptions&lt;/li&gt;
&lt;li&gt;Don't suppress or swallow errors silently&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🧼 Clean Code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Remove unnecessary code or comments&lt;/li&gt;
&lt;li&gt;Use named constants instead of magic numbers/strings&lt;/li&gt;
&lt;li&gt;Avoid duplicating logic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔍 Input &amp;amp; Output
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Minimize direct &lt;code&gt;System.out.println()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Separate core logic from I/O when possible&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🚦 Testability
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Make code easy to unit test&lt;/li&gt;
&lt;li&gt;Aim for pure functions and clear input/output boundaries&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Junior-Level Code Review Example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Code Snippet:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserDataProcessor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&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="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"@"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Email: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Number: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Other: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What to Look For:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Vague method name (&lt;code&gt;process&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Overuse of &lt;code&gt;System.out.println()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Poor exception handling (&lt;code&gt;catch (Exception e)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;No input validation or testability&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Optional Follow-up Prompt:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Now refactor the code to improve clarity and maintainability. Feel free to break it into smaller methods and add input validation.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Mid-Level Code Review Example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Code Snippet:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileLogger&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;logMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;FileWriter&lt;/span&gt; &lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileWriter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"log.txt"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;": "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"\n"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// ignore&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What to Look For:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No resource management (&lt;code&gt;FileWriter&lt;/code&gt; should use try-with-resources)&lt;/li&gt;
&lt;li&gt;Swallowed exception with no logging or rethrow&lt;/li&gt;
&lt;li&gt;No separation between formatting and writing&lt;/li&gt;
&lt;li&gt;Hardcoded file path&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Follow-up Prompt:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Refactor this to follow SOLID principles and Java best practices. Consider testability and error handling.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Senior-Level Code Review Example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Code Snippet:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NotificationService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;notifyUsers&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEmail&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;EmailSender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEmail&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What to Look For:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tight coupling to &lt;code&gt;EmailSender&lt;/code&gt; (static call)&lt;/li&gt;
&lt;li&gt;No abstraction/interface for notification method&lt;/li&gt;
&lt;li&gt;No error handling or delivery guarantees&lt;/li&gt;
&lt;li&gt;No logging or observability&lt;/li&gt;
&lt;li&gt;Threading/scalability not considered&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Follow-up Prompt:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Refactor this to support future extensions (e.g., SMS, push notifications). Discuss design tradeoffs and test strategy.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Tips for Interviewers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;open-ended prompts&lt;/strong&gt; after the review:

&lt;ul&gt;
&lt;li&gt;What would you change first?&lt;/li&gt;
&lt;li&gt;Is this code testable? Why or why not?&lt;/li&gt;
&lt;li&gt;Would this scale in a production system?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Match the &lt;strong&gt;complexity to the candidate's level&lt;/strong&gt;
&lt;/li&gt;

&lt;li&gt;Don't judge by what they missed - focus on how they think, communicate, and justify decisions&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Coming Up Next: Python, JavaScript, and More
&lt;/h2&gt;

&lt;p&gt;This is just the beginning. Future posts will bring code review examples in other languages, helping teams run more effective interviews regardless of tech stack.&lt;/p&gt;

</description>
      <category>codereviewpractices</category>
      <category>technicalinterviews</category>
      <category>javahiring</category>
      <category>engineeringcareergrowth</category>
    </item>
    <item>
      <title>Rethinking Tech Interviews: Real Skills, Real Projects, No Bullshit</title>
      <dc:creator>Syed Mohammad Ibrahim</dc:creator>
      <pubDate>Sun, 04 May 2025 23:56:32 +0000</pubDate>
      <link>https://dev.to/iamibi/rethinking-tech-interviews-real-skills-real-projects-no-bullshit-13co</link>
      <guid>https://dev.to/iamibi/rethinking-tech-interviews-real-skills-real-projects-no-bullshit-13co</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Let’s be honest — most software engineering interviews suck.&lt;/p&gt;

&lt;p&gt;They’re filled with algorithmic trivia, abstract whiteboarding, and awkward “culture fit” questions that have nothing to do with the actual job. The result? Interviews that waste time for everyone and still fail to identify great engineers.&lt;/p&gt;

&lt;p&gt;This blog is for &lt;strong&gt;both interviewers and interviewees&lt;/strong&gt; — whether you’re designing a hiring process or preparing for one. The goal is to make interviews practical, time-efficient, and focused on what truly matters: real-world engineering skills.&lt;/p&gt;

&lt;p&gt;What follows is a no-nonsense framework based on real projects, meaningful collaboration, and practical coding. It respects your time, cuts the fluff, and gives you real signal — fast.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Start with a GitHub (or GitLab) Project Walkthrough
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Ask the candidate to walk through a personal or professional project they're proud of. Dive deep into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;why&lt;/em&gt; behind the project&lt;/li&gt;
&lt;li&gt;Their architecture or design choices&lt;/li&gt;
&lt;li&gt;Real implementation challenges and how they solved them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example prompts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“What tradeoffs did you make here?”&lt;/li&gt;
&lt;li&gt;“Would you change anything about this design today?”&lt;/li&gt;
&lt;li&gt;“How did you test this module?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You’re evaluating practical experience, ownership, and problem-solving — not memorization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caveat:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Not everyone has public projects. Offer the chance to discuss anonymized work or a written project summary. Don’t penalize candidates without open-source contributions.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Ask Role-Relevant Technical Questions (No Trivia)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Ask practical, role-specific questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Programming fundamentals (e.g., memory management, async flow)&lt;/li&gt;
&lt;li&gt;SOLID principles or OOP concepts in context&lt;/li&gt;
&lt;li&gt;Tech relevant to the role (e.g., Docker, message queues, testing frameworks)&lt;/li&gt;
&lt;li&gt;Operating System concepts&lt;/li&gt;
&lt;li&gt;Data Structures fundamentals (e.g., Big-O notation)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Bad:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
“What’s the time complexity of a red-black tree insertion?”&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Good:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
“Let’s say you’re building an API for file uploads. How would you handle large files?”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You're checking if they can apply technical concepts to real problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caveat:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Depth should match the role. Don’t quiz a frontend dev on database locking or a junior dev on system design at scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Code Review + Refactor: Test How They Think About Bad Code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Provide a small, &lt;em&gt;deliberately messy&lt;/em&gt; code sample — 2–3 files, 100–150 lines max. Include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unclear naming&lt;/li&gt;
&lt;li&gt;Some logic duplication&lt;/li&gt;
&lt;li&gt;Mild violations of style/architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then ask them to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Review&lt;/strong&gt; the code and point out what’s wrong
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refactor&lt;/strong&gt; it in a way they believe improves the design
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explain&lt;/strong&gt; why their changes are better
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Follow-up:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Ask: “What test would you write first after this refactor?” to assess how their cleanup impacts testability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you're testing:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can they identify practical issues?&lt;/li&gt;
&lt;li&gt;Do they understand real-world maintainability?&lt;/li&gt;
&lt;li&gt;How do they prioritize: clarity, performance, structure?&lt;/li&gt;
&lt;li&gt;Can they articulate technical decisions?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This simulates &lt;em&gt;real work&lt;/em&gt;. Engineers constantly read and fix code, not just write from scratch. You see their eye for detail, tradeoffs, and communication ability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caveats:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tailor to experience:&lt;/strong&gt; Give simpler code to juniors (naming, formatting), more structural issues to seniors (e.g., poor separation of concerns).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid trick questions:&lt;/strong&gt; Make the code realistically bad — don’t set traps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timebox it:&lt;/strong&gt; 30–45 minutes is enough. Don't let it sprawl.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Realistic Coding Task — AI Allowed
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Assign a real-world problem like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Write a script in your preferred language that fetches data from a public REST API, processes it, and saves the output as a file (any format). Include at least 2 unit tests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Rules:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They can use AI tools, docs, or the web — just like real life.&lt;/li&gt;
&lt;li&gt;They must &lt;strong&gt;explain&lt;/strong&gt; their code in detail.&lt;/li&gt;
&lt;li&gt;Code must be clean, readable, and minimally documented.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What you're evaluating:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Can they code in the language they claim?&lt;/li&gt;
&lt;li&gt;Do they understand the code they &lt;em&gt;copied or referenced&lt;/em&gt;?&lt;/li&gt;
&lt;li&gt;Do they value quality (tests, naming, structure)?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why it works:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You’re not testing memory — you’re testing how they work in real-world scenarios, with real tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caveat:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Be explicit: it's okay to use external help, but they must understand and &lt;em&gt;own&lt;/em&gt; every line they submit.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus: Soft Skills Appear Naturally
&lt;/h2&gt;

&lt;p&gt;You don’t need a separate "culture fit" round. Communication and collaboration show up organically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How they explain their project&lt;/li&gt;
&lt;li&gt;How they justify a refactor&lt;/li&gt;
&lt;li&gt;How they handle follow-up questions or critique&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just observe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are they clear?&lt;/li&gt;
&lt;li&gt;Are they open to feedback?&lt;/li&gt;
&lt;li&gt;Can they defend ideas without being defensive?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s culture.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: A Better Interview Framework
&lt;/h2&gt;

&lt;p&gt;A good interview doesn’t need whiteboards or brainteasers. It needs &lt;strong&gt;real-world simulation&lt;/strong&gt; — code, discussion, reasoning, collaboration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you get:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Candidates who can actually do the job&lt;/li&gt;
&lt;li&gt;A fairer process with less noise&lt;/li&gt;
&lt;li&gt;Stronger signals in less time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s stop playing games. Hire engineers like engineers.&lt;/p&gt;




</description>
      <category>techhiring</category>
      <category>engineeringinterviews</category>
      <category>practicalcoding</category>
      <category>devrel</category>
    </item>
    <item>
      <title>02. Software Engineering Design &amp; Security Principles</title>
      <dc:creator>Syed Mohammad Ibrahim</dc:creator>
      <pubDate>Sun, 09 Mar 2025 09:14:51 +0000</pubDate>
      <link>https://dev.to/iamibi/02-software-engineering-design-security-principles-57an</link>
      <guid>https://dev.to/iamibi/02-software-engineering-design-security-principles-57an</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the continuation of the course Secure Coding in Software Engineering.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Go to &lt;a href="https://dev.to/iamibi/secure-coding-in-software-engineering-51km"&gt;Home&lt;/a&gt;.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Go to &lt;a href="https://dev.to/iamibi/01-introduction-3c0l"&gt;previous chapter&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Go to next chapter - TBD&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Design Problems
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Wicked Problem&lt;/strong&gt;&lt;sup&gt;[1]&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;A problem that can be clearly defined only by solving it or solving a part of it (Horst Rittel and Melvin Webber, 1973). You essentially solve the problem first to define the problem, then solve it again to find a solution that works.&lt;/p&gt;

&lt;p&gt;"Design" is a wicked problem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fy33tn9kj75zhfbmeaeng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fy33tn9kj75zhfbmeaeng.png" alt="Software Development" width="349" height="440"&gt;&lt;/a&gt;&lt;br&gt; &lt;em&gt;Source: &lt;a href="https://xkcd.com/2021/" rel="noopener noreferrer"&gt;https://xkcd.com/2021/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Software Design
&lt;/h2&gt;

&lt;p&gt;&lt;b&gt;Book Recommendation&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Software Engineering Design by Carlos Otero 2012 &lt;a href="https://a.co/d/0cXzdeok" rel="noopener noreferrer"&gt;https://a.co/d/0cXzdeok&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Some concepts of software designs can be described as&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Abstraction&lt;/em&gt;&lt;/strong&gt;: Deals with creation of conceptual entities that facilitates solving the problem by focusing on the essential characteristics of the entities themselves (procedural and data abstraction). Required for good modularization (Liskov and Guttag 2010).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Modularization&lt;/em&gt;&lt;/strong&gt;: Decomposition of the system until fine-grained components are created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Encapsulation&lt;/em&gt;&lt;/strong&gt;: Principles that deals with providing access to the services of the conceptual entities (modules, components etc.) by exposing only essential information and hiding details on how those services are carried out.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Coupling&lt;/em&gt;&lt;/strong&gt;: The manner and degree of interdependence between software modules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Cohesion&lt;/em&gt;&lt;/strong&gt;: The manner and degree to which the tasks performed by a single software module are related to one another.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Separation of Interface and Implementation&lt;/em&gt;&lt;/strong&gt;: While encapsulation deals with exposing and hiding implementation details, this principle of separation goes further and allows for an interface with the implementation (separate) to be swapped for modified or new behavior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Completeness&lt;/em&gt;&lt;/strong&gt;: Measures how well design units provide required services to achieve their intent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Sufficiency&lt;/em&gt;&lt;/strong&gt;: Measures how well design units provide services that are sufficient to achieve their intent.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Impact of Design Principles on Security
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Abstraction and modularization help in being able to determine which of the modules are security relevant. If you don’t need a module, then it is redundant and should be removed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For example, having a module to deal with users and their profile management can allow for security related functions for a user to be implemented easily.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Encapsulation and Interface-Implementation Separation can be used to achieve security goals for modules as well by checking security related functions as part of the design. This design principle also helps in reducing the number of surfaces that need to be checked or secured by separating the implementation from the interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For example, exposing administrative functionality for a web based application to authenticated and authorized users only where the authentication and authorization mechanisms are implemented independently of the Login.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reducing coupling is a general software design goal and helps in securing modules because it also reduces the cascade of failures through the system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For Example, NPM repository down: March 2016, a disgruntled developer unpublished a very popular package called &lt;code&gt;left-pad&lt;/code&gt; due to a naming dispute that many other packages had as a dependency causing widespread disruption&lt;sup&gt;[2]&lt;/sup&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data abstraction is a key principle that has implications on privacy and securing data flows within an application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The sufficiency principle similarly has implications on minimizing the surfaces that need to be secured.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Faa1t6u962ioxczx3til8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Faa1t6u962ioxczx3til8.png" alt="Dependency" width="385" height="489"&gt;&lt;/a&gt;&lt;br&gt; &lt;em&gt;Source: &lt;a href="https://xkcd.com/2347/" rel="noopener noreferrer"&gt;https://xkcd.com/2347/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  NIST Special Publication 800-160, Volume 1 Revision 1
&lt;/h3&gt;

&lt;p&gt;The following topics are taken from NIST Special Publication 800-160, Volume 1 Revision 1&lt;sup&gt;[3]&lt;/sup&gt;,&lt;br&gt;
Engineering Trustworthy Secure Systems:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fltt75jvb4lsnquseanlf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fltt75jvb4lsnquseanlf.png" alt="NIST Special Publication 800-160" width="778" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How does software quality affect security?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are several software quality metrics that can help assess the quality of the software and its design. High software quality can also lead to more secure software since it helps with the maintenance of software systems during its lifecycle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F53d6j08a0pgjop8fn5bq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F53d6j08a0pgjop8fn5bq.png" alt="Code Quality" width="740" height="258"&gt;&lt;/a&gt;&lt;br&gt; &lt;em&gt;Source: &lt;a href="https://xkcd.com/1513/" rel="noopener noreferrer"&gt;https://xkcd.com/1513/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For example, In a code base, a developer may state that a method/function is not going to be used by anyone and can stay in the code base. Even if no other components depend on it, it is more than likely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  That someone will reuse the code from the component&lt;/li&gt;
&lt;li&gt;  That someone will make it dependent on another software module&lt;/li&gt;
&lt;li&gt;  That an attacker will gain access to it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finding bugs becomes easier when software quality is maintained!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ffthccdqjs2dmwhq9p3oc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ffthccdqjs2dmwhq9p3oc.png" alt="Bad Code" width="740" height="277"&gt;&lt;/a&gt;&lt;br&gt; &lt;em&gt;Source: &lt;a href="https://xkcd.com/1926/" rel="noopener noreferrer"&gt;https://xkcd.com/1926/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Security Principles
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Weakness
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Mistakes or flaws (intentional or unintentional) in the software system that can lead to serious system level impacts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can use the CWE&lt;sup&gt;TM&lt;/sup&gt; language to describe such flaws.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Different from vulnerabilities, which involve using a weakness or set of weaknesses to achieve a desired effect or impact on the system.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Attack Surface
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Informal Definition&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We have heard the concept of a "surface" in principles of software system design – an interface to the interaction between modules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An attack surface similarly provides attackers an interface to system resources that could be abused to access security vulnerabilities and to exploit the software system to achieve an attacker’s goals.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;For a home, what are some example attack surfaces?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Formal Definition&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Attacker can attack using channels (e.g., ports, sockets), invoke methods (e.g., API), and send data items (input strings or indirectly via persistent or stored data)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A system’s attack surface – Subset of the system’s resources (channels, methods, and data) that can be used in attacks on the system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;More attack surfaces likely means it is easier to exploit and cause more damage.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fdwkd0lew7zlab62axcva.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fdwkd0lew7zlab62axcva.png" alt="Attack Surface Metric" width="370" height="184"&gt;&lt;/a&gt;&lt;br&gt; &lt;em&gt;Source: Attack Surface Metric, Pratyusa K. Manadhata, CMU-CS-08-152, November 2008&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Attack Vector
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The set of inputs, actions and effects on the software system that when provided via the attack surface cause the exploitation of the system achieving the attacker/user’s goal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Typically involves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Access to the software system&lt;/li&gt;
&lt;li&gt;  Ability to manipulate input&lt;/li&gt;
&lt;li&gt;  Ability and access to the configuration of the software environment&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Illustration
&lt;/h4&gt;

&lt;p&gt;Death Star, Star Wars&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fyq8vhp0sd6fchpx70um2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fyq8vhp0sd6fchpx70um2.png" alt="Death Star" width="800" height="598"&gt;&lt;/a&gt; &lt;br&gt; &lt;em&gt;Source: Johnson, S. (1995). In Star Wars technical journal. Boxtree.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The reactor system at the core has a &lt;strong&gt;weakness&lt;/strong&gt; that when it is hit with a blast, it causes a chain reaction that can be catastrophic. Intentionally hidden by Galen Erso, a scientist coerced to work for the Galactic Empire.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exhaust port on the Death Star designed for exhaust (output) is an example of an &lt;strong&gt;attack surface&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Death Star has a &lt;strong&gt;vulnerability&lt;/strong&gt; where anything that can cause a chain reaction in the reactor core can lead to a catastrophic loss of the system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;attack vector&lt;/strong&gt; is the two proton torpedoes used to access the exhaust port, reach the reactor core and initiate the chain reaction.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Typical Security Objectives
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Confidentiality&lt;/strong&gt;: Information is only available to those who should have access.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integrity&lt;/strong&gt;: Data is known to be correct and trusted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Availability&lt;/strong&gt;: Information is available for use by legitimate users when it is needed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F7002vslsa464qt78hma5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F7002vslsa464qt78hma5.png" alt="CIA Triad" width="719" height="603"&gt;&lt;/a&gt; &lt;br&gt; &lt;em&gt;Source: &lt;a href="https://www.itgovernance.co.uk/blog/what-is-the-cia-triad-and-why-is-it-important" rel="noopener noreferrer"&gt;https://www.itgovernance.co.uk/blog/what-is-the-cia-triad-and-why-is-it-important&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Other Security Objectives
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Non-repudiation&lt;/strong&gt; - Transactional security property where sender of a message is provided with proof of delivery and recipient of the message is provided with proof of sender’s identity. A real-life example of non-repudiation is when you sign for a package upon delivery—your signature serves as proof that you received it, preventing you from later denying acceptance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Privacy&lt;/strong&gt; - Property where all disclosure of information is provided only by authorized consent. A real-life example of privacy is when a doctor keeps your medical records confidential, ensuring that only authorized personnel can access them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Audit/Accountability/Logging&lt;/strong&gt; - Transactional security property where all security relevant actions and events are recorded and can be examined by authorized parties. A real-life example of audit/accountability/logging is security cameras in a retail store recording all transactions, allowing store managers to review footage if a theft or dispute occurs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Id-entity&lt;/strong&gt; - Typically digital identity, a security property that allows unique identification of individual entities allowing for authentication, authorization and access to services. A real-life example of identity is a passport, which serves as official proof of a person's identity and nationality when traveling internationally.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Set of Security Principles
&lt;/h2&gt;

&lt;p&gt;A set of guiding principles for securing software systems need to be followed. The real "secret-sauce" behind most of the secure designs of software being followed in modern enterprises.&lt;/p&gt;

&lt;p&gt;The following security principles already have existed since the 1970s and are from the following sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  McGraw, Gary &amp;amp; Viega, John. "Keep It Simple." Software Development. CMP Media LLC, May, 2003.&lt;/li&gt;
&lt;li&gt;  Viega, John &amp;amp; McGraw, Gary. Building Secure Software: How to Avoid Security Problems the Right Way. Boston, MA: Addison-Wesley, 2002.&lt;/li&gt;
&lt;li&gt;  Saltzer, Jerome H. &amp;amp; Schroeder, Michael D. "The Protection of Information in Computer Systems" 1278-1308. Proceedings of the IEEE 63, 9 (September 1975).&lt;/li&gt;
&lt;li&gt;  Howard, Michael &amp;amp; LeBlanc, David. Writing Secure Code. 2nd. Redmond, WA: Microsoft Press, 2002.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Trustworthiness vs. Trust&lt;sup&gt;[4]&lt;/sup&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;"Trustworthiness implies that something is worthy of being trusted."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Trust merely implies that you trust something, whether it is trustworthy or not." - Trust is a &lt;em&gt;decision&lt;/em&gt;. - You &lt;em&gt;should&lt;/em&gt; only trust things that have &lt;em&gt;adequate&lt;/em&gt; evidence of being trustworthy.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Security Principle - Defence in Depth
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Do not rely on a single security method.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Anticipate failures and layer basic security practices.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Example: A Bank that manages money.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Security Guard &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fror08yazj5g3fdwgmrr1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fror08yazj5g3fdwgmrr1.jpg" alt="Security Guard" width="800" height="600"&gt;&lt;/a&gt; &lt;em&gt;Title: A private security officer at a Chinese factory in February 2004. Creator: Robbie Sproule. Source: &lt;a href="https://www.flickr.com/photos/85278812@N00/1555598" rel="noopener noreferrer"&gt;Flickr&lt;/a&gt;. License: &lt;a href="https://creativecommons.org/licenses/by/2.0/" rel="noopener noreferrer"&gt;CC-By-2.0&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bank Building &lt;br&gt;
&lt;a href="https://media2.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%2Fznnhejnr8gj9i3ui4mgo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fznnhejnr8gj9i3ui4mgo.jpg" alt="Bank Building" width="800" height="751"&gt;&lt;/a&gt; &lt;em&gt;Title: Lloyds Bank Building. Creator: Pit-Yacker. Source: &lt;a href="https://commons.wikimedia.org/wiki/File:Lloyds_Bank_Building.jpg" rel="noopener noreferrer"&gt;Wikimedia Commons&lt;/a&gt;. License: &lt;a href="https://creativecommons.org/licenses/by/2.5/deed.en" rel="noopener noreferrer"&gt;CC-By-2.5&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bank Teller &lt;br&gt;
&lt;a href="https://media2.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%2F52exwju1x4fjdn1j0jvb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F52exwju1x4fjdn1j0jvb.jpg" alt="Bank Teller" width="640" height="427"&gt;&lt;/a&gt; &lt;em&gt;Title: A teller in a branch of Bank Muamalat. Creator: Melwinsy. Source: &lt;a href="https://en.wikipedia.org/wiki/Bank_teller#/media/File:Bank_Muamalat.JPG" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;. License: &lt;a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="noopener noreferrer"&gt;CC-By-SA-4.0&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bank Vault &lt;a href="https://media2.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%2Fevb2mz735f2mrkqv3od5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fevb2mz735f2mrkqv3od5.jpg" alt="Bank Vault" width="800" height="529"&gt;&lt;/a&gt; &lt;em&gt;Title: Bank Vaults under Hotels in Toronto, Ontario. Creator: Jason Baker. Source: &lt;a href="https://www.flickr.com/photos/jasonbaker/9027029071" rel="noopener noreferrer"&gt;Flickr&lt;/a&gt;. License: &lt;a href="https://creativecommons.org/licenses/by/2.0/" rel="noopener noreferrer"&gt;CC-By-2.0&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The above example demonstrates that to get to the bank vault, one must pass through multiple steps of security to reach it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Security Principle - Keep Security Simple
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Keep security or protection mechanisms simple.&lt;/li&gt;
&lt;li&gt;  Makes it easy to understand, implement and analyze security.

&lt;ul&gt;
&lt;li&gt;  This has a direct co-relation to a CWE called
&lt;a href="https://cwe.mitre.org/data/definitions/655.html" rel="noopener noreferrer"&gt;CWE-655: Insufficient Psychological Acceptability&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  Can also make it easy to use.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Security Principle - Attack Surface Reduction
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Actively address and reduce any surfaces exposed to unauthenticated or unauthorized actors that allow for the system to be compromised against its security goals.&lt;/li&gt;
&lt;li&gt;  This can be done in a number of ways:

&lt;ul&gt;
&lt;li&gt;  From software design principles, the ideas of encapsulation or hiding functionality from entities (code, users, etc.) that don’t require it, separation of interface and implementation can also be used to control which entities have access to what functionality etc.&lt;/li&gt;
&lt;li&gt;  In software systems, easiest way is to follow:

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;KISS principle&lt;/strong&gt;: 'keep it simple stupid'. Keeping the system simple at design time tends to make it easy for actors to use the system and prevent misuse. It also helps in understanding and analyzing the system for attack surfaces and vulnerabilities.&lt;/li&gt;
&lt;li&gt;  Remove functionality that is not needed. The attack surface is essentially going to be all the code, functionality or data that is accessible by entities. Removing or reducing those can go a long way. Example could be keeping a code that we feel nobody is going to use, in the codebase which eventually someone ends up using bringing up weaknesses.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Security Principle - Establish Secure Defaults
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The default configuration or state that ships with the software system should already include the most secure configuration. That means out of the box the software system should stop insecure actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do not rely on an entity to configure the software system in order to enable security features or to make it run securely.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Example: A banking app requires strong passwords and enables two-factor authentication (2FA) by default, ensuring users have a secure account setup from the start.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Security Principle - Principle of Least Privilege
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Not everyone needs access or privileges to do everything.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The actors (users, or programs) that use the software system should only be allowed to operate with the least privileges possible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This limits the damage from an accident, error or attack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Example: A hotel key card that only grants access to a guest’s room and common areas, but not to staff-only areas or other guests' rooms.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Security Principle - Fail Securely
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Security controls in an application should assume the application is under attack by default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Apple &lt;code&gt;SSLVerifySignedServerKeyExchange&lt;/code&gt; checks validity of SSL certificate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The second goto fail is not part of the if block:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight c"&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;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SSLHashSHA1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hashCtx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;signedParams&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;checks&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;fail&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="n"&gt;frees&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cleanups&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="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;em&gt;Source: &lt;a href="https://dwheeler.com/essays/apple-goto-fail.html" rel="noopener noreferrer"&gt;The Apple goto fail vulnerability: lessons learned, David A. Wheeler&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Several issues here. But, one of them is the error code default was 0 which meant no error. This allowed attacker to skip other checks and return error of 0 as long as first statement returned no error. Here, failure cases should be checked explicitly and independently rather than stacking them one after another.&lt;sup&gt;[5]&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Principle - Complete Mediation ("Non-Passable")
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Following from the earlier example, this principle involves making sure:

&lt;ul&gt;
&lt;li&gt;  To find &lt;strong&gt;all&lt;/strong&gt; channels&lt;/li&gt;
&lt;li&gt;  Check &lt;strong&gt;all&lt;/strong&gt; inputs from untrusted sources&lt;/li&gt;
&lt;li&gt;  Check as soon as possible and fail early&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;If the system has a client-server model, this means ensuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Security checks are done on the server-side (client is not necessarily trusted, server may be trusted but not necessary)&lt;/li&gt;
&lt;li&gt;  Check trustworthiness of environment (client or server) to ensure checks can also return trustworthy results&lt;/li&gt;
&lt;li&gt;  Client-side checking can improve user-response and lower server load, however do client-side checks &lt;em&gt;&lt;strong&gt;in addition&lt;/strong&gt;&lt;/em&gt; to server-side checks.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Example: A credit card transaction where the bank verifies the card details and available balance every time a purchase is made, rather than relying on previously approved transactions. This ensures that all inputs are checked, trustworthiness is validated on the bank's secure server, and potential fraud is caught early.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Principle - Don't Trust Service Interface
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This principle means the software system should not trust any of the interfaces it interacts with especially with regard to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Its behavior&lt;/li&gt;
&lt;li&gt;  Its promises&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;The mere existence of an interface is not a contract that it will behave correctly.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Example interfaces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Third-party services and libraries&lt;/li&gt;
&lt;li&gt;  Databases&lt;/li&gt;
&lt;li&gt;  File systems&lt;/li&gt;
&lt;li&gt;  Memory&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fw6m18q7ss8ww0t9i8l42.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fw6m18q7ss8ww0t9i8l42.gif" alt="R2D2 Shock" width="500" height="213"&gt;&lt;/a&gt; &lt;br&gt;&lt;em&gt;Source: [6]&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Principle - Separation of Duties/Privilege
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This principle involves splitting the roles, duties and privileges that go along with those roles and duties into separate parts of the software system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Example: You would not want a bank to allow the same customer to change the address of an account and authorize a check against an account.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Principle - Avoid Security Through Obscurity
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This principle states:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Avoid implementing obscure security mechanisms to "add" security.&lt;/li&gt;
&lt;li&gt;  Adversaries and attackers likely already have access to the software system, source code and perhaps even the data for reverse engineering given enough resources.&lt;/li&gt;
&lt;li&gt;  Relying on such mechanisms is very dangerous!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Assume the software system is already compromised and build security &lt;em&gt;in&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Example: The gate here really does not really add any security nor does it add deterrence.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fmydvf45ptvf7ec9cpnfo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fmydvf45ptvf7ec9cpnfo.jpg" alt="Security Bypass" width="640" height="480"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Principle - Avoid Non-Atomic Security Operations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This principles talks to how the software system should treat and implement security actions and operations atomically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Fake check scheme of the past.&lt;/li&gt;
&lt;li&gt;  Both check verification and account balance update should be part of the same atomic transaction.&lt;/li&gt;
&lt;li&gt;  Check needs to be verified and then the deposit updated as part of the same transaction.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Principle - Fix Security Issues Correctly
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Security issues need to be treated at the root cause of the issue rather than just addressing symptoms.&lt;/li&gt;
&lt;li&gt;  The first gut response to an attack is to fix the issues responsible directly for the attack. You may only be addressing the symptoms of the problem.&lt;/li&gt;
&lt;li&gt;  However, this principle states that the software system and processes should be analyzed for a deeper analysis on what allowed the issue to happen in the first place.&lt;/li&gt;
&lt;li&gt;  As a software engineer you need to be able to fully understand the problem before you can design and implement a fix.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Principle - Least Common 'Security' Mechanism
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This principle is actually a design principle where the system should be implemented in such a way as to reduce and minimize the use of shared mechanisms. For example, the use of &lt;code&gt;/tmp&lt;/code&gt; or &lt;code&gt;/var/tmp&lt;/code&gt; directories to store temporary files for users.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This applies to security mechanisms as well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shared objects provide potentially dangerous channels for information flow and unintended interactions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;What is wrong with this code?&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationUser&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IdentityUser&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ApplicationUserLogin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;ApplicationUserRole&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ApplicationUserClaim&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;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="n"&gt;Name&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="n"&gt;Surname&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="c1"&gt;//code omitted for brevity&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;Student&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ApplicationUser&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="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;Number&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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ValidateAntiForgeryToken&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;JsonResult&lt;/span&gt; &lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nf"&gt;Bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exclude&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="n"&gt;StudentViewModel&lt;/span&gt; &lt;span class="n"&gt;model&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;ModelState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ApplicationUser&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;UserManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&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="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Student&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Surname&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Surname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;UserName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;PhoneNumber&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PhoneNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Number&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//custom property&lt;/span&gt;
                &lt;span class="n"&gt;PasswordHash&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;checkUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PasswordHash&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;
            &lt;span class="n"&gt;UserManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Update&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="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;p&gt;&lt;em&gt;Source: [7]&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Principle - Limit Resource Dependencies
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This principle involves limiting the amount of resources depended upon by the software system wherever possible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fail2Ban – Limits excessive unauthorized login attempts over the network for an application based on logs and bans them when the limits are exceeded. Can be used for multiple applications including SSH.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Google, 2020 – Denial Of Service by UDP amplification attack&lt;sup&gt;[8]&lt;/sup&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  "In 2017, our Security Reliability Engineering team measured a record-breaking UDP amplification attack sourced out of several Chinese ISPs (ASNs 4134, 4837, 58453, and 9394), which remains the largest bandwidth attack of which we are aware."&lt;/li&gt;
&lt;li&gt;  "The attacker used several networks to spoof 167 Mpps (millions of packets per second) to 180,000 exposed CLDAP, DNS, and SMTP servers, which would then send large responses to us. This demonstrates the volumes a well-resourced attacker can achieve. This was four times larger than the record-breaking 623 Gbps attack from the Mirai botnet a year earlier." - Damien Menscher, Security Reliability Engineer at Google&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Principle - Ease Of Use For The Software System
&lt;/h3&gt;

&lt;p&gt;This principle follows the previously discussed KISS principle.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;However, as applied to security, the software system's human interface must be designed for ease of use so users will &lt;em&gt;routinely&lt;/em&gt; and &lt;em&gt;automatically&lt;/em&gt; use the protection mechanisms correctly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Making it easy for users to secure their data and the software system, will make the system more secure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mistakes are reduced when security mechanisms in the software system closely match the user’s perception of their own protection goals. - Credit: Dr. David A. Wheeler&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security Principle - Hardening The Software System Environment
&lt;/h3&gt;

&lt;p&gt;The software system is designed to run in an environment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Building an application securely + deploying it in an insecure environment ≠ Secure Software System&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The software system should also not assume anything about the environment wherever possible.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Types of Security Problems
&lt;/h2&gt;

&lt;p&gt;We will discuss some type of security problems that are worth mentioning outside of the security principles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The "Confused" deputy problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A more privileged program ("a deputy") that is tricked by a lower privileged program into transitively giving it authority and misusing the authority. This is a type of privilege escalation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Confused Deputy Example (Mainframe Billing System)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In an old mainframe billing system, a privileged billing process is responsible for generating and finalizing invoices. However, due to weak access controls, a user (or another less-privileged process) can trick the billing system into overwriting a bill—either by abusing its elevated permissions or by injecting unauthorized inputs.&lt;/p&gt;

&lt;p&gt;Why is this a Confused Deputy Problem?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The billing system (deputy) has the authority to modify bills.&lt;/li&gt;
&lt;li&gt;  A user or process (attacker) without direct billing privileges tricks the system into writing incorrect values.&lt;/li&gt;
&lt;li&gt;  The billing system, acting on behalf of the user, unknowingly misuses its higher privilege, allowing unauthorized bill modifications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A more modern analogy is Cloud Storage Misuse—where a web application (acting as a deputy) has write access to a cloud storage bucket. If a user uploads a malicious file, and the app inadvertently writes it with admin privileges, it allows unauthorized file modifications, similar to the mainframe billing issue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time-of-check-Time-of-Use (TOCTOU) problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A race condition where a program checks the state of a part of the system (like a security credential) and the use of the results of that check.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Example: The &lt;strong&gt;setuid&lt;/strong&gt; program bug&lt;sup&gt;[9]&lt;/sup&gt;. The following code had the race condition:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight c"&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;access&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;W_OK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O_WRONLY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Where, After the access check, before the open, the attacker replaces &lt;code&gt;file&lt;/code&gt; with a symlink to the Unix password file &lt;code&gt;/etc/passwd&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;symlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/etc/passwd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

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

&lt;p&gt;&lt;strong&gt;Covert/Side Channels&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Surreptitious ways to send or "leak" data across data boundaries.&lt;/li&gt;
&lt;li&gt;  This requires some sort of access, coordination and/or sharing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Impacts from Security Principle Violations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Information leakage&lt;/strong&gt;: Sensitive or Unauthorized information got exposed.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Modification of data&lt;/strong&gt;: Sensitive data was modified or unauthorized changes made to data.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Denial of Service&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Unreliable Execution&lt;/strong&gt;: The software system became unreliable or went into a degraded mode of operation.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Resource Consumption&lt;/strong&gt;: The software system ran out of resources.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Unauthorized code or command execution&lt;/strong&gt;: Unauthorized code or commands were able to be run or executed by external users.&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Escalation of privilege / Assumption of Identity&lt;/strong&gt;: Malicious actors were able to hijack the identity of a privileged user or escalate their privileges within the software system or its environment.&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Bypass Protection Mechanism&lt;/strong&gt;: Any protection mechanisms were easily bypassed or circumvented.&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Hide Activities&lt;/strong&gt;: Activities performed on the software system or its environment were hidden from auditors or system evaluators or monitors.&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Loss of trust&lt;/strong&gt;: Users lost trust in the system they were using.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Wicked_problem" rel="noopener noreferrer"&gt;Wicked Problem - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Npm_left-pad_incident" rel="noopener noreferrer"&gt;npm left-pad incident&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ron Ross, Michael McEvilley, Maichael McEvilley. Engineering of Trustworthy Secure Systems. Vol 1 Rev 1. &lt;a href="https://doi.org/10.6028/NIST.SP.800-160v1r1" rel="noopener noreferrer"&gt;https://doi.org/10.6028/NIST.SP.800-160v1r1&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Definitions from "Principled Assuredly Trustworthy Composable Architectures" by Peter Neumann, 2004&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.archive.org/web/20221017053210/https://www.cisa.gov/uscert/bsi/articles/knowledge/principles/failing-securely" rel="noopener noreferrer"&gt;Failing Securely&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://movies.stackexchange.com/questions/42527/is-there-any-real-world-science-behind-r2-d2-s-computer-interfacing-arm" rel="noopener noreferrer"&gt;Is there any real-world “science” behind R2-D2’s computer interfacing arm?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/39304464/how-to-save-new-record-with-hashed-password-in-my-custom-table-instead-of-aspnet" rel="noopener noreferrer"&gt;How to save new record with hashed password in my custom table instead of aspnet user?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.a10networks.com/blog/5-most-famous-ddos-attacks/" rel="noopener noreferrer"&gt;Five Most Famous DDoS Attacks and Then Some&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use" rel="noopener noreferrer"&gt;Time-of-check to time-of-use&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>securecoding</category>
      <category>softwareengineering</category>
      <category>security</category>
      <category>devsecurity</category>
    </item>
    <item>
      <title>01. Introduction</title>
      <dc:creator>Syed Mohammad Ibrahim</dc:creator>
      <pubDate>Sun, 09 Mar 2025 09:14:35 +0000</pubDate>
      <link>https://dev.to/iamibi/01-introduction-3c0l</link>
      <guid>https://dev.to/iamibi/01-introduction-3c0l</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the continuation of the course Secure Coding in Software Engineering.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Go to &lt;a href="https://dev.to/iamibi/secure-coding-in-software-engineering-51km"&gt;Home&lt;/a&gt;.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Go to &lt;a href="https://dev.to/iamibi/02-software-engineering-design-security-principles-57an"&gt;next chapter&lt;/a&gt;.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Almost every gadget around us uses software to operate, whether it be a hearing aid or an MRI machine. Software plays a major role in making every gadget operational and useful for its respective task. A lot of resources go into making the software work. But not enough attention is given to the software being safe, secure, behaving correctly, effects on other parts of the system(s). Yet, still somehow software still works.&lt;/p&gt;

&lt;p&gt;Some of the reasons for the software being insecure&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Poor communications (between all parties involved)&lt;/li&gt;
&lt;li&gt;  Commercial pressures&lt;/li&gt;
&lt;li&gt;  Poor system design&lt;/li&gt;
&lt;li&gt;  Poorly defined system requirements&lt;/li&gt;
&lt;li&gt;  Inaccurate estimates of required resources&lt;/li&gt;
&lt;li&gt;  Unmanaged Risks&lt;/li&gt;
&lt;li&gt;  Sloppy Development Practices&lt;/li&gt;
&lt;li&gt;  Use of immature technologies&lt;/li&gt;
&lt;li&gt;  Stakeholder politics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and many more... &lt;sup&gt;[1]&lt;/sup&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Importance of Secure Software Systems
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;What are the repurcussions of an insecure software or a software failure?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While it might not seem like a big deal, software failures can have serious consequences. Here are some events that illustrate this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Injury &amp;amp; Loss of Life &lt;sup&gt;[2]&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;  Loss of financial assets &lt;sup&gt;[1]&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;  Loss of resources: organizational assets &lt;sup&gt;[3]&lt;/sup&gt;, the organization itself
&lt;sup&gt;[1]&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;  Loss of the software system: Denial of service&lt;/li&gt;
&lt;li&gt;  Loss of valuable or sensitive information&lt;/li&gt;
&lt;li&gt;  Loss of trust&lt;sup&gt;*&lt;/sup&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;sup&gt;*&lt;/sup&gt;The trust factor is not measurable but has a direct impact on the application usage.&lt;/p&gt;

&lt;p&gt;And if the bugs were not enough, there are active adversaries trying to exploit vulnerabilities in software systems. These adversaries are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Well-organized, similar to small businesses&lt;/li&gt;
&lt;li&gt;  Well-resourced, ranging from organized crime to nation states&lt;/li&gt;
&lt;li&gt;  Sophisticated in their technical abilities and attack methods&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F5yort7uctdlfys2vwmc0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F5yort7uctdlfys2vwmc0.jpg" alt="Image description" width="800" height="400"&gt;&lt;/a&gt;&lt;br&gt; &lt;em&gt;Source: &lt;a href="https://www.linkedin.com/pulse/different-types-hackers-motivations-overview-yagnik-kathiriya" rel="noopener noreferrer"&gt;&lt;em&gt;The Different Types of Hackers and Their Motivations: An Overview&lt;/em&gt;&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do we identify the risks?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To identify the risks, one must look at the attacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mitigations for Insecure Software
&lt;/h3&gt;

&lt;p&gt;There are ways in which a couple of reasons for software being insecure mentioned above can be mitigated.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Poor System Design&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;  Giving a thought to security during the system design.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;em&gt;Unmanaged Risks&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;  Identifying security risks beforehand.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;em&gt;Sloppy Development Practices&lt;/em&gt;
Certain measures can be put in place to prevent such practices, including but not limited to:

&lt;ul&gt;
&lt;li&gt;Software Development Guidelines&lt;/li&gt;
&lt;li&gt;Software Lifecycle Management&lt;/li&gt;
&lt;li&gt;Code Review Process&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;What about using crypto, or anti-virus, or any other kind of Security Features?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;"Security Features"&lt;/strong&gt; are not the answer. Just by using Anti-virus, Crypto, Implementing your own Cryptographic Algorithm, using Open Source Software, or any other kind of Security Software is not going to provide you with a solution.&lt;/p&gt;

&lt;p&gt;Furthermore, security through obsecurity is also not the answer to the problem. Like adding barriers is not going to stop a user from finding other ways to bypass the system, thus, making it more insecure (CWE-655). The situation can develop a loss of trust within the user and the software system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F38si6h04kbrs2jesu26b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F38si6h04kbrs2jesu26b.jpg" alt="Image description" width="640" height="480"&gt;&lt;/a&gt;&lt;br&gt; &lt;em&gt;Source: &lt;a href="https://youtu.be/pqyFG-G4hF8?si=lt4FKxSA1dROA1J4" rel="noopener noreferrer"&gt;https://youtu.be/pqyFG-G4hF8?si=lt4FKxSA1dROA1J4&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There is a trade-off between Security and usability/convenience. Interestingly, new ways are being explored to find a balance in usable security.&lt;/p&gt;

&lt;h3&gt;
  
  
  Measuring Security
&lt;/h3&gt;

&lt;p&gt;There are a lot of places where one can retrieve information around the vulnerabilities. These location contain an extensive and actively updated information around the defects within the code.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;CISA Cybersecurity Advisory, &lt;a href="https://www.cisa.gov/news-events/cybersecurity-advisories" rel="noopener noreferrer"&gt;https://www.cisa.gov/news-events/cybersecurity-advisories&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Debian Security Tracker, &lt;a href="https://security-tracker.debian.org/tracker/" rel="noopener noreferrer"&gt;https://security-tracker.debian.org/tracker/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;National Vulnerabilities Database/CVE, &lt;a href="https://nvd.nist.gov/general/nvd-dashboard" rel="noopener noreferrer"&gt;https://nvd.nist.gov/general/nvd-dashboard&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MITRE CVE Database, &lt;a href="https://cve.mitre.org/" rel="noopener noreferrer"&gt;https://cve.mitre.org/&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Common Weakness Enumeration (CWE)
&lt;/h3&gt;

&lt;p&gt;The common weaknesses enumeration defines common weaknesses in software that have security implications. This is a language that communicates the root cause of the vulnerability.&lt;/p&gt;

&lt;p&gt;Difference from vulnerabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Weaknesses can be thought of as mistakes or flaws (intentional or unintentional) in the software that can have serious system level impacts.&lt;/li&gt;
&lt;li&gt;  Vulnerabilities allow adversaries to take advantage of accessible weaknesses that are exploitable in order to achieve their attack goals.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, when a vulnerability says that it is a buffer-overflow, that sentence in itself is useful only to a certain extent. Was it a out of bounds read/write? CWE can be attached to the vulnerability that will help in explaining why the vulnerability occurred. Try looking up CWE-125 or CWE-787 for more details.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What about Cross-Site Scripting (XSS)? Is it an attack or a weakness?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;code&gt;XSS&lt;/code&gt; is an attack, at heart of which lies a weakness termed Improper Neutralization of Input During Web Page Generation (CWE-79).&lt;/p&gt;

&lt;p&gt;Similarly, &lt;code&gt;SQL Injection&lt;/code&gt; is an attack which is caused by Improper Neutralization of Special Elements used in an SQL Command (CWE-89).&lt;/p&gt;

&lt;p&gt;While going through a CWE, you will see a section covering consequences. The heading in the page is &lt;code&gt;Common Consequences&lt;/code&gt; and they describe the impact on the application if the weakness is not fixed. However, not all the technical impact will be accurate to the application being addressed. It is upto the security personnel to educate the developer, what will happen if the weakness is not addressed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Weakness Inception within Software
&lt;/h3&gt;

&lt;p&gt;The following diagram shows the different layers of software over the operating system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F2p7fo2yefql9pzmedtt4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F2p7fo2yefql9pzmedtt4.png" alt="Image description" width="800" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The weakness can exist anywhere along these layers. The criticality of the weakness increases from top to bottom. If there is a weakness within the Hardware, then it is extremely difficult to mitigate it as upgrading hardware is not easy. In contrast, upgrading an application is much easier due to the availability of internet and in-place upgrade mechanisms within the software. As a software developer, one has to think about all the aspects of each layer while writing a software.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ffe5ev22lc5tyw4tr3p7e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ffe5ev22lc5tyw4tr3p7e.png" alt="Image description" width="800" height="600"&gt;&lt;/a&gt;&lt;br&gt;&lt;em&gt;Source: &lt;a href="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Waterfall_model.svg/1600px-Waterfall_model.svg.png" rel="noopener noreferrer"&gt;https://upload.wikimedia.org/wikipedia/commons/thumb/e/e2/Waterfall_model.svg/1600px-Waterfall_model.svg.png&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Each level of the software model incurs a security review. For example, in requirements phase, having a documentation is a step. However, if the documentation for some reason is incomplete/inconsistent, then it is a security risk (CWE-1112, CWE-1059, and more.). The security impact is indirect in this case as issues with documentations are primarily quality focused. This doesn't mean that one should never write any documentation, rather address the important or critical aspects of the application being developed.&lt;/p&gt;

&lt;p&gt;A majority of the weaknesses are found in the implementation phase, but they can be traced back to the requirements phase.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is it possible to write secure code at all?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer is &lt;strong&gt;Yes&lt;/strong&gt;. Developers don't share how one can write secure code due to various reasons, some of them being, insufficient understanding of the concepts, company restrictions, insufficient documentation (except in their minds), etc. CWE can help with that. It is designed to assist the developer in writing secure code and sharing it with their peers and public.&lt;/p&gt;

&lt;p&gt;One thing to note is what the CWE doesn't do is observing the human processes like in an organization or processes like for example, if the company doesn't have a security policy, there is no mapping within CWE to address it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secure Development Lifecycle
&lt;/h3&gt;

&lt;p&gt;An organization level of security risk can be addressed by following a secure development lifecycle. It encapsulates a software model with security findings. Some examples of Secure Development Models are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Building Security In Maturity Model (BSIMM) -
&lt;a href="https://www.synopsys.com/software-integrity/software-security-services/bsimm-maturity-model.html" rel="noopener noreferrer"&gt;https://www.synopsys.com/software-integrity/software-security-services/bsimm-maturity-model.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Software Assurance Maturity Model (SAMM) - &lt;a href="https://owaspsamm.org/" rel="noopener noreferrer"&gt;https://owaspsamm.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Microsoft Security Development Lifecycle (SDL) - &lt;a href="https://www.microsoft.com/en-us/securityengineering/sdl" rel="noopener noreferrer"&gt;https://www.microsoft.com/en-us/securityengineering/sdl&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To pick one, Microsoft has built the SDL for internal use and have provided information publicly to everyone on how to proceed in different stages:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ffjst19v72cikwwvrfgsl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ffjst19v72cikwwvrfgsl.jpg" alt="Image description" width="800" height="196"&gt;&lt;/a&gt; &lt;br&gt;&lt;em&gt;Source: &lt;a href="https://learn.microsoft.com/en-us/archive/technet-wiki/t/resources/5554.sdl_5f00_steps.jpg" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/archive/technet-wiki/t/resources/5554.sdl_5f00_steps.jpg&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Governance and Education Phase - Security Training
&lt;/h4&gt;

&lt;p&gt;Training the developers is the key, especially in secure coding practices. A training should be focused on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Secure Design&lt;/li&gt;
&lt;li&gt;  Threat Modeling&lt;/li&gt;
&lt;li&gt;  Secure Coding&lt;/li&gt;
&lt;li&gt;  Security Testing&lt;/li&gt;
&lt;li&gt;  Privacy analysis&lt;/li&gt;
&lt;li&gt;  Policy and Governance guidelines&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt; Requirements Phase &lt;/h4&gt;

&lt;p&gt;This phase is used to establish the security requirements of the entire software system. A Security Risk Assessment&lt;sup&gt;[4]&lt;/sup&gt; and a Privacy Risk Assessment&lt;sup&gt;[5]&lt;/sup&gt; can help to identify which functions of the software need to be closely looked at.&lt;/p&gt;

&lt;p&gt;For example, if the software stores personal information, the functionality of the software that governs stores, transmission and uses should be examined closely and requirements such as&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Health_Insurance_Portability_and_Accountability_Act" rel="noopener noreferrer"&gt;HIPAA&lt;/a&gt; rules should be applied to determine what security requirements should be put in place.&lt;/p&gt;

&lt;p&gt;What is the minimum criteria that must be met in order to pass the quality or security of the software system for a release?&lt;/p&gt;

&lt;p&gt;For example, no vulnerabilities marked critical should be present in the release.&lt;/p&gt;

&lt;p&gt;Once the minimum criteria is set, it should not be relaxed or compromised. Getting this agreement ahead of time from stakeholders can help establish the criteria.&lt;/p&gt;

&lt;h4&gt; Design Phase &lt;/h4&gt;

&lt;p&gt;With the security requirements in hand, the design phase can proceed accounting for those additional security requirements. The design requirements outline the plan for the project to follow through the rest of the phases.&lt;/p&gt;

&lt;p&gt;The security requirements should not be thought of as an add-on. The security requirements should be "baked-in" to the design of the software system. Especially with cryptographic functionality, the design requirements should account for what, how and why the minimum cryptographic requirements should be used.&lt;/p&gt;

&lt;p&gt;Attack Surface analysis/reduction and Threat modeling is generally performed during this phase.&lt;/p&gt;

&lt;h4&gt; Implementation Phase &lt;/h4&gt;

&lt;p&gt;The implementation phase of the security development lifecycle is focused on how the software system is planned to be developed, deployed and used. This includes all the documentation and tools geared towards the goal above.&lt;/p&gt;

&lt;p&gt;This phase generally involves identifying and using only an approved list of tools, security checks etc. It also involves deprecating unsafe functions of the software system and performing static code analysis.&lt;/p&gt;

&lt;h4&gt; Verification Phase &lt;/h4&gt;

&lt;p&gt;The verification phase acts as the phase where you are able to check and verify whether the security requirements were really met in the implementation. A public release security and privacy review can be performed during this phase. This may also include any consultations with institutional review boards.&lt;/p&gt;

&lt;p&gt;Dynamic Analysis techniques are used to test the software system as it runs. Fuzz Testing techniques are also used to ensure no failures due to random input result.&lt;/p&gt;

&lt;p&gt;An attack surface review is performed to ensure any and all attack vectors have been addressed as a result of any changes in the previous phases.&lt;/p&gt;

&lt;h4&gt; Operations Phase - Release and Incident Response &lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;I am just a coder... Who cares after the code is releases? #amiright&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgs.xkcd.com%2Fcomics%2Fupdate.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimgs.xkcd.com%2Fcomics%2Fupdate.png" alt="update" width="602" height="249"&gt;&lt;/a&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;This is a critical part of the lifecycle.&lt;/p&gt;

&lt;p&gt;The Release phase is used to ready the software system for consumption by customers. A final security and privacy review is performed. Licensing of the software and its terms and any servicing terms for third-party software are put in place. Release archiving is performed storing all source code, documentation, specifications, design (including security) documents are archived.&lt;/p&gt;

&lt;p&gt;An incident response plan is put in place including any Emergency response plans for the software system.&lt;/p&gt;

&lt;p&gt;Detailed description of each step is available at Microsoft's SDL&lt;sup&gt;[6]&lt;/sup&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;The references are provided as URLs, however, if the original content is for some reason not accessible then the information is recorded as a copy of the original content under &lt;code&gt;docs/references&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://spectrum.ieee.org/why-software-fails" rel="noopener noreferrer"&gt;Why software fails?&lt;/a&gt; (2005) by Robert N. Charette&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cs.colostate.edu/~bieman/CS314/Notes/therac25.pdf" rel="noopener noreferrer"&gt;Medical Devices: The Therac-25&lt;sup&gt;*&lt;/sup&gt;&lt;/a&gt; by Nancy Leveson&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.cdemi.io/analyzing-software-failure-on-the-nasa-mars-climate-orbiter/" rel="noopener noreferrer"&gt;Analyzing Software Failure on the NASA Mars Climate Orbiter&lt;/a&gt; (2017) by Christopher Demicoli&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.synopsys.com/glossary/what-is-security-risk-assessment.html" rel="noopener noreferrer"&gt;What is Security Risk Assessment and How does it work?&lt;/a&gt; by Synopsys&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://privacypillar.com/data-privacy-risk-assessment/" rel="noopener noreferrer"&gt;What is Data Privacy Risk Assessment and Why is it Important?&lt;/a&gt; by Privacy Pillar&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://learn.microsoft.com/en-us/archive/technet-wiki/7100.the-security-development-lifecycle" rel="noopener noreferrer"&gt;The Security Development Lifecycle&lt;/a&gt; by Microsoft&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>securecoding</category>
      <category>softwareengineering</category>
      <category>security</category>
      <category>devsecurity</category>
    </item>
    <item>
      <title>Secure Coding in Software Engineering</title>
      <dc:creator>Syed Mohammad Ibrahim</dc:creator>
      <pubDate>Sun, 09 Mar 2025 09:14:07 +0000</pubDate>
      <link>https://dev.to/iamibi/secure-coding-in-software-engineering-51km</link>
      <guid>https://dev.to/iamibi/secure-coding-in-software-engineering-51km</guid>
      <description>&lt;p&gt;Welcome to Secure Coding in Software Engineering, a comprehensive course designed to equip you with essential knowledge and skills in securing software systems. In today's interconnected world, where software vulnerabilities pose significant risks to organizations and individuals, understanding software security principles is paramount. This course is crafted to provide you with a solid foundation in software security concepts, methodologies, and best practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgement
&lt;/h2&gt;

&lt;p&gt;I would like to thank Prof. Gananand Kini for his efforts and contributions in creating the original course from which this course is derived from. List of sources from where the course derived from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Prof. Gananand Kini's coursework.&lt;/li&gt;
&lt;li&gt;  Title: Secure Software Design and Programming: Class Materials

&lt;ul&gt;
&lt;li&gt;  Author: Prof. David A. Wheeler&lt;/li&gt;
&lt;li&gt;  Source: &lt;a href="https://dwheeler.com/secure-class/index.html" rel="noopener noreferrer"&gt;https://dwheeler.com/secure-class/index.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  License: CC BY-SA 3.0&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  Title: Introduction to Secure Coding

&lt;ul&gt;
&lt;li&gt;  Author: Andrew Buttner and Larry Shields&lt;/li&gt;
&lt;li&gt;  Source: &lt;a href="https://opensecuritytraining.info/IntroSecureCoding.html" rel="noopener noreferrer"&gt;https://opensecuritytraining.info/IntroSecureCoding.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  License: CC BY-SA 3.0&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Learning Objectives
&lt;/h2&gt;

&lt;p&gt;Throughout this course, you will achieve the following learning objectives:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Understanding the Secure Development Lifecycle (SDLC)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  Define and apply the principles of the Secure Development Lifecycle (SDLC).&lt;/li&gt;
&lt;li&gt;  Learn how to effectively communicate and mitigate software security weaknesses within the SDLC framework.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Penetration Testing and Security Analysis
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  Apply penetration testing techniques to evaluate software security.&lt;/li&gt;
&lt;li&gt;  Utilize security analysis techniques and tools to assess software security posture.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Identification and Remediation of Software Weaknesses
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  Develop the ability to explain weaknesses in software systems.&lt;/li&gt;
&lt;li&gt;  Apply defenses to remediate software exploits and vulnerabilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/em&gt; &lt;br&gt; This course will not cover topics such as anti-virus technology, hacking, or advanced exploitations. While relevant aspects of software design and architecture may be highlighted, they are not the primary focus.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What You Will Gain
&lt;/h3&gt;

&lt;p&gt;By completing this course, you will acquire practical skills and knowledge to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Audit software systems and identify security weaknesses effectively.&lt;/li&gt;
&lt;li&gt;  Describe identified weaknesses using MITRE's CWE&lt;sup&gt;TM&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;  Master methodologies, techniques, and tools used in secure code review processes.&lt;/li&gt;
&lt;li&gt;  Identify and address security weaknesses efficiently.&lt;/li&gt;
&lt;li&gt;  Conduct secure code reviews for various purposes, including enhancing code quality, improving communication, and
educating others.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why Take This Course?
&lt;/h3&gt;

&lt;p&gt;Many security education programs predominantly focus on exploiting vulnerabilities to showcase weaknesses. In contrast, this course emphasizes proactive measures to secure software systems through best practices. It fills the gap in traditional software engineering classes, which often overlook security aspects. While there's a gradual shift in academic curriculums, this course provides you with practical knowledge and skills essential for securing software systems in today's digital landscape.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;INFO&lt;/strong&gt;&lt;/em&gt; &lt;br&gt; The course will use the &lt;a href="https://cwe.mitre.org/data/definitions/699.html" rel="noopener noreferrer"&gt;CWE-699&lt;/a&gt; as base view which is focused on the security of a software. There are other views, which can be explored &lt;a href="https://cwe.mitre.org/data/index.html" rel="noopener noreferrer"&gt;here&lt;/a&gt; but are not within the scope of this course.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Course Structure
&lt;/h2&gt;

&lt;p&gt;This course is structured into multiple chapters, each covering different areas and topics within software development and security. Throughout the course, relevant code references will be provided in various programming languages such as C#, Python, etc., although the concepts discussed are applicable to any modern-day programming language. There will be references to relevant excerpts and images and reading material will be provided as references as and when required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Vulnerabilities
&lt;/h3&gt;

&lt;p&gt;To comprehend vulnerabilities within software systems, the course will employ a root cause analysis (RCA) approach, aided by Common Weakness Enumerations (CWE).&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Concepts
&lt;/h3&gt;

&lt;p&gt;The course will begin by exploring fundamental concepts essential for secure software development, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Tenets of Software System Design.&lt;/li&gt;
&lt;li&gt;  Security Principles and the Secure Software Development Cycle.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  In-Depth Exploration
&lt;/h3&gt;

&lt;p&gt;In addition to the core concepts, the course will delve into the following areas in-depth:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Input Security&lt;/li&gt;
&lt;li&gt;  Cryptography&lt;/li&gt;
&lt;li&gt;  Authentication &amp;amp; Authorization&lt;/li&gt;
&lt;li&gt;  Session Management&lt;/li&gt;
&lt;li&gt;  Error Handling&lt;/li&gt;
&lt;li&gt;  Logging&lt;/li&gt;
&lt;li&gt;  Debug Code&lt;/li&gt;
&lt;li&gt;  Performing Secure Code Reviews.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/iamibi/secure-coding-in-software-engineering-51km"&gt;About the Course&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/iamibi/01-introduction-3c0l"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/iamibi/02-software-engineering-design-security-principles-57an"&gt;Software Engineering Design &amp;amp; Security Principles&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  License
&lt;/h2&gt;

&lt;p&gt;The course is licensed under Creative Commons "Share Alike" license. &lt;a href="https://creativecommons.org/licenses/by-sa/3.0/" rel="noopener noreferrer"&gt;https://creativecommons.org/licenses/by-sa/3.0/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The course is derived from Introduction to Secure Software Engineering class by Gananand Kini et al.&lt;/p&gt;

&lt;p&gt;Check the LICENSE for more details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contribute
&lt;/h2&gt;

&lt;p&gt;Use the &lt;a href="https://github.com/iamibi/Secure-Coding-in-Software-Engineering/issues" rel="noopener noreferrer"&gt;github issues&lt;/a&gt; section to know more.&lt;/p&gt;

</description>
      <category>securecoding</category>
      <category>softwareengineering</category>
      <category>security</category>
      <category>devsecurity</category>
    </item>
    <item>
      <title>Credentials substitution at runtime in Python</title>
      <dc:creator>Syed Mohammad Ibrahim</dc:creator>
      <pubDate>Sat, 01 Apr 2023 23:14:24 +0000</pubDate>
      <link>https://dev.to/iamibi/credentials-substitution-at-runtime-in-python-140k</link>
      <guid>https://dev.to/iamibi/credentials-substitution-at-runtime-in-python-140k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Often we hear that credentials should not be hardcoded in the code or Version Control (like git). You can leverage the dynamic substitution of such credentials using Environment variables tied to the code as a variable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisite
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.8 or up&lt;/li&gt;
&lt;li&gt;PyYaml - To read YAML configuration file&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;yaml&lt;/code&gt; file as the following
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# credentials.yml&lt;/span&gt;

&lt;span class="na"&gt;aws&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;access_key_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${AWS_ACCESS_KEY_ID}"&lt;/span&gt;
  &lt;span class="na"&gt;secret_access_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${AWS_SECRET_ACCESS_KEY}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We will read this &lt;code&gt;yaml&lt;/code&gt; file and get the python dictionary object
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_credentials_file&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;credentials.yml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;cred_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safe_load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cred_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;YAMLError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;yaml_err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unable to read the file. Error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;yaml_err&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We will use the &lt;code&gt;string.Template&lt;/code&gt; from the standard library to substitute the value from the environment variables
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;substitute_creds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access_key_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access_key_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;substitute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="sh"&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;creds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;secret_access_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;secret_access_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;substitute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="sh"&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;ul&gt;
&lt;li&gt;Add the following two variables as part of the environment. They can be added in the &lt;code&gt;.env&lt;/code&gt; file as well
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"abcd1234"&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"secret123"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Complete Program
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_credentials_file&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;credentials.yml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;cred_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safe_load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cred_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;YAMLError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;yaml_err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unable to read the file. Error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;yaml_err&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;substitute_creds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access_key_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access_key_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;substitute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="sh"&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;creds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;secret_access_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;secret_access_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;substitute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;credentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_credentials_file&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;substitute_creds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# WARNING: Never print or log credentials or any sensitive information
&lt;/span&gt;  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Credentials: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The above code when run should produce the following output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python3 main.py
Credentials: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"aws"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"access_key_id"&lt;/span&gt;: &lt;span class="s2"&gt;"abcd1234"&lt;/span&gt;, &lt;span class="s2"&gt;"secret_access_key"&lt;/span&gt;: &lt;span class="s2"&gt;"secret123"&lt;/span&gt;&lt;span class="o"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
      <category>codequality</category>
      <category>security</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to handle different application environments like Prod, Dev, Test, etc.?</title>
      <dc:creator>Syed Mohammad Ibrahim</dc:creator>
      <pubDate>Sat, 01 Apr 2023 17:34:12 +0000</pubDate>
      <link>https://dev.to/iamibi/how-to-handle-different-application-environments-like-prod-dev-test-etc-3h68</link>
      <guid>https://dev.to/iamibi/how-to-handle-different-application-environments-like-prod-dev-test-etc-3h68</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;There are times when we are in a dilemma as to how to properly use application environments. It gets confusing really fast. I will try to explain the approach (that I see) makes sense.&lt;/p&gt;

&lt;p&gt;I will be using Python in this blog, but this implementation is agnostic of the programming language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Python 3.8.x or higher&lt;/li&gt;
&lt;li&gt;PyYaml library - To read our YAML configuration files&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Lets get started!
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;yaml&lt;/code&gt; file just like below
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# settings.yml&lt;/span&gt;
&lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;default&lt;/span&gt;
  &lt;span class="na"&gt;api_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://example.com/dev"&lt;/span&gt;
  &lt;span class="na"&gt;aws&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;aws&lt;/span&gt;
    &lt;span class="na"&gt;s3_bucket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;my-bucket&lt;/span&gt;

&lt;span class="na"&gt;dev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;dev&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;

&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;test&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;api_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://example.com/test"&lt;/span&gt;

&lt;span class="na"&gt;prod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;prod&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;api_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://prod.example.com/"&lt;/span&gt;
  &lt;span class="na"&gt;aws&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*aws&lt;/span&gt;
    &lt;span class="na"&gt;s3_bucket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;my-prod-bucket&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above yaml, we are using the inheritance to override the configurations for individual environments.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To pass the correct configuration, we can leverage &lt;code&gt;argparse&lt;/code&gt; which parses command-line arguments for us. The following python script does that.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_cli_arguments&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="n"&gt;arg_parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ArgumentParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;arg_parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--app-env&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;store&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prod&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dev&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;test&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Application environment to run in&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;arg_parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Next, we read the configuration file based on the environment
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_settings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app_env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;settings.yml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safe_load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;YAMLError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;yaml_err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error occurred while reading the file. Error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;yaml_err&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;app_env&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Reading the configuration dictionary is now as easy as
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.py
&lt;/span&gt;
&lt;span class="n"&gt;settings_prod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_settings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prod&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Prod Configurations: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;settings_prod&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;settings_test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_settings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;test&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Test Configurations: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;settings_test&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Finally, we use this as part of running our &lt;code&gt;main.py&lt;/code&gt; file from the command-line like this
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls
&lt;/span&gt;main.py     settings.yml

&lt;span class="nv"&gt;$ &lt;/span&gt;python3 main.py &lt;span class="nt"&gt;--app-env&lt;/span&gt; prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Complete Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_cli_arguments&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="n"&gt;arg_parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ArgumentParser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;arg_parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--app-env&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;store&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prod&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dev&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;test&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Application environment to run in&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;arg_parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_settings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app_env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;settings.yml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safe_load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;YAMLError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;yaml_err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error occurred while reading the file. Error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;yaml_err&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;app_env&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="c1"&gt;# Program Execution Starts Here
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Read CLI arguments
&lt;/span&gt;  &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_cli_arguments&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="c1"&gt;# Retrieve specific configurations
&lt;/span&gt;  &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_settings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app_env&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;app_env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Configs: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executing the above code on the terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python3 main.py &lt;span class="nt"&gt;--app-env&lt;/span&gt; prod
Configs: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"api_url"&lt;/span&gt;: &lt;span class="s2"&gt;"https://prod.example.com/"&lt;/span&gt;, &lt;span class="s2"&gt;"aws"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"s3_bucket"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"my-prod-bucket"&lt;/span&gt;&lt;span class="o"&gt;]}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cheers!
&lt;/h3&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Add coverage report with pytest and Gitlab CI</title>
      <dc:creator>Syed Mohammad Ibrahim</dc:creator>
      <pubDate>Thu, 16 Mar 2023 14:49:36 +0000</pubDate>
      <link>https://dev.to/iamibi/add-coverage-report-with-pytest-and-gitlab-ci-3e9p</link>
      <guid>https://dev.to/iamibi/add-coverage-report-with-pytest-and-gitlab-ci-3e9p</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this blog, I am going to cover the integration of Pytest with Poetry and then using the coverage to generate a report that is displayed as part of Gitlab file diffs.&lt;/p&gt;

&lt;p&gt;I will be using poetry to install and manage my dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-requisite
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.python.org/" rel="noopener noreferrer"&gt;Python 3.8.x&lt;/a&gt; or higher&lt;/li&gt;
&lt;li&gt;&lt;a href="https://python-poetry.org/docs/" rel="noopener noreferrer"&gt;Poetry 1.4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.pytest.org/en/7.2.x/" rel="noopener noreferrer"&gt;Pytest 7.2.x&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://coverage.readthedocs.io/en/7.2.1/" rel="noopener noreferrer"&gt;Coverage 7.2.1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;An empty Gitlab project/repository with the name &lt;code&gt;gitlab-demo-project&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Setting up the project
&lt;/h2&gt;

&lt;h3&gt;
  
  
  This part assumes that you have Python and Poetry installed and setup in your development environment. Additionally, you have cloned the empty project in your local. All the following instructions are to be done in the root of the cloned project.
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Initialize the current project with poetry using
```bash
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;poetry init&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Follow the on-screen instructions that will allow you to add some necessary information and generate a `pyproject.toml` file to contain your dependency. Your project structure should look something like this
```bash


.
├── README.md
├── pyproject.toml
├── gitlab_demo_project
│   └── __init__.py
└── tests
    └── __init__.py


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Install &lt;code&gt;pytest&lt;/code&gt; and &lt;code&gt;coverage&lt;/code&gt; using poetry under a &lt;code&gt;test&lt;/code&gt; group
```bash
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;poetry install pytest --group test&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;```bash


poetry install coverage --group test


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;In the &lt;code&gt;pyproject.toml&lt;/code&gt; file, add the following lines which are responsible for &lt;code&gt;pytest&lt;/code&gt; and &lt;code&gt;coverage&lt;/code&gt; configurations while running.
```toml
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;[tool.pytest.ini_options]&lt;br&gt;
testpaths = ["tests"]&lt;br&gt;
addopts = "-s -v --durations=0"&lt;br&gt;
cache_dir = ".cache/pytest_cache"&lt;/p&gt;

&lt;p&gt;[tool.coverage.run]&lt;br&gt;
branch = true&lt;br&gt;
source = ["gitlab-demo-project"]&lt;br&gt;
command_line = "-m pytest"&lt;/p&gt;

&lt;p&gt;[tool.coverage.report]&lt;br&gt;
show_missing = true&lt;/p&gt;

&lt;p&gt;[tool.coverage.xml]&lt;br&gt;
output = "coverage.xml"&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
4. Create a file called `.gitlab-ci.yml` in the root of the project and copy the following contents in it
```yaml


default:
  image: python:3.8

stages:
  - test

variables:
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
  POETRY_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pypoetry"
  POETRY_VIRTUALENVS_IN_PROJECT: "true"

cache:
  paths:
    - .cache/pip
    - .cache/pytest_cache
    - .cache/pypoetry
    - .venv

# Install specific version of poetry using pipx
# Poetry installation is recommended through pipx
# https://python-poetry.org/docs/#ci-recommendations
.poetry_setup: &amp;amp;poetry_setup
  before_script:
    - python -V
    - python -m pip install --upgrade pip
    - python -m pip install pipx
    - python -m pipx install poetry==1.4.0
    - export PATH=$PATH:$HOME/.local/bin
    - poetry install

Testing:
  &amp;lt;&amp;lt;: *poetry_setup
  stage: test
  script:
    - poetry run coverage run
    - poetry run coverage report
    - poetry run coverage xml
  coverage: '/TOTAL.*\s+(\d+%)$/'
  artifacts:
    # https://docs.gitlab.com/ee/ci/yaml/index.html#artifactsexpire_in
    expire_in: 1 week

    # https://docs.gitlab.com/ee/ci/testing/test_coverage_visualization.html
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage.xml


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Create a file in your &lt;code&gt;gitlab_demo_project&lt;/code&gt; folder called &lt;code&gt;hello.py&lt;/code&gt; and add the following lines in it
```python
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;def call_hello():&lt;br&gt;
    print("hey, its me!")&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
6. Create a file in your `tests` folder called `test_hello.py` and add the following lines in it
```python


from gitlab_demo_project.hello import call_hello

def test_hello():
    assert call_hello() == "hey, its me!"


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Verify the test case using &lt;code&gt;pytest tests/&lt;/code&gt; command on the terminal.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Checkout a branch using the git bash named &lt;code&gt;testing-gitlab-coverage&lt;/code&gt; and commit all the changes in that branch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once committed, push all the changes to remote and create a merge request. The pipeline should be triggered with the name &lt;code&gt;Testing&lt;/code&gt;. After it succeeds, check the diff of files in the merge request. It should have the following lines appearing&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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%2Fwgyc6jn5jhnt9zp8ctlq.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%2Fwgyc6jn5jhnt9zp8ctlq.png" alt="Test coverage visualization"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;1: Pytest command-line flags &lt;a href="https://docs.pytest.org/en/7.2.x/reference/reference.html#command-line-flags" rel="noopener noreferrer"&gt;https://docs.pytest.org/en/7.2.x/reference/reference.html#command-line-flags&lt;/a&gt;&lt;br&gt;
2: Coverage configurations &lt;a href="https://coverage.readthedocs.io/en/7.2.1/config.html" rel="noopener noreferrer"&gt;https://coverage.readthedocs.io/en/7.2.1/config.html&lt;/a&gt;&lt;br&gt;
3: Gitlab Artifacts &lt;a href="https://docs.gitlab.com/15.9/ee/ci/yaml/" rel="noopener noreferrer"&gt;https://docs.gitlab.com/15.9/ee/ci/yaml/&lt;/a&gt;&lt;br&gt;
4: Gitlab Artifacts Report &lt;a href="https://docs.gitlab.com/15.9/ee/ci/yaml/artifacts_reports.html" rel="noopener noreferrer"&gt;https://docs.gitlab.com/15.9/ee/ci/yaml/artifacts_reports.html&lt;/a&gt;&lt;br&gt;
5: Gitlab Test Coverage visualization image &lt;a href="https://docs.gitlab.com/ee/ci/testing/img/test_coverage_visualization_v12_9.png" rel="noopener noreferrer"&gt;https://docs.gitlab.com/ee/ci/testing/img/test_coverage_visualization_v12_9.png&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>python</category>
    </item>
    <item>
      <title>Mocking AWS Dynamo Db calls during testing</title>
      <dc:creator>Syed Mohammad Ibrahim</dc:creator>
      <pubDate>Sun, 24 Apr 2022 03:16:24 +0000</pubDate>
      <link>https://dev.to/iamibi/mocking-aws-dynamo-db-calls-during-testing-5in</link>
      <guid>https://dev.to/iamibi/mocking-aws-dynamo-db-calls-during-testing-5in</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;It is always a good idea to write test cases for your application when you build any new feature or the application from scratch itself. Testing allows your code to be more bug free and gives a clear sense of where the development should go and if there are any bottlenecks involved.&lt;/p&gt;

&lt;p&gt;In this space, I am going to go over the basics of how to mock AWS Dynamo DB calls in while testing in Python. I will be using the &lt;strong&gt;moto&lt;/strong&gt; library to do that.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;I will be using Python version 3.9.x for the demonstration and following additional libraries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pytest - version 7.1.1&lt;/li&gt;
&lt;li&gt;moto - version 3.1.5&lt;/li&gt;
&lt;li&gt;boto3 - version 1.21.45&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will be using &lt;a href="https://docs.python.org/3.9/library/venv.html"&gt;virtualenv&lt;/a&gt; to manage my packages, but you are open to use whatever seems appropriate.&lt;/p&gt;

&lt;p&gt;To install these libraries, use the following commands on your terminal or command prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install pytest==7.1.1.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Installs pytest version 7.1.1&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install moto[all]==3.1.5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Installs moto version 3.1.5 with all of it's dependencies. The &lt;strong&gt;moto&lt;/strong&gt; library can mock a lot of AWS services. For installing all of it's dependencies - which it doesn't install by default - we need to add the &lt;strong&gt;[all]&lt;/strong&gt; part while installing it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install boto3==1.21.45
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Installs boto3 version 1.21.45&lt;/p&gt;

&lt;p&gt;You can check out the complete list of requirements for this project on my &lt;a href="https://github.com/iamibi/Mock-AWS-Services/tree/MockDynamoDbExample/"&gt;GitHub&lt;/a&gt; page.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;The project structure for this demo is going to look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MockDynamoDbExample
├── __init__.py
├── src
│   ├── __init__.py
│   └── service.py
└── test
    ├── __init__.py
    └── test_service.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;Let's start implementing the mocks. &lt;/p&gt;

&lt;p&gt;First, create a base folder (in my case, it is MockDynamoDbExample). Then create two sub-folders &lt;strong&gt;src&lt;/strong&gt; and &lt;strong&gt;test&lt;/strong&gt;. As the name suggest, &lt;strong&gt;src&lt;/strong&gt; will contain the code which needs to be tested and &lt;strong&gt;test&lt;/strong&gt; will contain our tests to the given source code.&lt;/p&gt;

&lt;p&gt;Next, we need a running service that will more or less reflect the operations we want to perform in the real world. Create empty &lt;code&gt;__init__.py&lt;/code&gt; and &lt;code&gt;service.py&lt;/code&gt; files in the &lt;strong&gt;src&lt;/strong&gt; folder. The &lt;code&gt;__init__.py&lt;/code&gt; is created so that the current folder is treated as a module. We are not going to edit that file. By just existing, the file indicates to the Python Interpreter that the current folder is a module. The &lt;code&gt;service.py&lt;/code&gt; file is where we are going to write the source code that requires testing.&lt;/p&gt;

&lt;p&gt;Let's start by writing all the imports and the constructor method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from boto3.dynamodb.conditions import Key
import boto3


class Service:
    __dynamodb = None
    __table = None

    def __init__(self, table_name: str, env="dev") -&amp;gt; None:
        """
        Initiates an object of this class

        :param table_name: The table this service is going to perform CRUD operations for.
        :param env: The environment context the application is running in.
        """

        # Create a boto3 resource for local instance of dynamodb
        resource = {"region_name": "us-east-2"}
        if env == "dev":
            resource["endpoint_url"] = "http://localhost:8000"
        self.__dynamodb = boto3.resource("dynamodb", **resource)

        # Get the table
        self.__get_table(table_name)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The gist of the code in the constructor method is that it creates a &lt;code&gt;boto3.resource&lt;/code&gt; instance depending on the &lt;code&gt;env&lt;/code&gt; value passed. During testing, we won't be deploying an instance of Dynamo Db, that's why I had put an &lt;code&gt;env&lt;/code&gt; check. You are free to play around with it.&lt;/p&gt;

&lt;p&gt;Let's implement the &lt;code&gt;__get_table&lt;/code&gt; method which is responsible for either getting us the table, if it exists or create a new one. Copy the below code in the same class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def __get_table(self, table_name: str):
    # Get the table from the dynamodb instance
    self.__table = self.__dynamodb.Table(table_name)

    try:
        # Check whether the table exists or not
        self.__table.table_status
    except:
        # If the table doesn't exist, an exception will be thrown.
        # Create the table if that happens.
        print("The table user doesn't exist. Creating now...")
        self.__create_table(table_name)

def __create_table(self, table_name: str):
    try:
        table = self.__dynamodb.create_table(
            TableName=table_name,
            KeySchema=[
                {"AttributeName": "username", "KeyType": "HASH"},
                {"AttributeName": "age", "KeyType": "RANGE"},
            ],
            AttributeDefinitions=[
                {
                    "AttributeName": "username",
                    "AttributeType": "S",
                },
                {
                    "AttributeName": "age",
                    "AttributeType": "N",
                },
            ],
            ProvisionedThroughput={
                "ReadCapacityUnits": 1,
                "WriteCapacityUnits": 1,
            },
        )

        # Wait until the table exits
        table.wait_until_exists()
    except Exception:
        raise Exception(f"Unable to create the table {table_name}")

    # Set the instance variable to the new table created
    self.__table = table

def delete_table(self):
    self.__table.delete()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To give an overview, our table contains a primary-key &lt;code&gt;username&lt;/code&gt; which is of key type &lt;code&gt;HASH&lt;/code&gt; and &lt;code&gt;age&lt;/code&gt; as a key type of &lt;code&gt;RANGE&lt;/code&gt;. I am using the &lt;code&gt;create_table&lt;/code&gt; method that is provided as part of the &lt;code&gt;boto3.resource&lt;/code&gt; instance to create the desired table. The upstream code, namely &lt;code&gt;__get_table&lt;/code&gt; method is responsible for checking whether the table exists in the first place or not. If it does, we return early with it's instance.&lt;/p&gt;

&lt;p&gt;Now, we implement all the CRUD operations that are required to perform the task for the database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def create_user(self, username: str, email: str, age: int, first_name: str, last_name: str):
    user_obj = {
        "username": username,
        "email": email,
        "age": age,
        "first_name": first_name,
        "last_name": last_name
    }

    # Insert the data into table
    self.__table.put_item(Item=user_obj)

def get_user_by_username(self, username: str):
    response = self.__table.query(
        KeyConditionExpression=Key("username").eq(username)
    )
    items = response["Items"]

    # Return none, if the length of the items list is not 1
    if len(items) != 1:
        return None

    # Return the value fetched from the database
    return items[0]

def delete_user_by_username(self, username: str):
    response = self.__table.delete_item(
        Key={"username": username}
    )

    return response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above CRUD operations can vary depending on your use case. For the purpose of this blog, I will be using these basic operations. You can implement your own CRUD operations by following &lt;a href="https://boto3.amazonaws.com/v1/documentation/api/latest/guide/dynamodb.html"&gt;this&lt;/a&gt; link.&lt;/p&gt;

&lt;p&gt;The complete &lt;code&gt;service.py&lt;/code&gt; file should look like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from boto3.dynamodb.conditions import Key
import boto3


class Service:
    __dynamodb = None
    __table = None

    def __init__(self, table_name: str, env="dev") -&amp;gt; None:
        """
        Initiates an object of this class

        :param table_name: The table this service is going to perform CRUD operations for.
        :param env: The environment context the application is running in.
        """

        # Create a boto3 resource for local instance of dynamodb
        resource = {"region_name": "us-east-2"}
        if env == "dev":
            resource["endpoint_url"] = "http://localhost:8000"
        self.__dynamodb = boto3.resource("dynamodb", **resource)

        # Get the table
        self.__get_table(table_name)

    def __get_table(self, table_name: str):
        # Get the table from the dynamodb instance
        self.__table = self.__dynamodb.Table(table_name)

        try:
            # Check whether the table exists or not
            self.__table.table_status
        except:
            # If the table doesn't exist, an exception will be thrown.
            # Create the table if that happens.
            print("The table user doesn't exist. Creating now...")
            self.__create_table(table_name)

    def __create_table(self, table_name: str):
        try:
            table = self.__dynamodb.create_table(
                TableName=table_name,
                KeySchema=[
                    {"AttributeName": "username", "KeyType": "HASH"},
                    {"AttributeName": "age", "KeyType": "RANGE"},
                ],
                AttributeDefinitions=[
                    {
                        "AttributeName": "username",
                        "AttributeType": "S",
                    },
                    {
                        "AttributeName": "age",
                        "AttributeType": "N",
                    },
                ],
                ProvisionedThroughput={
                    "ReadCapacityUnits": 1,
                    "WriteCapacityUnits": 1,
                },
            )

            # Wait until the table exits
            table.wait_until_exists()
        except Exception:
            raise Exception(f"Unable to create the table {table_name}")

        # Set the instance variable to the new table created
        self.__table = table

    def delete_table(self):
        self.__table.delete()

    def create_user(self, username: str, email: str, age: int, first_name: str, last_name: str):
        user_obj = {
            "username": username,
            "email": email,
            "age": age,
            "first_name": first_name,
            "last_name": last_name
        }

        # Insert the data into table
        self.__table.put_item(Item=user_obj)

    def get_user_by_username(self, username: str):
        response = self.__table.query(
            KeyConditionExpression=Key("username").eq(username)
        )
        items = response["Items"]

        # Return none, if the length of the items list is not 1
        if len(items) != 1:
            return None

        # Return the value fetched from the database
        return items[0]

    def delete_user_by_username(self, username: str):
        response = self.__table.delete_item(
            Key={"username": username}
        )

        return response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generally, I use double-underscore's in front of methods that will be used internally within a class and are not required outside of it. I feel this to be a good coding standard. However, you are open to use the way you feel like.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Moving to the testing of this service, create two files &lt;code&gt;__init__.py&lt;/code&gt; and &lt;code&gt;test_service.py&lt;/code&gt; files under the &lt;strong&gt;test&lt;/strong&gt; directory. As with the &lt;strong&gt;src&lt;/strong&gt; files, the &lt;code&gt;__init__.py&lt;/code&gt; will be used for setting the current directory as module and will be empty. The &lt;code&gt;test_service.py&lt;/code&gt; will be where our test code is going to be.&lt;/p&gt;

&lt;p&gt;I am using a combination of pytest and unittest modules to perform testing.&lt;/p&gt;

&lt;p&gt;Let's start by writing the &lt;code&gt;setUp&lt;/code&gt; and &lt;code&gt;tearDown&lt;/code&gt; methods. These methods are automatically whenever a test case is executed from the test suite.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from MockDynamoDbExample.src.service import Service
from moto import mock_dynamodb
from unittest import TestCase


@mock_dynamodb
class TestService(TestCase):
    def setUp(self) -&amp;gt; None:
        """Method called before every test case is executed"""

        # Create an instance of the Service class
        self.service = Service("user", env="test")

    def tearDown(self) -&amp;gt; None:
        """Method called after every test case has finished execution"""

        # Clear the table after use
        self.service.delete_table()

        # Reset the service variable
        self.service = None
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am importing few things here, like the &lt;code&gt;Service&lt;/code&gt; class that we implemented, the &lt;code&gt;mock_dynamodb&lt;/code&gt; decorator from the &lt;code&gt;moto&lt;/code&gt; library and &lt;code&gt;TestCase&lt;/code&gt; from the &lt;code&gt;unittest&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;mock_dynamodb&lt;/code&gt; is going to be helpful in mocking all of our Dynamo Db related calls. This import will be used as a decorator. To learn more about decorators in general, follow  &lt;a href="https://realpython.com/primer-on-python-decorators/"&gt;this&lt;/a&gt; link.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;setUp&lt;/code&gt; method, we are creating a &lt;code&gt;Service&lt;/code&gt; class instance with &lt;code&gt;"user"&lt;/code&gt; as the table name and environment as &lt;code&gt;"test"&lt;/code&gt;. The &lt;code&gt;tearDown&lt;/code&gt; method implements the cleanup functionality. Both of these methods are called before and after every test case respectively.&lt;/p&gt;

&lt;p&gt;Moving on, the following code implements the first test case which tests for &lt;code&gt;create_user&lt;/code&gt; method in services&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def test_create_user(self):
    username = "test-mike"
    age = 19
    first_name = "Mike"
    last_name = "Ross"
    email = "test_mike@example.com"

    try:
        self.service.create_user(username, email, age, first_name, last_name)
    except Exception as exc:
        assert False, f"service.create_user raised an exception {exc}"
    assert True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are testing the creation success using &lt;code&gt;assert True&lt;/code&gt; at the end.&lt;/p&gt;

&lt;p&gt;Let's run the test case by going over to the terminal or command prompt. Make sure that you are in the root directory of this project while executing the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pytest test/test_service.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should print out the following on Linux system&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(venv) ibi@ibi:~/MockDynamoDbExample$ pytest MockDynamoDbExample/test/test_service.py 
======================================================================================== test session starts =========================================================================================
platform linux -- Python 3.9.12, pytest-7.1.1, pluggy-1.0.0
rootdir: /home/ibi/MockDynamoDbExample
collected 1 items                                                                                                                                                                                    

MockDynamoDbExample/test/test_service.py ...                                                                                                                                                   [100%]

========================================================================================= 1 passed in 1.46s ==========================================================================================
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For windows powershell, the output should look like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(venv) PS D:\MockDynamoDbExample&amp;gt; pytest test\test_service.py
================================================= test session starts =================================================
platform win32 -- Python 3.9.10, pytest-7.1.1, pluggy-1.0.0
rootdir: D:\MockDynamoDbExample
collected 1 items

test\test_service.py ...                                                                                         [100%]

================================================== 1 passed in 1.63s ==================================================
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding another test case to test getting a user by username.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def test_get_user_by_username(self):
    username = "test-mike"
    age = 19
    first_name = "Mike"
    last_name = "Ross"
    email = "test_mike@example.com"

    # Create a user in the database
    try:
        self.service.create_user(username, email, age, first_name, last_name)
    except Exception as exc:
        assert False, f"service.create_user raised an exception {exc}"

    # Get the user by username from the database
    try:
        response = self.service.get_user_by_username(username)
    except Exception as exc:
        assert False, f"service.get_user_by_username raised an exception {exc}"

    # Verify the details
    assert response is not None
    assert response["username"] == username
    assert response["age"] == age
    assert response["email"] == email
    assert response["first_name"] == first_name
    assert response["last_name"] == last_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this test case, we are testing the insertion and fetch performed by Dynamo Db.&lt;/p&gt;

&lt;p&gt;The complete file should look like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from MockDynamoDbExample.src.service import Service
from moto import mock_dynamodb
from unittest import TestCase


@mock_dynamodb
class TestService(TestCase):
    def setUp(self) -&amp;gt; None:
        """Method called before every test case is executed"""

        # Create an instance of the Service class
        self.service = Service("user", env="test")

    def tearDown(self) -&amp;gt; None:
        """Method called after every test case has finished execution"""

        # Clear the table after use
        self.service.delete_table()

        # Reset the service variable
        self.service = None

    def test_create_user(self):
        username = "test-mike"
        age = 19
        first_name = "Mike"
        last_name = "Ross"
        email = "test_mike@example.com"

        try:
            self.service.create_user(username, email, age, first_name, last_name)
        except Exception as exc:
            assert False, f"service.create_user raised an exception {exc}"
        assert True

    def test_get_user_by_username(self):
        username = "test-mike"
        age = 19
        first_name = "Mike"
        last_name = "Ross"
        email = "test_mike@example.com"

        # Create a user in the database
        try:
            self.service.create_user(username, email, age, first_name, last_name)
        except Exception as exc:
            assert False, f"service.create_user raised an exception {exc}"

        # Get the user by username from the database
        try:
            response = self.service.get_user_by_username(username)
        except Exception as exc:
            assert False, f"service.get_user_by_username raised an exception {exc}"

        # Verify the details
        assert response is not None
        assert response["username"] == username
        assert response["age"] == age
        assert response["email"] == email
        assert response["first_name"] == first_name
        assert response["last_name"] == last_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, if you don't want to use a class based approach and would like to write independent functions then you can do the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@mock_dynamodb
def test_create_user():
    service = Service("user", "test")
    username = "test-mike"
    age = 19
    first_name = "Mike"
    last_name = "Ross"
    email = "test_mike@example.com"

    try:
        service.create_user(username, email, age, first_name, last_name)
    except Exception as exc:
        assert False, f"service.create_user raised an exception {exc}"
    assert True
    service.delete_table()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, it can get a little tedious if you have a lot of test cases to write with a start and end common functionality.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;moto&lt;/strong&gt; is an amazing library to mock any AWS Dynamo DB based calls. You can check out the development on their &lt;a href="https://github.com/spulec/moto"&gt;GitHub&lt;/a&gt; page.&lt;/p&gt;

&lt;p&gt;A trivia, prior to the &lt;strong&gt;moto&lt;/strong&gt; library version 3.1.0, the mock decorator to be used was &lt;code&gt;@mock_dynamodb2&lt;/code&gt;. Make sure if you are using the version prior to 3.1.0, use this decorator instead or update to the version I used in this blog.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

</description>
      <category>dynamodb</category>
      <category>moto</category>
      <category>testing</category>
      <category>python</category>
    </item>
  </channel>
</rss>
