Sich von fest codierten Werten befreien

Weg von festgeschriebenen Werten: Intelligentere Strategien für moderne Software

Fest codierte Werte wirken wie Abkürzungen. Ein Entwickler benötigt eine Datenbank-URL, gibt sie direkt in eine Verbindungszeichenfolge ein und arbeitet weiter. Drei Monate später ändert sich die URL, die Änderung wird in einer Datei vorgenommen, aber in vier anderen übersehen, und die Produktion bricht um 2 Uhr nachts zusammen. Ein Entwickler benötigt einen API-Schlüssel, gibt ihn in die Quelldatei ein, committet und pusht die Änderungen. Sechs Monate später wird das Repository geklont, der Schlüssel taucht in einem öffentlichen Fork auf, und das Konto wird kompromittiert, bevor es jemand bemerkt. Das sind keine Sonderfälle. Es ist der typische Verlauf fest codierter Werte in Softwaresystemen: harmlos aussehende Abkürzungen, die sich zu Wartungsaufwand, Sicherheitsvorfällen und Bereitstellungsfehlern summieren.

Fest codierte Werte finden und eliminieren

Beseitigen und Entfernen von Hardcoding-Werten

Erfahren Sie mehr

Die Lösung ist nicht kompliziert. Umgebungsvariablen, Konfigurationsdateien, Dependency Injection und zentralisierte Konstanten sind bewährte Muster, die in allen gängigen Programmiersprachen und Frameworks verfügbar sind. Die Herausforderung besteht darin, sie systematisch auf bestehende Codebasen anzuwenden, sie auch für neuen Code zu erzwingen und die Disziplin zu entwickeln, Fehler zu erkennen, bevor sie in der Produktion auftreten. Alle dafür notwendigen Techniken werden im Folgenden anhand von Codebeispielen für Python, Java und JavaScript erläutert.

Was ist ein fest codierter Wert?

Ein fest codierter Wert ist eine direkt im Quellcode eingebettete Konstante, die nicht über Konfigurationen, Umgebungsvariablen, eine Datenbank oder Laufzeiteingaben bereitgestellt wird. Das entscheidende Merkmal ist die fehlende Indirektion: Wenn eine Änderung des Wertes eine Modifizierung des Quellcodes, eine Neukompilierung oder eine erneute Bereitstellung der Anwendung erfordert, ist er fest codiert.

Häufige Beispiele:

  • Eine Datenbankverbindungszeichenfolge, die direkt in eine Konfigurationsklasse eingegeben wurde
  • Ein API-Schlüssel oder ein Zugriffstoken in einer Quelldatei
  • Eine Service-URL, die auf eine bestimmte Umgebung verweist
  • Ein numerischer Schwellenwert (if (amount > 5000)) ohne Erklärung oder externe Quelle
  • Ein Dateipfad unter der Annahme eines bestimmten Server-Layouts
  • Eine Benutzerrollenzeichenfolge ("admin") über Autorisierungsprüfungen verstreut

Fest codierte Werte finden sich in jeder Programmiersprache und jeder Codebasis. Ältere Mainframe-Anwendungen kodieren umgebungsspezifische Datensatznamen, Regionscodes und Geschäftsschwellenwerte direkt in COBOL-Programmen. Moderne Microservices akkumulieren fest codierte Timeout-Werte, Wiederholungszähler und Service-Discovery-URLs in Anwendungsklassen. Die Form ändert sich mit der Sprache; das Problem bleibt dasselbe.

Fest codierte Werte vs. Konstanten: Worin liegt der Unterschied?

Fest codierte Werte werden oft mit Konstanten verwechselt, doch die Unterscheidung ist wichtig. Eine Konstante repräsentiert eine stabile, beabsichtigte Tatsache auf Domänenebene, die per Definition korrekt ist und sich voraussichtlich nicht ändern wird: Math.PI, HTTP_STATUS_OK = 200, MAX_RETRY_ATTEMPTS = 3 (Vorausgesetzt, die Zahl Drei ist tatsächlich in allen Kontexten korrekt.) Konstanten sind im Code sinnvoll. Sie erhöhen die Übersichtlichkeit, verhindern Tippfehler und machen die Absicht deutlich.

