Inkonsistenz zwischen Implementierung und dokumentiertem Design

Beschreibung

Inkonsistenz zwischen Implementierung und dokumentiertem Design tritt auf, wenn die Implementierung eines Produkts nicht mit dem Design übereinstimmt, wie es in der relevanten Dokumentation beschrieben ist. Dies umfasst Diskrepanzen zwischen Architekturdokumenten und tatsächlicher Codestruktur, API-Dokumentation die nicht dem tatsächlichen Verhalten entspricht, Sicherheitsdesigndokumente die Kontrollen beschreiben die nicht tatsächlich implementiert sind, und Konfigurationsanleitungen die nicht die tatsächlichen Einstellungen widerspiegeln. Diese Inkonsistenzen erzeugen Verwirrung, erhöhen den Wartungsaufwand und können Sicherheitsimplikationen haben, wenn angenommene Sicherheitskontrollen nicht tatsächlich vorhanden sind.

Risiko

Dokumentationsinkonsistenz erzeugt indirekte aber signifikante Sicherheitsrisiken. Dokumentierte aber nicht implementierte Sicherheitskontrollen geben falsche Sicherheit. Sicherheitsauditoren können Systeme basierend auf ungenauer Dokumentation genehmigen. Entwickler können unsichere Annahmen basierend auf veralteten Designdokumenten treffen. Incident Response wird behindert, wenn Dokumentation nicht der Realität entspricht. Compliance-Verstoße treten auf, wenn dokumentierte Kontrollen nicht implementiert sind. Bedrohungsmodelle basierend auf ungenauen Architekturdiagrammen übersehen echte Angriffsvektoren. Benutzer und Integratoren können Systeme basierend auf falscher Dokumentation falsch konfigurieren.

Lösung

Implementieren Sie Documentation-as-Code-Praktiken, bei denen Dokumentation zusammen mit Code versioniert wird. Verwenden Sie automatisierte Tools zur Generierung von API-Dokumentation aus Code (OpenAPI, JSDoc usw.). Nehmen Sie Dokumentationsaktualisierungen in Code-Review-Checklisten auf. Führen Sie regelmäßige Dokumentationsaudits durch, die Dokumentation mit Implementierung vergleichen. Verwenden Sie Architecture Fitness Functions, um zu verifizieren dass Implementierung dem Design entspricht. Automatisieren Sie Tests dokumentierten Verhaltens. Erstellen Sie Rückverfolgbarkeit zwischen Anforderungen, Designdokumenten und Implementierung. Verwenden Sie lebende Dokumentation, die sich mit dem Code aktualisiert. Nehmen Sie Dokumentationsgenauigkeit in die Definition of Done auf.

Häufige Auswirkungen

AuswirkungDetails
AndereBereich: Ändere

Reduzierte Wartbarkeit - Inkonsistente Dokumentation macht das System schwerer zu verstehen und korrekt zu warten.
AndereBereich: Ändere

Qualitätsverschlechterung - Entwickler und Benutzer treffen falsche Annahmen basierend auf falscher Dokumentation.
ZugriffskontrolleBereich: Zugriffskontrolle

Schutzmechanismus umgehen - Dokumentierte Sicherheitskontrollen sind möglicherweise nicht tatsächlich implementiert.

Beispielcode

Anfälliger Code

// Der "Code" für diese CWE demonstriert Dokumentations-/Implementierungsdiskrepanz

/* ============================================================
   BEISPIEL Für DOKUMENTATIONS-/IMPLEMENTIERUNGSINKONSISTENZ
   ============================================================

   API-DOKUMENTATION (api-docs.yaml):
   ----------------------------------

   /api/users/{id}:
     get:
       description: Benutzer nach ID abrufen
       security:
         - bearerAuth: []           # Doku sagt Auth erforderlich
       parameters:
         - name: id
           in: path
           required: true
           schema:
             type: integer
       responses:
         200:
           description: Benutzerobjekt
           content:
             application/json:
               schema:
                 type: object
                 properties:
                   id:
                     type: integer
                   username:
                     type: string
                   email:
                     type: string   # Doku zeigt E-Mail in Antwort

   TATSÄCHLICHE IMPLEMENTIERUNG:
   -----------------------------
*/

