# Hardcoded strings are leaking your .NET app’s secrets


Open any .NET binary in a decompiler and one of the first things you'll see is a clean list of every string literal in the app. For most applications, that list is a roadmap to how everything works — and sometimes to things that were never meant to be seen.

## Why plain-text strings are a problem

String literals compile straight into your assembly's metadata, completely readable. From that list an attacker can immediately learn:

- **API endpoints and URLs** your app talks to.
- **Error and log messages** that reveal internal logic and control flow.
- **Registry keys, file paths, and feature flags.**
- **Embedded secrets** that shouldn't be there at all — API keys, tokens, connection strings.

Even without decompiling a single method, searching the string table often tells an attacker exactly where to look next — for example, jumping straight to your licensing code by searching for "license" or "trial".

## What string encryption does

String encryption replaces those readable literals with encrypted data that's decrypted at runtime:

- Each literal is encrypted at build time, ideally with a **fresh per-build key**.
- The plain text no longer appears in the binary's string table.
- At runtime, an inlined routine decrypts the value on demand.

Done well, the decryptor is **unbranded** (its name doesn't advertise which tool produced it) and inlined, so it's not a single obvious function an attacker can hook to dump every string at once.

## What it doesn't do

String encryption raises the bar; it isn't a vault. A determined attacker can still run the app and recover decrypted strings from memory. So the rule stands: **don't ship real secrets in the client at all.** Keep private keys and master credentials server-side. String encryption protects your *code's* strings — endpoints, messages, logic markers — not secrets that should never leave your server.

## Where it fits

String encryption is one layer of a hardened build, alongside:

- **Identifier renaming** — removes readable names.
- **Control-flow flattening** — hides logic structure.
- **Anti-tamper / anti-debug** — stops live patching and stepping.

[Nebula.NET](https://delta1labs.com/products/nebula) encrypts string literals with a per-build key and an unbranded, inlined decryptor, as part of the same pass that renames and flattens your code — across .NET Framework 4.8 and .NET 6–10. See it on your own binary with the [free edition](https://delta1labs.com/download): decompile before and after, and watch the string table go dark.