Ein fest codierter Wert kodiert eine Annahme über den Bereitstellungskontext, die Infrastruktur oder Geschäftsregeln, die erwartungsgemäß variieren kann. Eine Produktionsdatenbank-URL, ein API-Schlüssel, ein regionsspezifischer Steuersatz, ein Feature-Flag-Status: Dies sind fest codierte Werte, die als Konstanten getarnt sind. Der Test ist einfach: Wenn der Wert in einer anderen Umgebung, bei einem anderen Kunden oder in einer anderen Version unterschiedlich sein muss, handelt es sich nicht um eine Konstante und er sollte nicht im Quellcode enthalten sein.

Was ist Soft Coding?

Soft Coding bezeichnet die Praxis, Werte zur Laufzeit konfigurierbar zu machen, anstatt sie zur Kompilierzeit festzulegen. Ein so konfigurierter Wert kann über eine Konfigurationsdatei, eine Umgebungsvariable, einen Datenbankeintrag oder eine administrative Schnittstelle geändert werden, ohne den Quellcode zu modifizieren oder die Anwendung neu bereitzustellen. Soft Coding ist die richtige Methode für umgebungsspezifische Einstellungen, Geschäftsparameter, Feature-Flags und alle Werte, die sich zwischen Entwicklung, Staging und Produktion unterscheiden können.

Der Unterschied zwischen Hardcoding und Softcoding liegt darin, dass ein System zur Aktualisierung eines Steuersatzes entweder eine Codeänderung und eine Bereitstellung erfordert oder es einem Betriebsteam ermöglicht, die Änderung in einer Konfigurationsdatei vorzunehmen und den Dienst neu zu starten. Im großen Maßstab bedeutet dieser Unterschied Tausende von Ingenieurstunden und ein erhebliches Betriebsrisiko.

Warum Hardcoding eine schlechte Praxis ist

Es zerstört die Wartungsfreundlichkeit

Fest codierte Werte vervielfachen sich. Eine Service-URL, die in einer Datei fest codiert ist, wird beim Kopieren des Moduls für eine neue Integration in fünf Dateien fest codiert. Eine magische Zahl, die in einer Berechnung vorkommt, taucht in drei auf, wenn dieselbe Logik in leicht unterschiedlichen Kontexten repliziert wird. Jede Instanz erfordert einen separaten Wartungsaufwand: Sie muss gefunden, aktualisiert, die Aktualisierung getestet und gehofft werden, dass keine Instanz übersehen wurde.

Das Problem der Wartbarkeit betrifft nicht nur den Aufwand, sondern auch das Risiko. Das Suchen und Ersetzen eines fest codierten Werts im gesamten Quellcode ist ein Refactoring-Vorgang mit Auswirkungen auf die Produktion. Jede übersehene Instanz ist ein Fehler. Jede fehlerhafte Ersetzung ist ebenfalls ein Fehler. Nur automatisierte Tests, die bei verbliebenen Instanzen fehlschlagen würden, gewährleisten die Vollständigkeit der Änderung. Genau diese automatisierten Tests erschweren jedoch die Erstellung von Tests durch fest codierte Werte.

Es blockiert Tests und CI/CD.

Automatisierte Tests müssen in kontrollierten Umgebungen ausgeführt werden. Ein Test, der sich aufgrund einer fest codierten Verbindungszeichenfolge mit einer Produktionsdatenbank verbindet, ist kein Test, sondern ein Produktionsvorgang, der zufällig während eines Builds ausgeführt wird. Eine CI-Pipeline, die aufgrund einer nicht erreichbaren, fest codierten Service-URL vom Build-Server abbricht, ist kein Problem der Testinfrastruktur, sondern ein Problem der Festcodierung.

Umgebungsvariablen und Konfigurationsinjektion ermöglichen es, dieselbe Testsuite in lokalen Entwicklungs-, CI-, Staging- und Produktionsumgebungen mit unterschiedlichen Backend-Diensten auszuführen. Ohne sie werden Tests umgebungsspezifisch, fehleranfällig und schließlich aufgegeben.

Es schafft schwerwiegende Sicherheitslücken.

