Architektur mit Anzahl horizontaler Schichten außerhalb des erwarteten Bereichs
Beschreibung
Architektur mit Anzahl horizontaler Schichten außerhalb des erwarteten Bereichs tritt auf, wenn die Architektur eines Softwaresystems zu viele oder zu wenige horizontale Schichten im Vergleich zu branchenempfohlenen Standards enthält. CISQ (Consortium for Information and Software Quality) empfiehlt standardmäßig mindestens 4 Schichten und maximal 8 Schichten für Produktarchitekturen. Zu wenige Schichten deuten oft auf mangelhafte Trennung von Belangen hin, während zu viele Schichten unnötige Komplexität, Leistungsoverhead und Wartungsherausforderungen einführen können.
Risiko
Obwohl hauptsächlich ein architektonisches Qualitätsproblem, hat unsachgemäße Schichtung indirekte Sicherheitsimplikationen. Zu wenige Schichten bedeuten oft, dass Sicherheitslogik über die gesamte Codebasis verstreut ist, anstatt zentralisiert zu sein, was Audits erschwert und Umgehungen erleichtert. Systeme mit zu vielen Schichten führen zusätzliche Angriffsfläche durch Inter-Layer-Kommunikation ein und erhöhen das Risiko der Datenoffenlegung, wenn Informationen durch mehrere Grenzen geleitet werden. Komplexe Architekturen sind schwerer zu sichern, da das Verständnis des vollständigen Datenflusses die Navigation durch viele Abstraktionsebenen erfordert.
Lösung
Entwerfen Sie Architekturen mit einer angemessenen Anzahl horizontaler Schichten, typischerweise zwischen 4 und 8. Gängige Schichtmuster umfassen: Präsentationsschicht (UI), Anwendungs-/Service-Schicht, Geschäftslogik-Schicht und Datenzugriffsschicht. Fügen Sie sicherheitsspezifische Schichten (Authentifizierung, Autorisierung) als dedizierte Belange hinzu. Stellen Sie sicher, dass jede Schicht klare Verantwortlichkeiten und Schnittstellen hat. Dokumentieren Sie die Architektur und Schichtzwecke. Überprüfen Sie Architekturentscheidungen während Sicherheitsbewertungen.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Andere | Bereich: Ändere Reduzierte Wartbarkeit - Unsachgemäße Schichtung erschwert die Produktwartung und beeinflusst indirekt die Sicherheit, indem Schwachstellenerkennung und -behebung schwieriger werden. |
| Andere | Bereich: Ändere Qualitätsverschlechterung - Architektonische Komplexität kann die Einführung von Sicherheitsmängeln erleichtern und deren Identifikation erschweren. |
Beispielcode
Anfälliger Code
// ANFÄLLIG: Zu wenige Schichten - alles in einer Klasse
// Keine Trennung von Belangen, Sicherheit überall verstreut
public class VulnerableMonolithicApp {
private Connection dbConnection;
// Präsentation, Geschäftslogik und Datenzugriff alle gemischt
public void handleUserRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
// Direkte HTML-Generierung (Präsentation)
PrintWriter out = response.getWriter();
out.println("<html><body>");
// Authentifizierung mit Geschäftslogik vermischt
String username = request.getParameter("username");
String password = request.getParameter("password");
// Direktes SQL (Datenzugriff) - SQL-Injection anfällig
Statement stmt = dbConnection.createStatement();
ResultSet rs = stmt.executeQuery(
"SELECT * FROM users WHERE username='" + username +
"' AND password='" + password + "'"
);
if (rs.next()) {
// Autorisierungsprüfung inline
String role = rs.getString("role");
if ("admin".equals(role)) {
ResultSet data = stmt.executeQuery("SELECT * FROM sensitive_data");
while (data.next()) {
out.println("<p>" + data.getString("info") + "</p>");
}
}
}
out.println("</body></html>");
}
// Sicherheitslogik kann nicht einfach auditiert oder gewartet werden
}
Korrigierter Code
// KORRIGIERT: Angemessene geschichtete Architektur (4-5 Schichten)
// Schicht 1: Präsentationsschicht - behandelt HTTP-Belange
@Controller
public class UserController {
private final UserService userService;
private final SecurityContext securityContext;
@PostMapping("/login")
public ResponseEntity<LoginResponse> login(@RequestBody LoginRequest request) {
// Behandelt nur HTTP-Belange, delegiert an Service-Schicht
try {
AuthResult result = userService.authenticate(
request.getUsername(),
request.getPassword()
);
return ResponseEntity.ok(new LoginResponse(result.getToken()));
} catch (AuthenticationException e) {
return ResponseEntity.status(401).build();
}
}
@GetMapping("/data")
@RequiresRole("ADMIN") // Sicherheit ist deklarativ und zentralisiert
public ResponseEntity<DataResponse> getSensitiveData() {
List<DataItem> data = userService.getSensitiveData(
securityContext.getCurrentUser()
);
return ResponseEntity.ok(new DataResponse(data));
}
}
// Schicht 2: Service/Anwendungsschicht - Geschäftslogik
@Service
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final TokenService tokenService;
private final AuditService auditService;
public AuthResult authenticate(String username, String password) {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new AuthenticationException("Ungültige Anmeldedaten"));
if (!passwordEncoder.matches(password, user.getPasswordHash())) {
auditService.logFailedLogin(username);
throw new AuthenticationException("Ungültige Anmeldedaten");
}
auditService.logSuccessfulLogin(username);
String token = tokenService.generateToken(user);
return new AuthResult(user, token);
}
}
// Schicht 3: Sicherheitsschicht - querschnittliche Sicherheitsbelange
@Component
public class SecurityService {
private final TokenValidator tokenValidator;
private final RoleChecker roleChecker;
public void validateAccess(String token, String requiredRole) {
User user = tokenValidator.validateAndExtract(token);
if (!roleChecker.hasRole(user, requiredRole)) {
throw new AccessDeniedException("Unzureichende Berechtigungen");
}
}
}
// Schicht 4: Datenzugriffsschicht - Datenbankoperationen
@Repository
public class UserRepository {
private final JdbcTemplate jdbcTemplate;
public Optional<User> findByUsername(String username) {
// Parametrisierte Abfragen verhindern SQL-Injection
return jdbcTemplate.queryForOptional(
"SELECT * FROM users WHERE username = ?",
new UserRowMapper(),
username
);
}
}
CVE-Beispiele
Diese CWE ist für direkte CVE-Zuordnung als VERBOTEN markiert, da sie ein architektonisches Qualitätsproblem und keine direkte Sicherheitsschwachstelle darstellt.
Verwandte CWEs
- CWE-710: Improper Adherence to Coding Standards (Eltern)
- CWE-1006: Bad Coding Practices (Kategoriemitglied)
- CWE-1130: CISQ Quality Measures - Maintainability (Kategoriemitglied)
Referenzen
-
MITRE Corporation. "CWE-1044: Architecture with Number of Horizontal Layers Outside of Expected Range." https://cwe.mitre.org/data/definitions/1044.html
-
CISQ. "Automated Source Code Quality Measures."
-
Fowler, Martin. "Patterns of Enterprise Application Architecture."