Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Intelligence View
⚡ tsecurity.de Intelligence

Why "null" is an abomination

Imagine you're halfway through your third cup of coffee, navigating through a sea of null in your codebase, and you can't help but whisper to yourself, "What in the world..." Perhaps you're even tempted to unleash a fiery comment into the…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Imagine you're halfway through your third cup of coffee, navigating through a sea of null in your codebase, and you can't help but whisper to yourself, "What in the world..." Perhaps you're even tempted to unleash a fiery comment into the void of the internet. It’s widely known that Tony Hoare, the architect behind the null reference back in 1965, has famously labeled it his "billion-dollar blunder."



Humorous GIF depicting frustration with null references



Let’s dive into the intricacies of null through the lens of TypeScript, a language that you all know (and hate?).






Unraveling the Mystery of null



At its core, null signifies the intentional absence of a value. Its sibling, undefined, serves a similar role, denoting an uninitialized state. Here’s a simple breakdown:





  • undefined: A variable not yet blessed with a value.


  • null: A conscious decision to embrace emptiness.



Consider this example:




type User = {
username: string,
pictureUrl?: string,
};

type UpdateUser = {
username?: string,
pictureUrl?: string | null,
};

const update = (user: User, data: UpdateUser) => {
if (data.pictureUrl === undefined) {
// No action required
return;
}
if (typeof data.pictureUrl === "string") {
// Update in progress
user.pictureUrl = data.pictureUrl;
}
if (data.pictureUrl === null) {
// Time to say goodbye
delete user.pictureUrl;
}
}






This scenario is common when working with partial objects from APIs, where undefined fields imply no change, and null explicitly requests data deletion.



However, how clear is it that null means "I am going to delete something"? You better hope that you have a big warning banner in your documentation and that your client will never inadvertently send a null value by mistake (which is going to happen by the way).



It feels natural because you have "NULL" in your database but employing null in your programming language solely because it exists in formats like JSON or SQL isn’t a strong argument. After all, a direct one-to-one correspondence between data structures isn't always practical or necessary. Just think about Date.






The Trouble with null



The introduction of null into programming languages has certainly stirred the pot, blurring the lines between absence and presence. This ambiguity, as demonstrated earlier, can lead to unintuitive code. In fact, the TypeScript team has prohibited the use of null within their internal codebase, advocating for clearer expressions of value absence.



Moreover, the assumption that null and undefined are interchangeable in JavaScript leads to bewildering behavior, as illustrated by the following examples:




console.log(undefined == null); // Curiously true
console.log(undefined === null); // Definitely false
console.log(typeof null); // Unexpectedly "object"
console.log(typeof undefined); // As expected, "undefined"
console.log(JSON.stringify(null)); // Returns "null"
console.log(JSON.stringify(undefined)); // Vanishes into thin air






Regrettably, I've written code like this more often than I'd like to admit:




function isObject(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null;
}






Furthermore, if you begin incorporating both null and undefined into your codebase, you will likely encounter patterns like the following:




const addOne = (n: number | null) => (n ? n + 1 : null);

const subtractOne = (n?: number) => (n ? n - 1 : undefined);

const calculate = () => {
addOne(subtractOne(addOne(subtractOne(0) ?? null) ?? undefined) ?? null);
};









The Undefined Conundrum



Okay, so we just ban null from our codebase and only use undefined instead. Problem solved, right?



It’s easy to assume that optional properties {key?: string} are synonymous with {key: string | undefined}, but they’re distinct, and failing to recognize this can lead to headaches.




const displayName = (data: { name?: string }) =>
console.log("name" in data ? data.name : "Missing name");

displayName({}); // Displays "Missing name"
displayName({ name: undefined }); // Displays undefined
displayName({ name: "Hello" }); // Greets you with "Hello"






Yet, in other scenarios such as JSON conversion, these distinctions often evaporate, revealing a nuanced dance between presence and absence.




console.log(JSON.stringify({})); // {}
console.log(JSON.stringify({ name: undefined })); // {}
console.log(JSON.stringify({ name: null })); // {"name": null}
console.log(JSON.stringify({ name: "Bob" })); // {"name":"Bob"}






So, sometimes there are differences, sometimes not. You just have to be careful I guess!



Another problem of undefined, is that you often end up doing useless if statements because of them. Does this ring a bell?




type User = { name?: string };

const validateUser = (user: User) => {
if (user.name === undefined) {
throw new Error('Missing name');
}

const name = getName(user);

// ...
}

const getName = (user: User): => {
// Grrrr... Why do I have to do that again?
if (user.name === undefined) {
throw new Error('Missing name');
}

return name;
}






Consider this scenario, which is even more problematic: a function employs undefined to represent the action of "deleting a value." Here's what it might look like:




type User = { id: string, name?: string };

const updateUser = (user: User, newId: string, newName?: string) => {
user.id = newId;
user.name = newName;
}

updateUser(user, "123"); // It's unclear that this call actually removes the user's name.






In this example, using undefined ambiguously to indicate the deletion of a user's name could lead to confusion and maintenance issues. The code does not clearly convey that omitting newName results in removing the user's name, which can be misleading.






A Path Forward



Instead of wrestling with null-ish values, consider whether they’re necessary. Utilizing unions or more descriptive data structures can streamline your approach, ensuring clarity and reducing the need for null checks.




type User = { id: string };
type NamedUser = User & { name: string };

const getName = (user: NamedUser): string => user.name;






You can also have a data structure to clearly indicate the absence of something, for example:




type User = {
id: string;
name: { kind: "Anonymous" } | { kind: "Named", name: string }
}






If we jump back to my first example of updating a user, here is a refactored version of it:




type UpdateUser = {
name:
| { kind: "Ignore" }
| { kind: "Delete" }
| { kind: "Update"; newValue: string };
};







This model explicitly delineates intent, paving the way for cleaner, more intuitive code.



Some languages have completely abandoned the null value to embrace optional values instead. In Rust for example, there is neither null or undefined, instead you have the Option enum.




type Option<T> = Some<T> | None;
type Some<T> = { kind: "Some", value: T };
type None = { kind: "None" };






I recommend this lib if you want to try this pattern in JS: https://swan-io.github.io/boxed/getting-started






In Conclusion



Adopting refined practices for dealing with null and undefined can dramatically enhance code quality and reduce bugs. Let the evolution of languages and libraries inspire you to embrace patterns that prioritize clarity and safety. By methodically refactoring our codebases, we can make them more robust and maintainable. This doesn't imply you should entirely abandon undefined or null; rather, use them thoughtfully and deliberately, not merely because they're convenient and straightforward.

1. Sofort-Triage & Abwehrmaßnahmen

SOC Incident Playbook: Vulnerability Remediation & Verification
Syntax validiert (0 Fehler)
title: Detect Exploitation - Why "null" is an abomination
id: 27d4d19d-f48e-432d-9eed-758573e4f8a3
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-25
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-25"
        description = "YARA Signature for "
    strings:
        $str = "Why \"null\" is an abomination" ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("Why null is an abomination")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*Why null is an abomination*"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "Why null is an abomination"
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc

2. Cyber Threat Intelligence & Forensik

🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich Why &quot;null&quot; is an abomination.... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Why "null" is an abomination

Thematisch verwandte Begriffe: null, abomination · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-97735 | ITFlow before 26.08 allows SVG attachments in the ticket email parser (c…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag