<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Web Security on Software Engineering Learning Paths</title><link>https://kyngo.github.io/learning-paths/paths/web-security/</link><description>Recent content in Web Security on Software Engineering Learning Paths</description><generator>Hugo</generator><language>en</language><atom:link href="https://kyngo.github.io/learning-paths/paths/web-security/index.xml" rel="self" type="application/rss+xml"/><item><title>Web Security Fundamentals</title><link>https://kyngo.github.io/learning-paths/paths/web-security/01-fundamentals/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/web-security/01-fundamentals/</guid><description>&lt;h2 id="why-web-security-matters"&gt;Why Web Security Matters&lt;a class="anchor" href="#why-web-security-matters"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Every web application exposed to the internet is under constant attack. Automated scanners probe for vulnerabilities within minutes of a new service going live. A single SQL injection or misconfigured header can expose millions of user records, destroy a company&amp;rsquo;s reputation, and trigger regulatory fines measured in percentages of global revenue.&lt;/p&gt;
&lt;p&gt;Security is not a feature — it is a property of the system. You cannot bolt it on at the end. This section establishes the foundational mental models that underpin every subsequent topic.&lt;/p&gt;</description></item><item><title>Injection Attacks</title><link>https://kyngo.github.io/learning-paths/paths/web-security/02-injection-attacks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/web-security/02-injection-attacks/</guid><description>&lt;h2 id="what-is-injection"&gt;What Is Injection?&lt;a class="anchor" href="#what-is-injection"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Injection occurs when untrusted data is sent to an interpreter as part of a command or query. The interpreter cannot distinguish between intended instructions and injected instructions. This has been the most devastating class of web vulnerability for over two decades.&lt;/p&gt;
&lt;p&gt;The root cause is always the same: &lt;strong&gt;string concatenation of user input into a structured language&lt;/strong&gt; (SQL, shell, LDAP, NoSQL query).&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="sql-injection"&gt;SQL Injection&lt;a class="anchor" href="#sql-injection"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="how-it-works"&gt;How It Works&lt;a class="anchor" href="#how-it-works"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The application builds a SQL query by concatenating user input directly:&lt;/p&gt;</description></item><item><title>Cross-Site Scripting (XSS)</title><link>https://kyngo.github.io/learning-paths/paths/web-security/03-cross-site-scripting/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/web-security/03-cross-site-scripting/</guid><description>&lt;h2 id="what-is-xss"&gt;What Is XSS?&lt;a class="anchor" href="#what-is-xss"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Cross-Site Scripting (XSS) occurs when an attacker injects malicious scripts into web pages viewed by other users. The victim&amp;rsquo;s browser cannot distinguish between legitimate scripts from the application and injected scripts — it executes both with the same origin and permissions.&lt;/p&gt;
&lt;p&gt;XSS is the most prevalent web vulnerability. It enables session hijacking, credential theft, defacement, phishing, and client-side malware distribution.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="types-of-xss"&gt;Types of XSS&lt;a class="anchor" href="#types-of-xss"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="reflected-xss"&gt;Reflected XSS&lt;a class="anchor" href="#reflected-xss"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The malicious script is part of the HTTP request and reflected back in the response without being stored. The attacker crafts a URL containing the payload and tricks the victim into clicking it.&lt;/p&gt;</description></item><item><title>Authentication</title><link>https://kyngo.github.io/learning-paths/paths/web-security/04-authentication/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/web-security/04-authentication/</guid><description>&lt;h2 id="what-is-authentication"&gt;What Is Authentication?&lt;a class="anchor" href="#what-is-authentication"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Authentication answers one question: &lt;strong&gt;who are you?&lt;/strong&gt; It is the process of verifying that a claimed identity is genuine. Authentication is distinct from authorisation (what you can do), but a failure in authentication makes authorisation meaningless.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="password-storage"&gt;Password Storage&lt;a class="anchor" href="#password-storage"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="the-golden-rule"&gt;The Golden Rule&lt;a class="anchor" href="#the-golden-rule"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Never store passwords in plaintext.&lt;/strong&gt; Never store them encrypted (encryption is reversible). Always store a &lt;strong&gt;one-way hash&lt;/strong&gt; with a unique &lt;strong&gt;salt&lt;/strong&gt; per password.&lt;/p&gt;
&lt;h3 id="how-password-hashing-works"&gt;How Password Hashing Works&lt;a class="anchor" href="#how-password-hashing-works"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;User password: &amp;#34;correct horse battery staple&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌───────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Hashing function │ ← bcrypt, argon2, scrypt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ + unique salt │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ + cost factor │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└────────┬──────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Stored hash: &amp;#34;$2b$12$LJ3m4ys3Lg0Yf7KlZ8K0VePXdRkSEqGNmFCS.sVGBHby/RASY7Y/G&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="algorithm-comparison"&gt;Algorithm Comparison&lt;a class="anchor" href="#algorithm-comparison"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Algorithm&lt;/th&gt;
					&lt;th&gt;Type&lt;/th&gt;
					&lt;th&gt;Memory-Hard&lt;/th&gt;
					&lt;th&gt;Recommended&lt;/th&gt;
					&lt;th&gt;Notes&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Argon2id&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;KDF&lt;/td&gt;
					&lt;td&gt;Yes&lt;/td&gt;
					&lt;td&gt;✅ Best choice&lt;/td&gt;
					&lt;td&gt;Winner of Password Hashing Competition (2015)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;bcrypt&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;KDF&lt;/td&gt;
					&lt;td&gt;No&lt;/td&gt;
					&lt;td&gt;✅ Excellent&lt;/td&gt;
					&lt;td&gt;Battle-tested since 1999, 72-byte password limit&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;scrypt&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;KDF&lt;/td&gt;
					&lt;td&gt;Yes&lt;/td&gt;
					&lt;td&gt;✅ Good&lt;/td&gt;
					&lt;td&gt;Memory-hard, harder to tune than argon2&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PBKDF2&lt;/td&gt;
					&lt;td&gt;KDF&lt;/td&gt;
					&lt;td&gt;No&lt;/td&gt;
					&lt;td&gt;⚠️ Acceptable&lt;/td&gt;
					&lt;td&gt;SHA-256 variant only; GPU-friendly&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;SHA-256&lt;/td&gt;
					&lt;td&gt;Hash&lt;/td&gt;
					&lt;td&gt;No&lt;/td&gt;
					&lt;td&gt;❌ Never&lt;/td&gt;
					&lt;td&gt;No salt, no cost factor, GPU-crackable&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;MD5&lt;/td&gt;
					&lt;td&gt;Hash&lt;/td&gt;
					&lt;td&gt;No&lt;/td&gt;
					&lt;td&gt;❌ Never&lt;/td&gt;
					&lt;td&gt;Broken, collisions found, GPU-crackable&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="implementation"&gt;Implementation&lt;a class="anchor" href="#implementation"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Python (argon2):&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Authorisation</title><link>https://kyngo.github.io/learning-paths/paths/web-security/05-authorisation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/web-security/05-authorisation/</guid><description>&lt;h2 id="authentication-vs-authorisation"&gt;Authentication vs Authorisation&lt;a class="anchor" href="#authentication-vs-authorisation"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Authentication proves &lt;strong&gt;who you are&lt;/strong&gt;. Authorisation determines &lt;strong&gt;what you can do&lt;/strong&gt;. A system can have perfect authentication and still be completely broken if authorisation is missing or bypassable.&lt;/p&gt;
