<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Go on guy@secdev.uk</title>
    <link>https://www.secdev.uk/blog/tags/go/</link>
    <description>Recent content in Go on guy@secdev.uk</description>
    <generator>Hugo</generator>
    <language>en-gb</language>
    <copyright>Guy Dixon | guy@secdev.uk</copyright>
    <lastBuildDate>Sat, 28 Feb 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://www.secdev.uk/blog/tags/go/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Deserialization Attacks: From Pickle to ObjectInputStream</title>
      <link>https://www.secdev.uk/blog/technology/2026-02-28-deserialization-attacks/</link>
      <pubDate>Sat, 28 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2026-02-28-deserialization-attacks/</guid>
      <description>&lt;p&gt;Deserialization vulnerabilities are some of the scariest bugs in application security, because when they&amp;rsquo;re exploitable, it&amp;rsquo;s almost always remote code execution. The core problem is that an application reconstructs objects from untrusted data without validating what types are being instantiated. In languages with powerful serialization mechanisms &amp;ndash; Python&amp;rsquo;s &lt;code&gt;pickle&lt;/code&gt;, Java&amp;rsquo;s &lt;code&gt;ObjectInputStream&lt;/code&gt;, PHP&amp;rsquo;s &lt;code&gt;unserialize&lt;/code&gt; &amp;ndash; an attacker can craft serialized payloads that execute arbitrary code during the deserialization process itself. The more I researched how these attacks work across languages, the more I appreciated how a single API call can turn into a full server compromise.&lt;/p&gt;</description>
    </item>
    <item>
      <title>CORS Misconfiguration: The Open Door You Didn&#39;t Know About</title>
      <link>https://www.secdev.uk/blog/technology/2026-02-14-cors-misconfiguration/</link>
      <pubDate>Sat, 14 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2026-02-14-cors-misconfiguration/</guid>
      <description>&lt;p&gt;CORS misconfiguration is one of those vulnerabilities that keeps coming up because most developers don&amp;rsquo;t fully understand what CORS actually does. It&amp;rsquo;s the browser mechanism that controls which websites can make requests to your API. When it&amp;rsquo;s configured correctly, it prevents malicious sites from stealing data through a victim&amp;rsquo;s browser. When it&amp;rsquo;s misconfigured, and this happens constantly based on public bug bounty reports, it effectively disables the Same-Origin Policy, letting any website read authenticated responses from your API. What makes CORS misconfigurations particularly interesting to study is that they&amp;rsquo;re invisible to users, silent in server logs, and trivial to exploit.&lt;/p&gt;</description>
    </item>
    <item>
      <title>XXE Attacks: XML Parsing Gone Wrong</title>
      <link>https://www.secdev.uk/blog/technology/2026-01-31-xxe-attacks/</link>
      <pubDate>Sat, 31 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2026-01-31-xxe-attacks/</guid>
      <description>&lt;p&gt;XML External Entity injection is one of those vulnerabilities that fascinated me the more I dug into it. The core issue is that the XML spec supports external entities, a feature that lets XML documents pull in content from external sources, and most parsers enable this by default. When an app parses untrusted XML without disabling that feature, an attacker can read arbitrary files off the server, perform SSRF, and sometimes even get remote code execution. What surprised me most when researching this was how straightforward the exploitation is compared to how long these bugs survive in production, the attack payloads are simple, but the parser defaults are so permissive that developers often have no idea the risk exists.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Secrets in Source Code: Finding and Eliminating Hardcoded Credentials</title>
      <link>https://www.secdev.uk/blog/technology/2026-01-17-secrets-in-source-code/</link>
      <pubDate>Sat, 17 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2026-01-17-secrets-in-source-code/</guid>
      <description>&lt;p&gt;Hardcoded credentials are one of the most common and most preventable vulnerability classes out there. API keys, database passwords, encryption keys, and service tokens embedded directly in source code end up in version control, build artifacts, container images, and log files. Once a secret reaches a Git repository, it persists in the history even after the offending line is deleted. When I started researching how often this happens in practice, the numbers were staggering, public reports of leaked credentials on GitHub alone run into the millions per year. In this post I&amp;rsquo;ll cover the patterns that lead to hardcoded secrets, the tools that detect them, and the architecture changes that eliminate them for good.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Go Learning Guide</title>
      <link>https://www.secdev.uk/blog/articles/go-guide/</link>
      <pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/articles/go-guide/</guid>
      <description>&lt;p&gt;A structured learning guide for developers coming from Java, C, or Python who want to learn Go. I put this together because when I started learning Go myself, I kept wishing for a resource that mapped Go&amp;rsquo;s idioms back to languages I already knew.&#xA;&lt;a href=&#34;https://github.com/guyadixon/GoLearning&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&#xA;    Github Repo of Code Examples&#xA;&lt;/a&gt;&#xA;&lt;/p&gt;&#xA;&lt;h2 id=&#34;introduction-to-go&#34;&gt;Introduction to Go&lt;/h2&gt;&#xA;&lt;p&gt;Go (also called Golang) was created at Google in 2009 by Robert Griesemer, Rob Pike, and Ken Thompson. It was designed to address the challenges of building large-scale, concurrent software systems while keeping the language simple and productive.&lt;/p&gt;</description>
    </item>
    <item>
      <title>String Formatting and Security: A Cross-Language Minefield</title>
      <link>https://www.secdev.uk/blog/technology/2026-01-03-string-formatting-and-security/</link>
      <pubDate>Sat, 03 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2026-01-03-string-formatting-and-security/</guid>
      <description>&lt;p&gt;String formatting is one of those operations that&amp;rsquo;s everywhere, and it&amp;rsquo;s more dangerous than most developers realise when user input gets involved. Every language provides multiple ways to build strings from dynamic data, and each mechanism carries different security implications. From C&amp;rsquo;s &lt;code&gt;printf&lt;/code&gt; family, where a format string bug can read and write arbitrary memory, to Python&amp;rsquo;s f-strings that can execute attribute lookups, the attack surface is broader than most people think. I wanted to map out the full landscape across languages, and what I found was that each mechanism breaks down in its own unique and sometimes surprising way.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SAST Tools Compared: What They Catch and What They Miss</title>
      <link>https://www.secdev.uk/blog/technology/2025-12-20-sast-tools-compared/</link>
      <pubDate>Sat, 20 Dec 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-12-20-sast-tools-compared/</guid>
      <description>&lt;p&gt;Static Application Security Testing (SAST) tools are the first line of automated defence against vulnerabilities in source code. They analyse code without executing it, looking for patterns that match known vulnerability classes. But here&amp;rsquo;s the thing, no single tool catches everything, and the differences between tools in detection capability, false positive rates, and language support are significant. I wanted to understand exactly where the gaps are, so I spent time running these tools against intentionally vulnerable code and comparing their output. This post is my honest assessment of what they actually catch, what they miss, and where manual review has to pick up the slack.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Art of the Subtle Bug: Nuanced Vulnerabilities That Evade Review</title>
      <link>https://www.secdev.uk/blog/technology/2025-12-06-the-art-of-the-subtle-bug/</link>
      <pubDate>Sat, 06 Dec 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-12-06-the-art-of-the-subtle-bug/</guid>
      <description>&lt;p&gt;The vulnerabilities that cause real breaches are rarely the textbook examples. They&amp;rsquo;re the ones that survive multiple rounds of code review, pass SAST scans, and sit in production for years. The more I researched these nuanced bugs, the more I realised what makes them dangerous: they exploit assumptions reviewers make about language behaviour, framework internals, or data flow boundaries. This post dissects the patterns that make a vulnerability subtle and walks through real examples that show why even experienced reviewers still miss them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Go Security: Goroutines, Error Handling, and Hidden Bugs</title>
      <link>https://www.secdev.uk/blog/technology/2025-09-27-go-security-goroutines-errors/</link>
      <pubDate>Sat, 27 Sep 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-09-27-go-security-goroutines-errors/</guid>
      <description>&lt;p&gt;Go&amp;rsquo;s simplicity is its greatest strength and, I&amp;rsquo;d argue, its most dangerous security property. The language has no exceptions, no generics-based abstractions (until recently), and no implicit behaviour, everything is explicit. But that explicitness creates its own class of vulnerabilities: unchecked errors that silently skip security validation, goroutine races on shared state, HTTP client defaults that follow redirects into internal networks, and string handling patterns that bypass input validation. In this post, I want to walk through the Go-specific anti-patterns that lead to security vulnerabilities, from the error that nobody checked to the goroutine that corrupted the authentication cache. The more I dug into Go&amp;rsquo;s security landscape, the more I realised these bugs are subtle precisely because the language feels so straightforward.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Race Conditions</title>
      <link>https://www.secdev.uk/blog/technology/2025-08-16-race-conditions/</link>
      <pubDate>Sat, 16 Aug 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-08-16-race-conditions/</guid>
      <description>&lt;p&gt;Race conditions (CWE-362) are, in my opinion, the most insidious class of security bugs you&amp;rsquo;ll encounter. They occur when the behaviour of a program depends on the relative timing of concurrent operations, and at least one of those operations modifies shared state. The window between a check and a subsequent use of the checked value, the classic time-of-check to time-of-use (TOCTOU) pattern, is the most exploited form, but races also show up in counter increments, balance updates, session management, and file operations. What makes race conditions uniquely dangerous is their non-determinism: the bug may not manifest in thousands of test runs, then appear under production load when two requests arrive within microseconds of each other. I want to walk through race conditions in Python, Go, Java, and Rust, from the obvious unprotected counter to the subtle channel-based ordering assumption that passes every test but fails under contention.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Integer Overflow</title>
      <link>https://www.secdev.uk/blog/technology/2025-08-02-integer-overflow/</link>
      <pubDate>Sat, 02 Aug 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-08-02-integer-overflow/</guid>
      <description>&lt;p&gt;Integer overflow (CWE-190) is one of those bugs that I find endlessly fascinating because of how quietly destructive it is. It happens when an arithmetic operation produces a value that exceeds the maximum (or falls below the minimum) representable value for the integer type. In C and C++, signed integer overflow is undefined behaviour, the compiler is free to assume it never happens, and optimizations built on that assumption can eliminate bounds checks entirely. Unsigned overflow wraps around silently. Go and Java define overflow as wrapping (two&amp;rsquo;s complement), which prevents undefined behaviour but still produces incorrect results that lead to security vulnerabilities: undersized allocations, bypassed length checks, and negative indices into arrays. Rust panics on overflow in debug mode but wraps in release mode by default, creating a gap between testing and production behaviour that caught me off guard when I first started digging into Rust&amp;rsquo;s safety guarantees. I want to walk through integer overflow across C, C++, Rust, Go, and Java, from the textbook multiplication overflow to the subtle cast truncation that can survive expert review.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Null Pointer Dereference</title>
      <link>https://www.secdev.uk/blog/technology/2025-07-19-null-pointer-dereference/</link>
      <pubDate>Sat, 19 Jul 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-07-19-null-pointer-dereference/</guid>
      <description>&lt;p&gt;Null pointer dereference (CWE-476) is one of those bugs that shows up across every language, and the more I researched it for this post, the more I was struck by how much damage it can do depending on context. The consequences vary dramatically: C programs crash with a segfault (or worse, the kernel maps page zero and an attacker gets code execution), C++ invokes undefined behaviour that the compiler may optimise into literally anything, Go panics with a nil pointer dereference that kills the goroutine or the whole program, and Java throws a &lt;code&gt;NullPointerException&lt;/code&gt; that can crash the app or leak stack traces to an attacker. MITRE ranks CWE-476 consistently in the top 25 most dangerous software weaknesses, and digging into the CVE data, that ranking is well deserved. I want to walk through C, C++, Go, and Java here, from the obvious unchecked &lt;code&gt;malloc&lt;/code&gt; return to the subtle nil interface trap in Go and the conditional path where null silently propagates through multiple function calls.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SSRF</title>
      <link>https://www.secdev.uk/blog/technology/2025-06-07-ssrf/</link>
      <pubDate>Sat, 07 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-06-07-ssrf/</guid>
      <description>&lt;p&gt;Server-Side Request Forgery is one of those vulnerability classes that I&amp;rsquo;ve grown to respect more and more the deeper I dig into it. The idea is simple, you trick a server into making HTTP requests to destinations you choose, turning it into your personal proxy. It can reach internal services, cloud metadata endpoints, and private networks that you&amp;rsquo;d never touch directly from the outside. OWASP gave SSRF its own category (A10) in 2021, and reading through the rationale, it was overdue. The case studies are striking, a single SSRF against &lt;code&gt;http://169.254.169.254/&lt;/code&gt; on AWS can leak IAM credentials and compromise an entire account. In this post, I&amp;rsquo;ll walk through Python, Java, Go, and JavaScript examples, from the textbook URL-in-a-parameter to the subtle redirect-chain and DNS rebinding variants that make SSRF so hard to defend against.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Logging Failures</title>
      <link>https://www.secdev.uk/blog/technology/2025-05-24-logging-failures/</link>
      <pubDate>Sat, 24 May 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-05-24-logging-failures/</guid>
      <description>&lt;p&gt;When I started researching logging failures for this post, I expected to find dramatic exploit chains. Instead, what I found was something more unsettling, the absence of evidence. The most frustrating thing about incident response isn&amp;rsquo;t finding a sophisticated exploit; it&amp;rsquo;s opening the log aggregator and finding nothing. No entries, no breadcrumbs, no evidence that anything happened at all. That&amp;rsquo;s CWE-778 (Insufficient Logging), and it&amp;rsquo;s the backbone of OWASP A09: Security Logging and Monitoring Failures. This isn&amp;rsquo;t a crash or a data leak in the traditional sense; it&amp;rsquo;s the absence of evidence. When your incident response team can&amp;rsquo;t investigate what was never recorded, the attacker wins by default. In this post, I&amp;rsquo;m going to walk through logging failures across Python, Java, and Go, from the obvious missing-log-statement to the subtle cases where logging exists but captures the wrong data, at the wrong level, or silently drops events under load.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Integrity Failures</title>
      <link>https://www.secdev.uk/blog/technology/2025-05-10-integrity-failures/</link>
      <pubDate>Sat, 10 May 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-05-10-integrity-failures/</guid>
      <description>&lt;p&gt;Integrity failures happen when an application trusts data or code that hasn&amp;rsquo;t been verified, and they can lead to some of the most devastating compromises out there. OWASP A08 covers two patterns I find particularly fascinating: unsafe deserialization (CWE-502), where untrusted data is fed into a deserializer that can execute arbitrary code, and inclusion of functionality from untrusted sources (CWE-829), where the application loads and runs code from URLs, plugins, or scripts without integrity checks. Both patterns share a root cause, the application assumes that incoming data or code is benign. In this post I&amp;rsquo;ll walk through Python, Java, JavaScript, and Go, from the textbook &lt;code&gt;pickle.loads()&lt;/code&gt; to the subtle VM sandbox escapes that can survive expert review.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Authentication Failures</title>
      <link>https://www.secdev.uk/blog/technology/2025-04-26-authentication-failures/</link>
      <pubDate>Sat, 26 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-04-26-authentication-failures/</guid>
      <description>&lt;p&gt;Authentication is the front door of every application, and OWASP A07 documents how often that door is left unlocked. When I started digging into authentication failures, I realised they go far beyond weak passwords, they encompass hardcoded credentials compiled into binaries, brute-force attacks with no rate limiting, password hashes that can be reversed in seconds, and reset flows that hand tokens directly to attackers. These patterns show up in production regularly, sometimes in the same application. This post covers three CWEs across Python, Java, Go, and Rust: CWE-798 (Use of Hard-Coded Credentials), CWE-287 (Improper Authentication), and CWE-307 (Improper Restriction of Excessive Authentication Attempts).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Security Misconfiguration</title>
      <link>https://www.secdev.uk/blog/technology/2025-03-29-security-misconfiguration/</link>
      <pubDate>Sat, 29 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-03-29-security-misconfiguration/</guid>
      <description>&lt;p&gt;Security misconfiguration is the vulnerability class that really drove home for me why secure defaults matter more than secure documentation. OWASP A05 covers the gap between what a framework &lt;em&gt;can&lt;/em&gt; do securely and how developers actually configure it. Debug mode left on in production. CORS wide open. XML parsers that resolve external entities. Settings endpoints with no authentication. These aren&amp;rsquo;t coding mistakes, they&amp;rsquo;re configuration mistakes, and they show up everywhere. In this post I&amp;rsquo;ll walk through Python, Java, Go, and JavaScript examples covering CWE-16 (Improper Configuration) and CWE-611 (XML External Entity Processing), from the flags that any reviewer would catch to the subtle combinations that can survive months in production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Cryptographic Failures That Pass Code Review</title>
      <link>https://www.secdev.uk/blog/technology/2025-03-01-cryptographic-failures-that-pass-code-review/</link>
      <pubDate>Sat, 01 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-03-01-cryptographic-failures-that-pass-code-review/</guid>
      <description>&lt;p&gt;Cryptographic code is uniquely dangerous, and it&amp;rsquo;s one of the areas I find most challenging to review. The reason is simple: it can be completely wrong and still appear to work perfectly. A broken hash function still produces a hash. A weak cipher still encrypts and decrypts. A predictable random number generator still generates numbers. The application runs, tests pass, and the vulnerability sits quietly until an attacker exploits it. In this post, I want to walk through the cryptographic failures that routinely survive code review across Python, Java, Go, and Rust, from the obvious use of MD5 to the subtle misuse of otherwise strong primitives.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Broken Access Control</title>
      <link>https://www.secdev.uk/blog/technology/2025-02-15-broken-access-control/</link>
      <pubDate>Sat, 15 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-02-15-broken-access-control/</guid>
      <description>&lt;p&gt;Broken access control sits at the top of the OWASP Top 10 for good reason, and it&amp;rsquo;s the vulnerability class I find most fascinating to research. It&amp;rsquo;s the most common serious vulnerability in modern web applications, and it&amp;rsquo;s almost entirely a logic problem, no amount of input sanitization or encryption fixes it. The application simply fails to verify that the authenticated user is authorized to perform the requested action on the requested resource. In this post, I want to walk through the patterns that show up across Python, Java, and Go, from the IDOR that any pentester would find in minutes to the subtle authorization gaps that can survive months of code review.&lt;/p&gt;</description>
    </item>
    <item>
      <title>XSS Is Not Just a JavaScript Problem</title>
      <link>https://www.secdev.uk/blog/technology/2025-02-01-xss-is-not-just-a-javascript-problem/</link>
      <pubDate>Sat, 01 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-02-01-xss-is-not-just-a-javascript-problem/</guid>
      <description>&lt;p&gt;Cross-site scripting gets framed as a front-end problem a lot, something that happens in JavaScript and gets fixed with JavaScript. But the more I dug into this, the clearer it became that XSS vulnerabilities almost always originate on the server side, in whatever language is generating the HTML. I&amp;rsquo;ve found XSS in Python templates, Java JSPs, Go&amp;rsquo;s &lt;code&gt;html/template&lt;/code&gt; misuse, Rust web frameworks, and server-rendered JavaScript. The language you write your backend in determines which XSS patterns you&amp;rsquo;ll run into and which ones will sneak past your review.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Command Injection Beyond os.system</title>
      <link>https://www.secdev.uk/blog/technology/2025-01-18-command-injection-beyond-os-system/</link>
      <pubDate>Sat, 18 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-01-18-command-injection-beyond-os-system/</guid>
      <description>&lt;p&gt;When most developers hear &amp;ldquo;command injection,&amp;rdquo; they think of &lt;code&gt;os.system()&lt;/code&gt; in Python or &lt;code&gt;Runtime.exec()&lt;/code&gt; in Java. Those are the textbook examples, and most teams know to avoid them. But the more I researched this topic, the more I realised that command injection surfaces through dozens of less obvious APIs across every language, subprocess pipes, shell expansions, backtick operators, and even seemingly safe exec functions that become dangerous with the wrong arguments. This is one of my favourite vulnerability classes to dig into because the attack surface is so much wider than people realise. Let me walk you through command injection patterns across seven languages, from the obvious to the genuinely subtle.&lt;/p&gt;</description>
    </item>
    <item>
      <title>SQL Injection Across Languages</title>
      <link>https://www.secdev.uk/blog/technology/2025-01-04-sql-injection-across-languages/</link>
      <pubDate>Sat, 04 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://www.secdev.uk/blog/technology/2025-01-04-sql-injection-across-languages/</guid>
      <description>&lt;p&gt;SQL injection is one of those vulnerability classes that refuses to go away, no matter how much the industry talks about it. I&amp;rsquo;ve been digging into how it manifests across different languages, Python, Java, Go, and JavaScript, and the root cause is always the same: untrusted input reaches a SQL query without proper parameterization. But the way developers introduce it varies wildly depending on the framework, ORM, and idioms of each language. In this post, I want to walk through real examples across these four languages, showing both the obvious patterns that any reviewer would catch and the subtle ones that slip through code review more often than you&amp;rsquo;d expect.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