Fest codierte Zugangsdaten gehören zu den häufigsten und am meisten ausgenutzten Schwachstellen in der Softwaresicherheit. Ein fest codierter API-Schlüssel, ein Datenbankpasswort oder ein Zugriffstoken, der in die Versionskontrolle eingecheckt wird, bleibt in der Versionshistorie des Repositorys erhalten, selbst nachdem er aus dem aktuellen Branch gelöscht wurde. Automatisierte Scanner durchsuchen öffentliche Repositories kontinuierlich nach solchen Mustern. Ein Schlüssel, der in einem 18 Monate alten Commit gefunden wurde, ist weiterhin gültig, solange er nicht rotiert wurde.

OWASP stuft fest codierte Passwörter ausdrücklich als kritische Sicherheitslücke ein (CWE-259, CWE-798). Die NIST-Richtlinien schreiben vor, dass Zugangsdaten niemals im Quellcode gespeichert werden dürfen. Trotzdem zählen Datenlecks durch fest codierte Werte weiterhin zu den häufigsten Ursachen für Sicherheitsvorfälle in Cloud-Umgebungen.

Das Risiko geht über Anmeldeinformationen hinaus. Fest codierte interne Service-URLs offenbaren die Infrastrukturtopologie. Fest codierte Benutzerrollen geben Einblick in die Autorisierungslogik. Fest codierte Validierungsschwellenwerte können umgangen werden, sobald ein Angreifer deren genaue Werte kennt. Keines dieser Risiken ist sofort als solches erkennbar, weshalb sie sich unbemerkt anhäufen.

Fest codierte Anmeldeinformationen und API-Schlüssel: Die Kategorie mit dem höchsten Risiko

Fest codierte Geheimnisse erfordern eine gesonderte Betrachtung, da die Folgen von Fehlern grundlegend anders sind als bei anderen Problemen mit der Festcodierung. Ein fest codierter Timeout-Wert verursacht einen Fehler. Ein fest codierter API-Schlüssel führt zu einer Sicherheitslücke.

So sehen fest codierte Anmeldeinformationen aus

python

# Python -- hardcoded database credentials (never do this)
connection = psycopg2.connect(
    host="prod-db.internal.example.com",
    database="accounts",
    user="app_service",
    password="s3cr3tP@ssword!"   # hardcoded secret in source code
)

# Python -- correct approach: load from environment
import os
connection = psycopg2.connect(
    host=os.environ["DB_HOST"],
    database=os.environ["DB_NAME"],
    user=os.environ["DB_USER"],
    password=os.environ["DB_PASSWORD"]
)

Java

// Java -- hardcoded API key (never do this)
private static final String API_KEY = "sk-prod-a1b2c3d4e5f6g7h8i9j0";

// Java -- correct approach: load from environment
private static final String API_KEY = System.getenv("OPENAI_API_KEY");

So beheben Sie fest codierte Anmeldeinformationen

Umgebungsvariablen sind die Standardlösung für Geheimnisse in bereitgestellten Anwendungen. Das Geheimnis wird in der Bereitstellungsumgebung (Server, Container, Kubernetes-Secret oder Cloud Secret Manager) festgelegt und zur Laufzeit abgerufen. Der Quellcode enthält keinen geheimen Wert, sondern nur den Schlüsselnamen, der zum Abrufen verwendet wird.

Geheimnisverwaltungsdienste wie AWS Secrets Manager, HashiCorp Vault, Azure Key Vault und Google Secret Manager sind die produktionsreife Lösung für die Rotation, Überwachung und Verteilung von Geheimnissen über verschiedene Dienste hinweg. Die Anwendung ruft das Geheimnis beim Start (oder bei Bedarf) aus dem Tresor ab, anstatt es aus einer Umgebungsvariablen zu beziehen. Dies ermöglicht die Rotation ohne erneute Bereitstellung und ein vollständiges Zugriffsprotokoll.