&lt;p&gt;Broken access control was the #1 risk in the OWASP Top 10 (2021), overtaking injection for the first time.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="access-control-models"&gt;Access Control Models&lt;a class="anchor" href="#access-control-models"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="role-based-access-control-rbac"&gt;Role-Based Access Control (RBAC)&lt;a class="anchor" href="#role-based-access-control-rbac"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Permissions are assigned to roles, and users are assigned to roles. Simple, widely understood, and sufficient for most applications.&lt;/p&gt;</description></item><item><title>OAuth 2.0 &amp; OpenID Connect</title><link>https://kyngo.github.io/learning-paths/paths/web-security/06-oauth-openid-connect/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/web-security/06-oauth-openid-connect/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;a class="anchor" href="#overview"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;OAuth 2.0&lt;/strong&gt; is an authorisation framework that allows third-party applications to obtain limited access to a user&amp;rsquo;s resources without exposing their credentials. &lt;strong&gt;OpenID Connect (OIDC)&lt;/strong&gt; is an identity layer built on top of OAuth 2.0 that adds authentication.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Protocol&lt;/th&gt;
					&lt;th&gt;Purpose&lt;/th&gt;
					&lt;th&gt;Result&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;OAuth 2.0&lt;/td&gt;
					&lt;td&gt;Authorisation (what can the app do?)&lt;/td&gt;
					&lt;td&gt;Access Token&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;OpenID Connect&lt;/td&gt;
					&lt;td&gt;Authentication (who is the user?)&lt;/td&gt;
					&lt;td&gt;ID Token + Access Token&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="oauth-20-roles"&gt;OAuth 2.0 Roles&lt;a class="anchor" href="#oauth-20-roles"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Role&lt;/th&gt;
					&lt;th&gt;Description&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Resource Owner&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;The user who owns the data&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Client&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;The application requesting access&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Authorization Server&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Issues tokens (e.g., Keycloak, Auth0, Okta)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Resource Server&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;The API that holds protected resources&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="grant-types"&gt;Grant Types&lt;a class="anchor" href="#grant-types"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="authorization-code-with-pkce--recommended-for-all-clients"&gt;Authorization Code (with PKCE) — Recommended for All Clients&lt;a class="anchor" href="#authorization-code-with-pkce--recommended-for-all-clients"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is the &lt;strong&gt;only recommended grant&lt;/strong&gt; for browser-based and mobile applications. PKCE (Proof Key for Code Exchange) prevents authorisation code interception.&lt;/p&gt;</description></item><item><title>CSRF &amp; Other Attacks</title><link>https://kyngo.github.io/learning-paths/paths/web-security/07-csrf-and-other-attacks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/web-security/07-csrf-and-other-attacks/</guid><description>&lt;h2 id="cross-site-request-forgery-csrf"&gt;Cross-Site Request Forgery (CSRF)&lt;a class="anchor" href="#cross-site-request-forgery-csrf"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;CSRF tricks a victim&amp;rsquo;s browser into making an unwanted request to a site where the victim is authenticated. The browser automatically attaches cookies (including session cookies), so the server cannot distinguish between a legitimate request and a forged one.&lt;/p&gt;
