Erstellung von unveränderlichem Text mit String-Verkettung

Beschreibung

Erstellung von unveränderlichem Text mit String-Verkettung tritt auf, wenn Software unveränderliche Textstrings unter Verwendung wiederholter String-Verkettungsoperationen erstellt, typischerweise innerhalb von Schleifen. In Sprachen, in denen Strings unveränderlich sind (wie Java, C#, Python), erstellt jede Verkettungsoperation ein neues String-Objekt im Speicher, wobei der gesamte existierende Inhalt plus der neue Inhalt kopiert wird. Bei wiederholter Ausführung, insbesondere in Schleifen, führt dies zu O(n²) Zeitkomplexität und exzessiver Speicherallokation, was sowohl Leistungs- als auch potenzielle Sicherheitsbedenken erzeugt.

Risiko

Obwohl hauptsächlich ein Leistungsproblem, kann diese Schwäche Sicherheitsimplikationen haben. Angreifer, die Codepfade mit ineffizienter String-Verkettung auslösen können, könnten dies für Denial-of-Service-Angriffe ausnutzen, indem sie exzessive CPU-Nutzung und Speicherallokation verursachen. Die Verarbeitung größer Eingaben durch ineffiziente String-Erstellung kann Serverressourcen erschöpfen. In Webanwendungen kann dies zu langsamen Reaktionszeiten führen, was das System anfällig für Slowloris-artige Angriffe macht.

Lösung

Verwenden Sie veränderbare String-Builder-Klassen anstelle von Verkettung: StringBuilder in Java/C#, StringBuffer für thread-sichere Szenarien, List-Joining in Python oder String-Streams in C++. Allokieren Sie Kapazität vor, wenn die endgültige Größe bekannt ist oder geschätzt werden kann. Für einfache Fälle mit wenigen Verkettungen ist die Leistungsauswirkung vernachlässigbar, aber verwenden Sie immer Builder in Schleifen oder bei der Verarbeitung von Eingaben variabler Länge.

Häufige Auswirkungen

AuswirkungDetails
VerfügbarkeitBereich: Verfügbarkeit

DoS: Ressourcenverbrauch (CPU) - Wiederholte String-Verkettung in Schleifen verursacht O(n²) Zeitkomplexität und verbraucht exzessive CPU-Zyklen.
VerfügbarkeitBereich: Verfügbarkeit

DoS: Ressourcenverbrauch (Speicher) - Jede Verkettung erstellt neue String-Objekte und erschöpft möglicherweise den Speicher.
AndereBereich: Ändere

Leistungsreduktion - Allgemeine Leistungsverschlechterung, die Denial-of-Service-Angriffe ermöglichen kann.

Beispielcode

Anfälliger Code

// ANFÄLLIG: String-Verkettung in Schleife (Java)
public class VulnerableStringBuilder {

    public String vulnerableBuildHTML(List<String> items) {
        String html = "<ul>";

        // ANFÄLLIG: Jedes += erstellt ein neues String-Objekt
        // O(n²) Komplexität: für n Elemente kopiert ca. n²/2 Zeichen
        for (String item : items) {
            html += "<li>" + item + "</li>";  // Erstellt mehrere neue Strings
        }

        html += "</ul>";
        return html;
    }

    // Mit 10.000 Elementen erstellt dies ~50 Millionen Zeichenkopien
}
# ANFÄLLIG: String-Verkettung in Python
def vulnerable_build_csv(records):
    csv_data = ""

    # ANFÄLLIG: Python-Strings sind unveränderlich
    # Jedes += erstellt ein neues String-Objekt
    for record in records:
        line = ""
        for field in record:
            line += str(field) + ","  # Mehrere Allokationen pro Feld
        line = line[:-1]  # Entferne nachfolgendes Komma
        csv_data += line + "\n"  # Mehr Allokationen

    return csv_data

# Verarbeitung von 100.000 Datensätzen wird extrem langsam

Korrigierter Code

// KORRIGIERT: StringBuilder in Java verwenden
public class FixedStringBuilder {

    public String fixedBuildHTML(List<String> items) {
        // KORRIGIERT: StringBuilder ist veränderbar, O(n) Komplexität
        StringBuilder html = new StringBuilder();

        // Kapazität vorallokieren wenn Größe bekannt
        html.ensureCapacity(items.size() * 25 + 10);

        html.append("<ul>");

        for (String item : items) {
            html.append("<li>")
                .append(escapeHtml(item))  // XSS auch beheben!
                .append("</li>");
        }

        html.append("</ul>");
        return html.toString();
    }

    // Thread-sichere Version mit StringBuffer
    public String fixedBuildHTMLThreadSafe(List<String> items) {
        StringBuffer html = new StringBuffer();
        html.append("<ul>");

        for (String item : items) {
            synchronized (html) {
                html.append("<li>")
                    .append(escapeHtml(item))
                    .append("</li>");
            }
        }

        html.append("</ul>");
        return html.toString();
    }
}
# KORRIGIERT: List-Join in Python verwenden
def fixed_build_csv(records):
    # KORRIGIERT: Liste von Zeilen erstellen, dann einmal verbinden
    lines = []

    for record in records:
        # Join für Felder innerhalb jeder Zeile verwenden
        line = ",".join(str(field) for field in record)
        lines.append(line)

    # Einzelne Join-Operation am Ende
    return "\n".join(lines)


# Alternativ: StringIO für stream-ähnliches Erstellen verwenden
from io import StringIO

def fixed_build_csv_stringio(records):
    buffer = StringIO()

    for record in records:
        buffer.write(",".join(str(field) for field in record))
        buffer.write("\n")

    return buffer.getvalue()


# Am besten für CSV: csv-Modul verwenden
import csv
from io import StringIO

def fixed_build_csv_proper(records):
    buffer = StringIO()
    writer = csv.writer(buffer)
    writer.writerows(records)
    return buffer.getvalue()
// KORRIGIERT: strings.Builder in Go verwenden
import (
    "strings"
    "fmt"
)

func fixedBuildLog(entries []LogEntry) string {
    // KORRIGIERT: strings.Builder ist effizient für String-Erstellung
    var builder strings.Builder

    // Puffer vorvergrößern wenn Größe bekannt
    builder.Grow(len(entries) * 100)

    for _, entry := range entries {
        fmt.Fprintf(&builder, "[%s] %s: %s\n",
            entry.Timestamp, entry.Level, entry.Message)
    }

    return builder.String()
}

CVE-Beispiele

Diese CWE ist hauptsächlich ein Leistungs-/Qualitätsproblem. Obwohl keine direkten CVEs spezifisch der String-Verkettung zugeschrieben werden, haben Leistungsschwachstellen durch ineffiziente String-Handhabung zu Denial-of-Service-Bedingungen in verschiedenen Anwendungen beigetragen.


Verwandte CWEs

  • CWE-1176: Inefficient CPU Computation (Eltern)
  • CWE-1006: Bad Coding Practices (Kategoriemitglied)
  • CWE-400: Uncontrolled Resource Consumption (kann führen zu)

Referenzen

  1. MITRE Corporation. "CWE-1046: Creation of Immutable Text Using String Concatenation." https://cwe.mitre.org/data/definitions/1046.html

  2. Oracle. "Java StringBuilder Class Documentation."

  3. Microsoft. "StringBuilder Class (System.Text)."