.env Dateien (unter Verwendung von Bibliotheken wie python-dotenv or dotenv (in Node.js) eignen sich für die lokale Entwicklung. Sie bieten dieselbe Schnittstelle wie Umgebungsvariablen, laden aber aus einer lokalen Datei. Die wichtigste Regel: .env Die Dateien müssen in .gitignore und darf niemals eingewiesen werden.

Aufdeckung bereits bekannter GeheimnisseWenn ein Geheimnis fest im Code verankert und eingecheckt wurde, sollte es als kompromittiert betrachtet und umgehend rotiert werden. Das Löschen des Wertes aus dem aktuellen Branch entfernt ihn nicht aus dem Git-Verlauf. Tools wie git-filter-branch Oder der BFG Repo Cleaner kann den Verlauf bereinigen, aber die sicherste Annahme nach einem Commit ist, dass das Geheimnis offengelegt wurde.

Wie man fest codierte API-Schlüssel verhindert

Bei API-Schlüsseln von Drittanbietern hängen die Alternativen zur festen Codierung vom Kontext ab:

  • Serverseitige Anwendungen: Umgebungsvariablen oder Dienste zur Geheimnisverwaltung
  • CI / CD-Pipelines: Pipeline-Geheimnisvariablen (GitHub Actions-Geheimnisse, GitLab CI-Variablen)
  • Mobile AnwendungenAPI-Schlüssel sollten niemals im clientseitigen Code gespeichert werden; verwenden Sie stattdessen einen Backend-Proxy, der die API mit dem serverseitig gespeicherten Schlüssel aufruft.
  • KI-Agenten und LLM-Integrationen: API-Schlüssel bei der Initialisierung des Agenten aus der Umgebung laden, niemals als fest codierte Zeichenketten in Eingabeaufforderungen oder Funktionsaufrufen übergeben.

Die sichere Codierung von RPG auf IBM i folgt dem gleichen Prinzip: Externe Datenbereiche, Datenwarteschlangen oder Systemwerte sollten umgebungsspezifische Verbindungsparameter enthalten, anstatt sie im Programmquellcode zu codieren.

Wie man fest codierte Werte vermeidet: Vollständige Muster mit Code

Umgebungsvariablen

Umgebungsvariablen sind die universellste Lösung. Jedes gängige Betriebssystem, jede Cloud-Plattform, jedes Containerisierungssystem und jedes Bereitstellungsframework unterstützt sie.

python

# Python: load all configuration from environment
import os
from dotenv import load_dotenv

load_dotenv()  # loads .env file in development; ignored in production

DATABASE_URL = os.environ["DATABASE_URL"]
API_BASE_URL = os.environ.get("API_BASE_URL", "https://api.example.com")
MAX_RETRIES  = int(os.environ.get("MAX_RETRIES", "3"))
DEBUG_MODE   = os.environ.get("DEBUG", "false").lower() == "true"

Javascript

// Node.js: access environment variables
require('dotenv').config();  // load .env in development

const config = {
  dbUrl:      process.env.DATABASE_URL,
  apiKey:     process.env.API_KEY,
  port:       parseInt(process.env.PORT, 10) || 3000,
  debug:      process.env.NODE_ENV !== 'production',
};

Java

// Java: environment variables via System.getenv()
public class AppConfig {
    public static final String DB_URL  = System.getenv("DATABASE_URL");
    public static final String API_KEY = System.getenv("THIRD_PARTY_API_KEY");
    public static final int    TIMEOUT = Integer.parseInt(
        Optional.ofNullable(System.getenv("REQUEST_TIMEOUT_MS")).orElse("5000")
    );
}

Konfigurationsdateien

Konfigurationsdateien externalisieren Werte, die umgebungsspezifisch, aber nicht geheim sind, Dienstnamen, Funktionsflags, Paginierungsgrößen, Cache-TTLs.

YAML

# config/production.yaml
database:
  host: prod-db.internal
  port: 5432
  pool_size: 20

api:
  base_url: https://api.partner.com/v2
  timeout_ms: 3000
  max_retries: 3

features:
  new_checkout: true
  beta_dashboard: false

python

# Load at startup; never hardcode the values it contains
import yaml

with open(f"config/{os.environ['APP_ENV']}.yaml") as f:
    config = yaml.safe_load(f)

timeout = config["api"]["timeout_ms"]

Abhängigkeitsspritze

Dependency Injection übergibt konfigurierte Werte an Komponenten, anstatt dass Komponenten ihre eigene Konfiguration erstellen oder abrufen. Dadurch lassen sich Komponenten isoliert testen und pro Umgebung konfigurieren.

Java

// Spring Boot: inject configuration via @Value
@Service
public class PaymentService {
    @Value("${payment.api.url}")
    private String apiUrl;

    @Value("${payment.api.timeout-ms}")
    private int timeoutMs;

    // No hardcoded URL or timeout anywhere in this class
    public PaymentResult process(Payment payment) {
        // uses apiUrl and timeoutMs injected from application.properties
    }
}

python

# Python: simple constructor injection
class EmailService:
    def __init__(self, smtp_host: str, smtp_port: int, api_key: str):
        self.smtp_host = smtp_host
        self.smtp_port = smtp_port
        self.api_key   = api_key

# Wire at application startup, reading from environment
email_service = EmailService(
    smtp_host=os.environ["SMTP_HOST"],
    smtp_port=int(os.environ["SMTP_PORT"]),
    api_key=os.environ["EMAIL_API_KEY"],
)

Zentralisierte Konstanten und Aufzählungen

Werte, die per Design tatsächlich festgelegt sind, wie HTTP-Statuscodes, domänenspezifische Zustände und Protokollkennungen, gehören in ein einzelnes, benanntes Konstantenmodul und nicht als Zeichenkettenliterale verstreut.

python

# Python: centralised constants
from enum import Enum

class OrderStatus(Enum):
    PENDING   = "pending"
    CONFIRMED = "confirmed"
    SHIPPED   = "shipped"
    DELIVERED = "delivered"
    CANCELLED = "cancelled"

# Usage: no magic strings scattered across modules
if order.status == OrderStatus.CONFIRMED:
    notify_warehouse(order)

Java

// Java: enum with business meaning
public enum UserRole {
    ADMIN("admin"),
    EDITOR("editor"),
    VIEWER("viewer");

    private final String value;
    UserRole(String value) { this.value = value; }
    public String getValue() { return value; }
}

// Replaces scattered "admin", "editor", "viewer" strings
if (user.getRole() == UserRole.ADMIN) {
    grantFullAccess(user);
}

Festcodierung in bestimmten Sprachen

Was ist Hardcoding in Python?

In Python tritt Hardcoding am häufigsten in Form von Stringliteralen für URLs und Zugangsdaten, numerischen Konstanten in der Geschäftslogik und Dateipfaden auf, die eine bestimmte Verzeichnisstruktur voraussetzen. os.environ und python-dotenv sind die Standardmechanismen für die umgebungsbasierte Konfiguration. configparser Das Modul verarbeitet Konfigurationsdateien im INI-Format. pydantic-settings Es wird eine typvalidierte Konfiguration aus Umgebungsvariablen mit Standardwerten bereitgestellt, was die empfohlene Vorgehensweise für produktive Python-Dienste ist.

Erkennung von fest codierten Werten in Python: Statische Analysetools wie Bandit (für sicherheitsrelevante Festcodierung wie Passwörter und Schlüssel), Pylint und Semgrep können fest codierte Anmeldeinformationen und magische Zahlen automatisch identifizieren.

Was ist Hardcoding in Java?

In Java erscheinen fest codierte Werte oft als private static final String Felder, @Value Annotationen mit Inline-Standardwerten, die externalisiert werden sollen, und Literale in der Geschäftslogik. Spring Boot application.properties und application.yml Dateien sind der Standardmechanismus zur Externalisierung. @ConfigurationProperties-annotierte Klassen stellen typsichere, validierte Konfigurationsobjekte aus YAML- oder Eigenschaftendateien bereit.

Erkennung fest codierter Werte in Java: SpotBugs mit dem Plugin „Sicherheitslücken finden“ erkennt fest codierte Anmeldeinformationen. SonarQube kennzeichnet magische Zahlen, fest codierte URLs und fest codierte Passwörter. SMART TS XLDie Unternehmensanalyse von [Name des Unternehmens] umfasst Java-Codebasen sowie COBOL und andere ältere Programmiersprachen.

Festcodierung in Legacy- und Mainframe-Code

COBOL-, RPG- und PL/I-Programme auf IBM-Großrechnern und Midrange-Systemen weisen spezifische, fest codierte Muster auf: Datensatznamen sind in DD-Anweisungen eingebettet, Umgebungsbezeichner in der Programmlogik und Geschäftsschwellenwerte werden direkt in die Programme kompiliert. Die Externalisierung dieser Werte erfordert Großrechner-fähige Tools: Systemparameter (SYSPARM), externe Datenbereiche, Konfigurationstabellen in DB2 und parametrisiertes JCL. Statische Analysetools, die Großrechnersprachen verstehen, sind notwendig, um diese Muster in großem Umfang zu erkennen.

Refactoring in der Praxis: Von fest codiert zu konfigurierbar

Der dreiphasige Refactoring-Ansatz

Phase 1: Ermittlung. Führen Sie eine statische Codeanalyse durch, um eine Liste der fest codierten Werte zu erstellen. Diese werden nach Typ (Anmeldeinformationen, URLs, Geschäftslogik, Magic Numbers) und Risikostufe gruppiert. Priorisieren Sie Anmeldeinformationen und produktionsspezifische Werte.

Phase 2: Auslagerung nach Kategorien. Beginnen Sie mit den Zugangsdaten (höchstes Risiko): Verlagern Sie alle Geheimnisse in Umgebungsvariablen oder einen Geheimnismanager. Bearbeiten Sie anschließend umgebungsspezifische URLs und Dienstnamen. Danach bearbeiten Sie Schwellenwerte für die Geschäftslogik. Ersetzen Sie schließlich die sogenannten „Magic Numbers“ durch benannte Konstanten oder Konfigurationswerte.

Phase 3: Durchsetzung. Fügen Sie der CI-Pipeline statische Codeanalysen hinzu, die bei neuen, fest codierten Anmeldeinformationen fehlschlagen. Fügen Sie Linting-Regeln hinzu, die sogenannte „Magic Numbers“ kennzeichnen. Ergänzen Sie die Code-Review-Checkliste um Punkte. Ziel ist es, das Hinzufügen eines fest codierten Wertes schwieriger zu gestalten als die Verwendung des korrekten Musters.

Identifizierung fest codierter Werte in Altprojekten

In älteren Projekten, in denen sich über Jahre hinweg fest codierte Werte angesammelt haben:

  • Arbeiten jederzeit weiterbearbeiten können. Jede Präsentation und jeder KI-Avatar, den Sie von Grund auf neu erstellen oder hochladen, grep oder Repository-Suche nach gemeinsamen Mustern: Verbindungszeichenfolgen, password, apikey, IP-Adressmuster und bekannte Dienstnamen
  • Führen Sie statische Analysetools aus (Bandit, SonarQube, Semgrep, SMART TS XL) um eine vollständige Bestandsaufnahme ohne manuelle Datei-für-Datei-Prüfung zu erhalten
  • Überprüfen Sie den Git-Verlauf auf zuvor gespeicherte und gelöschte Geheimnisse; diese sind weiterhin im Repository-Verlauf verfügbar.
  • Suchen Sie nach Werten, die in mehreren Dateien identisch vorkommen; diese sind Kandidaten für eine Zentralisierung.

Verhinderung der Einführung fest codierter Werte

  • Pre-Commit-Hooks: Überprüfung der Anmeldeinformationen durchführen (z. B. detect-secrets, git-secrets, truffleHog) bei jedem Commit, bevor er das Repository erreicht.
  • CI-Pipeline-Gates: Builds, die neu eingeführte Ergebnisse der statischen Analyse für Anmeldeinformationen oder magische Zahlen enthalten, schlagen fehl.
  • Checklisten für Code-Reviews: explizite Elemente für die Konfigurationsexternalisierung im Review-Prozess des Teams
  • Entwickler-Onboarding: Die korrekten Muster als Standardwerte festlegen, eine Projektvorlage bereitstellen, die bereits Umgebungsvariablen verwendet, und eine .env.example Datei

Wie SMART TS XL Eliminiert fest codierte Werte in großem Umfang

Manuelle Suche und grep reichen aus, um offensichtliche Fälle in kleinen Codebasen zu finden. In Enterprise-Systemen mit Millionen von Codezeilen in COBOL, Java, Python, .NET, RPG und SQL erfordert die umfassende Erkennung fest codierter Werte eine automatisierte Strukturanalyse. SMART TS XL führt gleichzeitig eine statische Analyse über alle diese Sprachen hinweg durch und erstellt ein einheitliches Querverweismodell, das Folgendes identifiziert:

  • Literale Zeichenkettenwerte in Verbindungsparametern und Authentifizierungsaufrufen wurden als potenzielle Gefährdung von Anmeldeinformationen gekennzeichnet.
  • Magische Zahlen in der Geschäftslogik werden mit einer konfigurierbaren Basislinie verglichen, um Werte zu identifizieren, die zwischen Modulen inkonsistent sind oder an verschiedenen Stellen unterschiedliche Werte aufweisen.
  • Doppelte Literalwerte, die in mehreren Dateien vorkommen, aber demselben logischen Zweck dienen, weisen auf Zentralisierungspotenziale hin.
  • Werte in COBOL-Programmen, die umgebungsspezifische Bezeichner kodieren, die typischerweise über JCL-Parameter verwaltet werden.
  • Datenflusspfade von fest codierten Werten durch das System, die zeigen, welche nachgelagerten Operationen von ihnen abhängen, bevor eine Refactoring-Entscheidung getroffen wird.

Die statische Codeanalyse erstellt ein Inventar. Die Auswirkungsanalyse zeigt, welche Änderungen sich durch das Ersetzen eines fest codierten Werts ergeben. Die Legacy-Modernisierungsfunktion erweitert dies auf sprach- und plattformübergreifende Szenarien, in denen derselbe logische Wert unabhängig voneinander in einem Mainframe-Programm und einem Java-Dienst fest codiert ist. Dies erfordert eine koordinierte Behebung anstelle isolierter Korrekturen.

Speziell für Teams, die sich mit Wertpapierschulden befassen, SMART TS XLDie Erkennung von fest codierten Zugangsdaten wird als Build-Gate in CI/CD-Pipelines integriert: Neue Commits, die fest codierte Geheimnisse einführen, führen automatisch zu einem Build-Fehler, bevor der Code ein Repository erreicht, in dem er offengelegt werden könnte.

Festcodierung ist ein Disziplinproblem, kein Wissensproblem.

Die meisten Entwickler, die Werte fest im Code verankern, wissen, dass dies nicht angebracht ist. Das Wissen um Umgebungsvariablen, Konfigurationsdateien als korrekte Vorgehensweise und die Tatsache, dass Zugangsdaten niemals im Quellcode gespeichert werden sollten, ist weit verbreitet und allgemein bekannt. Das Problem ist nicht mangelndes Wissen, sondern fehlende Disziplin unter Druck.

Lieferfristen lassen die Einrichtung von Umgebungsvariablen als zusätzlichen Aufwand erscheinen. Legacy-Codebasen machen die Auslagerung von Werten riskanter als deren Beibehaltung. Große Teams mit uneinheitlichem Onboarding erleichtern es neuen Entwicklern, ein bestehendes, aber fehlerhaftes Muster zu kopieren. Die Vermeidung von Hardcoding im Unternehmensmaßstab erfordert daher mehr als Dokumentation: Es bedarf einer automatisierten Durchsetzung, die das falsche Muster schwieriger macht als das richtige.

Pre-Commit-Hooks, die Commits mit Geheimnissen ablehnen, CI-Pipelines, die bei neuen magischen Zahlen fehlschlagen, Code-Review-Checklisten, die explizit nach der Externalisierung von Konfigurationen fragen, und statische Analysetools, die den gesamten Umfang vorhandener fest codierter Werte in einer Codebasis aufdecken: Das sind die Mechanismen, die die Lücke zwischen dem Wissen um den richtigen Ansatz und dessen konsequenter Anwendung schließen. Die Codebeispiele und Muster in diesem Artikel bilden die technische Grundlage. Die Durchsetzungsmechanismen sorgen dafür, dass sie sich auch bewähren.