&lt;h3 id="how-csrf-works"&gt;How CSRF Works&lt;a class="anchor" href="#how-csrf-works"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. Victim logs into bank.com (session cookie set)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. Victim visits evil.com
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. evil.com contains:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;lt;form action=&amp;#34;https://bank.com/transfer&amp;#34; method=&amp;#34;POST&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;lt;input type=&amp;#34;hidden&amp;#34; name=&amp;#34;to&amp;#34; value=&amp;#34;attacker&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;lt;input type=&amp;#34;hidden&amp;#34; name=&amp;#34;amount&amp;#34; value=&amp;#34;10000&amp;#34;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;lt;/form&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;lt;script&amp;gt;document.forms[0].submit()&amp;lt;/script&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. Browser sends the POST to bank.com WITH the session cookie
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;5. bank.com processes the transfer — it sees a valid session&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="csrf-attack-variants"&gt;CSRF Attack Variants&lt;a class="anchor" href="#csrf-attack-variants"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Vector&lt;/th&gt;
					&lt;th&gt;Technique&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Auto-submitting form&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; + &lt;code&gt;&amp;lt;script&amp;gt;document.forms[0].submit()&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Image tag (GET only)&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;&amp;lt;img src=&amp;quot;https://bank.com/transfer?to=attacker&amp;amp;amount=10000&amp;quot;&amp;gt;&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;XMLHttpRequest&lt;/td&gt;
					&lt;td&gt;Blocked by CORS for non-simple requests, but simple requests (form POST) pass&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Fetch API&lt;/td&gt;
					&lt;td&gt;Same CORS restrictions apply&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="prevention-samesite-cookies"&gt;Prevention: SameSite Cookies&lt;a class="anchor" href="#prevention-samesite-cookies"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;SameSite&lt;/code&gt; cookie attribute controls when cookies are sent with cross-site requests:&lt;/p&gt;</description></item><item><title>Transport Security</title><link>https://kyngo.github.io/learning-paths/paths/web-security/08-transport-security/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/web-security/08-transport-security/</guid><description>&lt;h2 id="why-transport-security-matters"&gt;Why Transport Security Matters&lt;a class="anchor" href="#why-transport-security-matters"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Data in transit is vulnerable to interception, modification, and replay. Without transport security, an attacker on the same network (coffee shop Wi-Fi, compromised router, ISP-level surveillance) can read passwords, session tokens, and personal data in plaintext.&lt;/p&gt;