// Der tatsächliche Code stimmt nicht mit der Dokumentation überein
@RestController
public class UserController {

    @GetMapping("/api/users/{id}")
    // DISKREPANZ: Keine @Secured-Annotation - Auth nicht tatsächlich erforderlich!
    public User getUser(@PathVariable String id) {  // DISKREPANZ: String, nicht integer
        User user = userService.findById(id);

        // DISKREPANZ: Gibt auch Passwort-Hash zurück, nicht dokumentiert!
        return user;
    }
}

public class User {
    private String id;        // DISKREPANZ: String, Doku sagt integer
    private String username;
    private String email;
    private String password;  // SICHERHEIT: Zurückgegeben aber nicht dokumentiert!
    private String ssn;       // SICHERHEIT: Sensible Daten nicht in Doku!
}

/* ============================================================
   SICHERHEITSARCHITEKTURDOKUMENT (security-design.md):
   ============================================================

   "Alle API-Endpunkte erfordern JWT-Authentifizierung.
    Passwörter werden mit bcrypt mit Kostenfaktor 12 gehasht.
    Alle sensiblen Daten werden im Ruhezustand mit AES-256 verschlüsselt.
    Rate-Limiting wird angewendet: 100 Anfragen pro Minute pro Benutzer."

   TATSÄCHLICHE IMPLEMENTIERUNGSDISKREPANZEN:
   -------------------------------------------
*/

@Configuration
public class SecurityConfig {

    // DISKREPANZ: Einige Endpunkte sind öffentlich, entgegen der Doku
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) {
        http.authorizeRequests()
            .antMatchers("/api/public/**").permitAll()  // Nicht dokumentiert!
            .antMatchers("/api/admin/**").permitAll()   // SICHERHEITSLÜCKE!
            .anyRequest().authenticated();

        return http.build();
    }

    // DISKREPANZ: bcrypt-Kosten sind 10, Doku sagt 12
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(10);  // Doku sagt 12!
    }

    // FEHLEND: Kein Rate-Limiting überhaupt implementiert!
}

// FEHLEND: Keine Verschlüsselung im Ruhezustand - Daten im Klartext gespeichert
@Entity
public class SensitiveData {
    private String creditCardNumber;  // Nicht verschlüsselt!
    private String ssn;               // Nicht verschlüsselt!
}

Korrigierter Code

// Korrigiert: Dokumentation automatisch aus Code generiert

/**
 * User Controller - behandelt benutzerbezogene API-Operationen.
 *
 * Sicherheit: Alle Endpunkte erfordern JWT-Authentifizierung, sofern nicht anders markiert.
 * Rate-Limit: 100 Anfragen/Minute pro authentifiziertem Benutzer.
 */
@RestController
@RequestMapping("/api/users")
@Validated
@Tag(name = "Users", description = "Benutzerverwaltungs-Endpunkte")
public class FixedUserController {

    private final UserService userService;

    /**
     * Benutzer nach ID abrufen.
     *
     * @param id Benutzer-ID (UUID-Format)
     * @return Benutzerdetails (ohne sensible Felder)
     * @throws NotFoundException wenn Benutzer nicht gefunden
     */
    @GetMapping("/{id}")
    @Secured("ROLE_USER")  // Korrigiert: Auth durch Annotation erzwungen
    @Operation(
        summary = "Benutzer nach ID abrufen",
        description = "Ruft Benutzerdetails ab. Erfordert Authentifizierung.",
        security = @SecurityRequirement(name = "bearerAuth")
    )
    @ApiResponses({
        @ApiResponse(
            responseCode = "200",
            description = "Benutzer gefunden",
            content = @Content(schema = @Schema(implementation = UserResponse.class))
        ),
        @ApiResponse(responseCode = "401", description = "Nicht authentifiziert"),
        @ApiResponse(responseCode = "404", description = "Benutzer nicht gefunden")
    })
    public UserResponse getUser(
        @Parameter(description = "Benutzer-UUID", required = true)
        @PathVariable UUID id  // Korrigiert: Typ entspricht Dokumentation
    ) {
        User user = userService.findById(id);
        return UserResponse.fromUser(user);  // Korrigiert: DTO schließt sensible Daten aus
    }
}

