It is undefined behavior in C. In many languages it is defined behavior; for instance in Go, dereferencing a nil pointer explicitly panics, which is a well-defined operation. It may, of course, crash your program, and the whole topic of 'should pointers even be able to be nil?' is a valid separate other question, but given that they exist, the operation of dereferencing a nil pointer is not undefined behavior in Go.
To many people reading this this may be a "duh" but I find it is worth pointing out, because there are still some programmers who believe that C is somehow the "default" or "real" language of a computer and that everything about C is true of other languages, but that is not the case. Undefined behavior in C is undefined in C, specifically. Try to avoid taking ideas about UB out of C, and to the extent that they are related (which slowly but surely decreases over time), C++. It's the language, not the hardware that is defining UB.
This is a common thing I get annoyed with when explaining to people too about Odin. Odin also defines dereferencing `nil` as panicking (as on all systems with virtual memory, it comes for free).
C is just one language of many and you do not have to define the rules of a new language to it.
Why does a language even allow dereferencing nil? Many languages make this impossible. If you anyway go and design a new language, why stay stuck in the old ways and carry that flaw with you?
Let me explain. Conceptually, a pointer is an optional reference. Either it's nil or it references some object. (That reference may be valid or not, but that's a separate topic.) Optionals have been well understood in the programming language community for a long time. Many modern languages get them right, usually with some form of what Haskell calls the Maybe monad. May sound intimidating, but the gist is that in order to unwrap the thing inside, you pattern match on its structure. It's either Nothing or it's a value. You can't even syntactically talk about the wrapped thing outside this pattern matching. With such a construction, "dereferencing nil" is not a thing. You either have a pointer (optional reference) which needs the unwrapping, or you already did unwrap, then you have a non-null-pointer (non-optional reference). So, a language can easily encode all this in its type system without runtime overhead.
When inventing a new language that fixes flaws of C, why not fix this one as well?
To many people reading this this may be a "duh" but I find it is worth pointing out, because there are still some programmers who believe that C is somehow the "default" or "real" language of a computer and that everything about C is true of other languages, but that is not the case. Undefined behavior in C is undefined in C, specifically. Try to avoid taking ideas about UB out of C, and to the extent that they are related (which slowly but surely decreases over time), C++. It's the language, not the hardware that is defining UB.