&lt;p&gt;Transport security is not optional — it is the foundation on which all other web security controls depend.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="tls-transport-layer-security"&gt;TLS (Transport Layer Security)&lt;a class="anchor" href="#tls-transport-layer-security"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;TLS encrypts the communication channel between client and server. HTTPS is HTTP over TLS.&lt;/p&gt;</description></item><item><title>API Security</title><link>https://kyngo.github.io/learning-paths/paths/web-security/09-api-security/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/web-security/09-api-security/</guid><description>&lt;h2 id="why-api-security-is-different"&gt;Why API Security Is Different&lt;a class="anchor" href="#why-api-security-is-different"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;APIs are the primary attack surface of modern applications. Unlike server-rendered pages, APIs expose raw business logic directly. They are consumed by browsers, mobile apps, third-party integrations, and automated scripts — each with different trust levels.&lt;/p&gt;
&lt;p&gt;The OWASP API Security Top 10 (2023) highlights risks specific to APIs that the standard Top 10 does not adequately cover.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="input-validation"&gt;Input Validation&lt;a class="anchor" href="#input-validation"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Every API endpoint must validate every input. Never trust the client — not the browser, not the mobile app, not a trusted partner&amp;rsquo;s integration.&lt;/p&gt;</description></item><item><title>Security Testing &amp; Operations</title><link>https://kyngo.github.io/learning-paths/paths/web-security/10-security-testing-operations/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kyngo.github.io/learning-paths/paths/web-security/10-security-testing-operations/</guid><description>&lt;h2 id="security-in-the-development-lifecycle"&gt;Security in the Development Lifecycle&lt;a class="anchor" href="#security-in-the-development-lifecycle"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Security testing is not a one-time gate before release. It is a continuous process woven into every stage of the software development lifecycle — from the first line of code to production monitoring.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;┌─────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Code │──▶│ Build │──▶│ Test │──▶│ Deploy │──▶│ Monitor │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ │ │ │ │ │ │ │ │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ SAST │ │ SCA │ │ DAST │ │ Headers │ │ WAF logs │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Linting │ │ License │ │ Pentest │ │ TLS │ │ Alerting │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ Secrets │ │ SBOM │ │ Fuzzing │ │ Config │ │ Incident │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─────────┘ └──────────┘ └──────────┘ └──────────┘ └───────────┘&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="sast-static-application-security-testing"&gt;SAST (Static Application Security Testing)&lt;a class="anchor" href="#sast-static-application-security-testing"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;SAST analyses source code (or bytecode) without executing it. It finds vulnerabilities in the code itself — injection flaws, hardcoded secrets, insecure configurations.&lt;/p&gt;</description></item></channel></rss>