// Korrigiert: Antwort-DTO - enthält nur dokumentierte Felder
@Schema(description = "Benutzer-Antwortobjekt")
public class UserResponse {

    @Schema(description = "Benutzer-ID", example = "123e4567-e89b-12d3-a456-426614174000")
    private UUID id;

    @Schema(description = "Benutzername", example = "johndoe")
    private String username;

    @Schema(description = "E-Mail-Adresse", example = "[email protected]")
    private String email;

    // Korrigiert: Kein Passwort, SSN oder andere sensible Felder exponiert

    public static UserResponse fromUser(User user) {
        UserResponse response = new UserResponse();
        response.id = user.getId();
        response.username = user.getUsername();
        response.email = user.getEmail();
        // Sensible Felder absichtlich ausgeschlossen
        return response;
    }
}
// Korrigiert: Sicherheitskonfiguration entspricht Dokumentation
@Configuration
@EnableWebSecurity
public class FixedSecurityConfig {

    // Korrigiert: Konfiguration entspricht Sicherheitsdesigndokument
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                // Korrigiert: Öffentliche Endpunkte explizit dokumentiert
                .antMatchers("/api/health", "/api/docs/**").permitAll()
                // Korrigiert: Alle anderen Endpunkte erfordern Authentifizierung
                .anyRequest().authenticated()
            .and()
            .oauth2ResourceServer()
                .jwt();

        return http.build();
    }

    // Korrigiert: bcrypt-Kosten entsprechen Dokumentation (12)
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(12);
    }

    // Korrigiert: Rate-Limiting wie dokumentiert implementiert
    @Bean
    public RateLimiter rateLimiter() {
        return RateLimiter.of("api",
            RateLimiterConfig.custom()
                .limitForPeriod(100)           // 100 Anfragen
                .limitRefreshPeriod(Duration.ofMinutes(1))  // pro Minute
                .build());
    }
}

// Korrigiert: Verschlüsselung im Ruhezustand wie dokumentiert implementiert
@Entity
@EntityListeners(EncryptionListener.class)
public class FixedSensitiveData {

    @Id
    private UUID id;

    @Encrypted  // Benutzerdefinierte Annotation löst AES-256-Verschlüsselung aus
    private String creditCardNumber;

    @Encrypted
    private String ssn;
}

// Korrigiert: Automatisierter Dokumentationskonsistenztest
@SpringBootTest
public class DocumentationConsistencyTest {

    @Autowired
    private SecurityFilterChain securityFilterChain;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Test
    void securityConfigurationMatchesDocumentation() {
        // Verifizieren dass bcrypt-Kostenfaktor 12 ist wie dokumentiert
        BCryptPasswordEncoder bcrypt = (BCryptPasswordEncoder) passwordEncoder;
        // Konfiguration gegen Doku assertieren

        // Verifizieren dass alle nicht-öffentlichen Endpunkte Auth erfordern
        // Dieser Test schlägt fehl wenn Konfiguration nicht mit Doku übereinstimmt
    }

    @Test
    void allSensitiveFieldsAreEncrypted() {
        // Reflexion verwenden um zu verifizieren dass alle @Encrypted-Felder
        // ordnungsgemäß behandelt werden
    }
}

CVE-Beispiele

Diese CWE ist für direkte CVE-Zuordnung als VERBOTEN markiert, da sie ein Dokumentations-/Qualitätsproblem und keine direkte Sicherheitsschwachstelle darstellt.


Verwandte CWEs

  • CWE-710: Improper Adherence to Coding Standards (Eltern)
  • CWE-1059: Insufficient Technical Documentation (verwandt)
  • CWE-1225: Documentation Issues (Kategoriemitglied)

Referenzen

  1. MITRE Corporation. "CWE-1068: Inconsistency Between Implementation and Documented Design." https://cwe.mitre.org/data/definitions/1068.html

  2. Docs as Code. "Documentation as Code Principles." https://www.writethedocs.org/guide/docs-as-code/

  3. OpenAPI Initiative. "OpenAPI Specification." https://swagger.io/specification/