Skip to content

Neil Madden

    • About Neil

  • Are we any closer to the Quantum Apocalypse?

    Another day, another urgent pronouncement on the need to transition to post-quantum cryptography ASAP: this one from the White House, in the form of an Executive Order requiring certain “high value” systems to transition to post-quantum cryptography (PQC) by the end of 2030 (for key exchange) or 2031 (for signatures). This brings forward the date slightly compared to previous guidance, which disallows quantum-vulnerable crypto for US Federal systems by 2035. But is this urgency justified?

    First, an important note: as you can probably tell already, I’m going to pour some skepticism on this sense of urgency. I don’t think cryptographically-relevant quantum computers are coming soon. However, that doesn’t mean we shouldn’t be prepared! The risk that they might appear soon is non-negligible, and the impact of them appearing for many applications is catastrophic. Sensible timelines to mitigate known threats are justified, panic-induced rushing is not. On with the article…

    (more…)

    Share this:

    • Email a link to a friend (Opens in new window) Email
    • Print (Opens in new window) Print
    • Share on Facebook (Opens in new window) Facebook
    • Share on Reddit (Opens in new window) Reddit
    • Share on LinkedIn (Opens in new window) LinkedIn
    Like Loading…
    2 July, 2026
    cryptography, post-quantum cryptography, standards

  • Java’s SSLContext protocol name is a footgun

    This should be old news, but I keep seeing the same mistake crop up, so I thought I’d blog about it and spread awareness. In Java, if you want to configure TLS you generally start with an SSLContext. And you get an instance of this class by calling the static method SSLContext.getInstance("TLSv1.3"), specifying the version of the protocol you want to support. But typically a TLS connection supports other versions of the protocol, so what exactly does specifying “TLSv1.3” here mean? Probably not what you think it means…

    (more…)

    Share this:

    • Email a link to a friend (Opens in new window) Email
    • Print (Opens in new window) Print
    • Share on Facebook (Opens in new window) Facebook
    • Share on Reddit (Opens in new window) Reddit
    • Share on LinkedIn (Opens in new window) LinkedIn
    Like Loading…
    23 June, 2026
    Java, JSSE, Security, tls

  • Java sealed classes and exhaustive pattern matching

    Java 17 introduced sealed classes, which allow you to explicitly list the allowed sub-types of an interface or base class. For example, here’s a toy example using a sealed interface and records (inner classes are implicitly added to the permitted sub-types if an explicit list is not given):

    public sealed interface SealedType {
        record TypeA() implements SealedType {}
        record TypeB() implements SealedType {}
    
        static SealedType of(String type) {
            return switch (type) {
                case “A” -> new TypeA();
                case “B” -> new TypeB();
                default -> throw new IllegalArgumentException();
            };
        }
    }
    

    If you are familiar with functional programming languages with algebraic datatypes, you can view this as similar to a datatype declaration in Haskell or ML:

    data SealedType = TypeA | TypeB
    

    We can then use this in a simple Main class:

    void main(String[] args) {
        var val = SealedType.of(args[0]);
        System.out.println(switch (val) {
            case SealedType.TypeA() -> “A”;
            case SealedType.TypeB() -> “B”;
        });
    }
    

    OK, not so exciting. But one thing to note here is that we didn’t have to add a default clause to the switch expression in our main method. This is because sealed classes (and enums) enable exhaustiveness checking: the compiler knows exactly what the possible cases are, and so can check if you have covered them all. If you have, then you don’t need a default clause. If you forget one (and don’t have a default clause), then you get a compile-time error.

    This is great when you want to ensure that all uses of some type do cover all of the cases, but it does introduce a new type of breaking change: adding a new sub-type to a sealed class/interface may break consumers of that code. For example, adding a new TypeC case to our example will cause the main method to fail to compile due to the missing case. So if you export a sealed type in your API then adding a new subtype is a breaking change that would require a major version bump (if you’re following SemVer).

    Compile-time or runtime error?

    Although Java will produce a compile-time error for a non-exhaustive switch when you compile the consumer (main in this case), it cannot do so if the consumer is not recompiled when the sealed type changes. For example, suppose that we extend our SealedType with another case:

    public sealed interface SealedType {
        record TypeA() implements SealedType {}
        record TypeB() implements SealedType {}
        record TypeC() implements SealedType {}
    
        static SealedType of(String type) {
            return switch (type) {
                case “A” -> new TypeA();
                case “B” -> new TypeB();
                case “C” -> new TypeC();
                default -> throw new IllegalArgumentException();
            };
        }
    }
    

    If we just recompiled SealedType.java and don’t recompile Main, then we end up with a runtime exception if we trigger the new case:

    % java Main C
    Exception in thread "main" java.lang.MatchException
    at Main.main(Main.java:3)

    Here we have the new MatchException being thrown. The Javadoc notes this potential issue with separate compilation, and also some corner-cases with nulls in patterns. So even if you were hoping that using sealed classes would statically ensure that you update all consumers when a new case is added, this is not the case unless you recompile everything.

    Conclusions

    I think for me the conclusion is that sealed types are probably most useful within the implementation of a component, and are less useful when exposed in the public API that a component offers to other components (eg a library). For internal use, where you typically are going to recompile everything together, you get the nice properties of exhaustiveness checking and higher compile-time safety guarantees. But when used across module boundaries, you may just be introducing new ways to break code, often only detectable at runtime.

    (I discovered these subtleties when reviewing the preview support for PEM-encoded cryptographic objects, which makes exactly this mistake of baking a sealed interface into a public API and recommend clients to pattern match against that type. A predict a very high chance of breakage if they ever want to add a new case).

    Share this:

    • Email a link to a friend (Opens in new window) Email
    • Print (Opens in new window) Print
    • Share on Facebook (Opens in new window) Facebook
    • Share on Reddit (Opens in new window) Reddit
    • Share on LinkedIn (Opens in new window) LinkedIn
    Like Loading…
    24 April, 2026
    Functional Programming, Java, programming, types

  • Mythos and its impact on security

    I’m sure by now you’ve all read the news about Anthropic’s new “Mythos” model and its apparently “dangerous” capabilities in finding security vulnerabilities. I’m sure everyone reading this also has opinions about that. Well, here are a few of mine.

    (more…)

    Share this:

    • Email a link to a friend (Opens in new window) Email
    • Print (Opens in new window) Print
    • Share on Facebook (Opens in new window) Facebook
    • Share on Reddit (Opens in new window) Reddit
    • Share on LinkedIn (Opens in new window) LinkedIn
    Like Loading…
    14 April, 2026
    AI, capability-security, LLMs, memory-safety, programming, Security

  • Maybe version ranges are a good idea after all?

    One of the most important lessons I’ve learned in security, is that it’s always better to push security problems back to the source as much as possible. For example, a small number of experts (hopefully) make cryptography libraries, so it’s generally better if they put in checks to prevent things like invalid curve attacks rather than leaving that up to applications, so that we don’t get the same vulnerabilities cropping up again and again. It’s much more efficient to fix the problem at source rather than having everyone re-implement the same redundant checks everywhere.

    Now consider how we currently manage security vulnerabilities in third-party software dependencies. Current accepted wisdom is to lock dependencies to a single specific version, often with a cryptographic hash to ensure you get exactly that version. This is great for reproducibility, and everyone loves reproducibility. However, when there’s a security vulnerability in that dependency, every single consumer of that library has to manually update to the next version, and then their consumers have to update, and so on. The fix is done at source, but the responsibility for updating cascades through the entire ecosystem. This is not efficient. Two years after log4shell, around 25% of vulnerable consumers had apparently still not updated.

    (more…)

    Share this:

    • Email a link to a friend (Opens in new window) Email
    • Print (Opens in new window) Print
    • Share on Facebook (Opens in new window) Facebook
    • Share on Reddit (Opens in new window) Reddit
    • Share on LinkedIn (Opens in new window) LinkedIn
    Like Loading…
    19 March, 2026
    Dependencies, programming, Security, Supply Chain

  • Why I don’t use LLMs for programming

    I originally posted this on Mastodon, but I thought I’d add it here too:

    “What I mean is that if you really want to understand something, the best way is to try and explain it to someone else. That forces you to sort it out in your own mind. And the more slow and dim-witted your pupil, the more you have to break things down into more and more simple ideas. And that’s really the essence of programming. By the time you’ve sorted out a complicated idea into little steps that even a stupid machine can deal with, you’ve certainly learned something about it yourself. The teacher usually learns more than the pupil. Isn’t that true?” — Douglas Adams

    “It is not knowledge, but the act of learning, not possession, but the act of getting there which generates the greatest satisfaction.” — Carl Friedrich Gauss

    “You think you KNOW when you learn, are more sure when you can write, even more when you can teach, but certain when you can program.” — Alan Perlis (of course)

    (Ironically, WordPress is now offering to “improve” these quotes with AI…)

    Share this:

    • Email a link to a friend (Opens in new window) Email
    • Print (Opens in new window) Print
    • Share on Facebook (Opens in new window) Facebook
    • Share on Reddit (Opens in new window) Reddit
    • Share on LinkedIn (Opens in new window) LinkedIn
    Like Loading…
    2 March, 2026
    AI, artificial intelligence, LLMs

  • Looking for vulnerabilities is the last thing I do

    There’s a common misconception among developers that my job, as a (application) Security Engineer, is to just search for security bugs in their code. They may well have seen junior security engineers doing this kind of thing. But, although this can be useful (and is part of the job), it’s not what I focus on and it can be counterproductive. Let me explain.

    (more…)

    Share this:

    • Email a link to a friend (Opens in new window) Email
    • Print (Opens in new window) Print
    • Share on Facebook (Opens in new window) Facebook
    • Share on Reddit (Opens in new window) Reddit
    • Share on LinkedIn (Opens in new window) LinkedIn
    Like Loading…
    20 February, 2026
    Application Security, Security, Security Engineering

  • Were URLs a bad idea?

    When I was writing Rating 26 years of Java changes, I started reflecting on the new HttpClient library in Java 11. The old way of fetching a URL was to use URL.openConnection(). This was intended to be a generic mechanism for retrieving the contents of any URL: files, web resources, FTP servers, etc. It was a pluggable mechanism that could, in theory, support any type of URL at all. This was the sort of thing that was considered a good idea back in the 90s/00s, but has a bunch of downsides:

    • Fetching different types of URLs can have wildly different security and performance implications, and wildly different failure cases. Do I really want to accept a mailto: URL or a javascript: “URL”? No, never.
    • The API was forced to be lowest-common-denominator, so if you wanted to set options that are specific to a particular protocol then you had to cast the return URLConnection to a more specific sub-class (and therefore lose generality).

    The new HttpClient in Java 11 is much better at doing HTTP, but it’s also specific to HTTP/HTTPS. And that seems like a good thing?

    In fact, in the vast majority of cases the uniformity of URLs is no longer a desirable aspect. Most apps and libraries are specialised to handle essentially a single type of URL, and are better off because of it. Are there still cases where it is genuinely useful to be able to accept a URL of any (or nearly any) scheme?

    Share this:

    • Email a link to a friend (Opens in new window) Email
    • Print (Opens in new window) Print
    • Share on Facebook (Opens in new window) Facebook
    • Share on Reddit (Opens in new window) Reddit
    • Share on LinkedIn (Opens in new window) LinkedIn
    Like Loading…
    12 November, 2025
    URLs, Web

  • Monotonic Collections: a middle ground between immutable and fully mutable

    This post covers several topics around collections (sets, lists, maps/dictionaries, queues, etc) that I’d like to see someone explore more fully. To my knowledge, there are many alternative collection libraries for Java and for many other languages, but I’m not aware of any that provide support for monotonic collections. What is a monotonic collection, I hear you ask? Well, I’m about to answer that. Jesus, give me a moment.

    It’s become popular, in the JVM ecosystem at least, for collections libraries to provide parallel class hierarchies for mutable and immutable collections: Set vs MutableSet, List vs MutableList, etc. I think this probably originated with Scala, and has been copied by Kotlin, and various alternative collection libraries, e.g. Eclipse Collections, Guava, etc. There are plenty of articles out there on the benefits and drawbacks of each type. But the gulf between fully immutable and fully mutable objects is enormous: they are polar opposites, with wildly different properties, performance profiles, and gotchas. I’m interested in exploring the space between these two extremes. (Actually, I’m interested in someone else exploring it, hence this post). One such point is the idea of monotonic collections, and I’ll now explain what that means.

    By monotonic I mean here logical monotonicity: the idea that any information that is entailed by some set of logical formulas is also entailed by any superset of those formulas. For a collection data structure, I would formulate that as follows:

    If any (non-negated) predicate is true of the collection at time t, then it is also true of the collection at any time t’ > t.

    For example, if c is a collection and c.contains(x) returns true at some point in time, then it must always return true from then onwards.

    To make this concrete, a MonotonicList (say) would have an append operation, but not insert, delete, or replace operations. More subtly, monotonic collections cannot have any aggregate operations: i.e., operations that report statistics/summary information on the collection as a whole. For example, you cannot have a size method, as the size will change as new items are added (and thus the predicate c.size() == n can become false). You can have (as I understand it) map and filter operations, but not a reduce/fold.

    So why are monotonic collections an important category to look at? Firstly, monotonic collections can have some of the same benefits as immutable data structures, such as simplified concurrency. Secondly, monotonic collections are interesting because they can be (relatively) easily made distributed, per the CALM principle: Consistency as Logical Monotonicity (insecure link, sorry). This says that monotonic collections are strongly eventually consistent without any need for coordination protocols. Providing such collections would thus somewhat simplify making distributed systems.

    Class hierarchies and mutability

    Interestingly, Kotlin decided to make their mutable collection classes sub-types of the immutable ones: MutableList is a sub-type of List, etc. (They also decided to make the arrows go the other way from normal in their inheritance diagram, crazy kids). This makes sense in one way: mutable structures offer more operations than immutable ones. But it seems backwards from my point of view: it says that all mutable collections are immutable, which is logically false. (But then they don’t include the word Immutable in the super types). It also means that consumers of a List can’t actually assume it is immutable: it may change underneath them. Guava seems to make the opposite decision: ImmutableList extends the built-in (mutable) List type, probably for convenience. Both options seem to have drawbacks.

    I think the way to resolve this is to entirely separate the read-only view of a collection from the means to update it. On the view-side, we would have a class hierarchy consisting of ImmutableList, which inherits from MonotonicList, which inherits from the general List. On the mutation side, we’d have a ListAppender and ListUpdater classes, where the latter extends the former. Creating a mutable or monotonic list would return a pair of the read-only list view, and the mutator object, something like the following (pseudocode):

    ImmutableList<T> list = ImmutableList.of(....); // normal
    Pair<MonotonicList<T>, ListAppender<T>> mono = MonotonicList.of(...);
    Pair<List<T>, ListUpdater<T>> mut = List.of(...);
    

    The type hierarchies would look something like the following:

    interface List<E> {
        void forEach(Consumer<E> action);
        ImmutableList<E> snapshot();
    }
    
    interface MonotonicList<E> extends List<E> {
        boolean contains(E element);
        // Positive version of isEmpty():
        boolean containsAnything(); 
        <T> MonotonicList<T> map(Function<E, T> f);
        MonotonicList<E> filter(Predicate<E> p);
    }
    
    interface ImmutableList<E> extends MonotonicList<E> {
        int size();
        <T> T reduce(BiFunction<E, T, T> f, T initial);
    }
    
    interface ListAppender<E> {
        void append(E element);
    }
    
    interface ListUpdater<E> extends ListAppender<E> {
        E remove(int index);
        E replace(int index, E newValue);
        void insert(int index, E newValue);
    }
    

    This seems to satisfy allowing the natural sub-type relationships between types on both sides of the divide. It’s a sort of CQRS at the level of data structures, but it seems to solve the issue that the inheritance direction for read-only consumers is the inverse of the natural hierarchy for mutating producers. (This has a relationship to covariant/contravariant subtypes, but I’m buggered if I’m looking that stuff up again on my free time).

    Anyway, these thoughts are obviously pretty rough, but maybe some inklings of ideas if anyone is looking for an interesting project to work on.

    Share this:

    • Email a link to a friend (Opens in new window) Email
    • Print (Opens in new window) Print
    • Share on Facebook (Opens in new window) Facebook
    • Share on Reddit (Opens in new window) Reddit
    • Share on LinkedIn (Opens in new window) LinkedIn
    Like Loading…
    11 November, 2025
    data structures, Functional Programming, immutability, Java, programming

  • Fluent Visitors: revisiting a classic design pattern

    It’s been a while since I’ve written a pure programming post. I was recently implementing a specialist collection class that contained items of a number of different types. I needed to be able to iterate over the collection performing different actions depending on the specific type. There are lots of different ways to do this, depending on the school of programming you prefer. In this article, I’m going to take a look at a classic “Gang of Four” design pattern: The Visitor Pattern. I’ll describe how it works, provide some modern spins on it, and compare it to other ways of implementing the same functionality. Hopefully even the most die-hard anti-OO/patterns reader will come away thinking that there’s something worth knowing here after all.

    (Design Patterns? In this economy?)

    (more…)

    Share this:

    • Email a link to a friend (Opens in new window) Email
    • Print (Opens in new window) Print
    • Share on Facebook (Opens in new window) Facebook
    • Share on Reddit (Opens in new window) Reddit
    • Share on LinkedIn (Opens in new window) LinkedIn
    Like Loading…
    4 November, 2025
    Design Patterns, Functional Programming, Java, programming, Visitor Pattern

Next Page

Blog at WordPress.com.

  • Subscribe Subscribed
    • Neil Madden
    • Join 68 other subscribers
    • Already have a WordPress.com account? Log in now.
    • Neil Madden
    • Subscribe Subscribed
    • Sign up
    • Log in
    • Report this content
    • View site in Reader
    • Manage subscriptions
    • Collapse this bar
%d