Source Code File with Excessive Number of Lines of Code
Description
Source Code File with Excessive Number of Lines of Code occurs when a source code file contains too many lines of code. CISQ recommends a default threshold of 1000 lines as the measure for excessive code. Large files are difficult to understand, maintain, navigate, and review for security issues. They often indicate that the file contains multiple responsibilities that should be separated according to the Single Responsibility Principle.
Risk
Excessively large files have indirect security implications. Security code reviews become impractical for very large files. Developers may skip thorough review due to cognitive overload. Vulnerabilities are easier to hide in large files. The complexity increases the likelihood of introducing bugs during maintenance. Merge conflicts are more frequent, potentially leading to security regressions. Testing coverage is typically lower for complex files. Automated security tools may timeout or produce overwhelming results.
Solution
Apply the Single Responsibility Principle - each file should have one reason to change. Extract related functionality into separate modules or classes. Use feature-based file organization. Create utility modules for shared functionality. Split large classes into smaller, focused classes. Apply design patterns to reduce complexity. Set maximum file length as a coding standard. Use static analysis to enforce file size limits. Refactor legacy large files incrementally. Consider domain-driven design for organizing code.
Common Consequences
| Impact | Details |
|---|---|
| Other | Scope: Other Reduce Maintainability - Large files are difficult to understand and modify safely. |
| Other | Scope: Other Increase Analytical Complexity - Security review of large files is impractical. |
| Other | Scope: Other Quality Degradation - Testing and code review coverage suffer with large files. |
Example Code
Vulnerable Code
// Vulnerable: Single file with excessive code (abbreviated example)
// In reality, this file has 5000+ lines
public class VulnerableMonolithicService {
// ===== Authentication Section (lines 1-500) =====
private Map<String, User> users = new HashMap<>();
private Map<String, Session> sessions = new HashMap<>();
public boolean authenticate(String username, String password) {
// 50 lines of authentication code
}
public Session createSession(User user) {
// 30 lines of session creation
}
// ... 20 more authentication methods ...
// ===== Authorization Section (lines 501-1000) =====
private Map<String, List<Permission>> rolePermissions = new HashMap<>();
public boolean hasPermission(User user, String permission) {
// 40 lines of permission checking
}
// ... 25 more authorization methods ...
// ===== User Management Section (lines 1001-1800) =====
public User createUser(UserDTO dto) {
// 80 lines of user creation
}
public void updateUser(String userId, UserDTO dto) {
// 60 lines of user update
}
// ... 30 more user management methods ...
// ===== Data Access Section (lines 1801-2800) =====
private Connection getConnection() {
// Database connection code
}
public List<User> findUsers(SearchCriteria criteria) {
// 100 lines of complex query building
}
// ... 40 more data access methods ...
// ===== Email Section (lines 2801-3500) =====
public void sendEmail(String to, String subject, String body) {
// 70 lines of email sending
}
// ... 20 more email methods ...
// ===== Logging Section (lines 3501-4000) =====
private void logActivity(String action, User user) {
// 40 lines of activity logging
}
// ... 15 more logging methods ...
// ===== Reporting Section (lines 4001-5000) =====
public Report generateUserReport(Date start, Date end) {
// 200 lines of report generation
}
// ... 30 more reporting methods ...
// Problems:
// 1. 5000+ lines in one file
// 2. Multiple responsibilities (auth, users, email, reports)
// 3. Security review is nearly impossible
// 4. Testing is extremely difficult
// 5. Any change risks breaking unrelated functionality
}
Fixed Code
// Fixed: Separate files for each responsibility
// ===== File 1: AuthenticationService.java (150 lines) =====
package com.example.security;
public class AuthenticationService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final SessionManager sessionManager;
public AuthenticationService(UserRepository userRepository,
PasswordEncoder passwordEncoder,
SessionManager sessionManager) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
this.sessionManager = sessionManager;
}
public AuthResult authenticate(String username, String password) {
User user = userRepository.findByUsername(username);
if (user == null) {
return AuthResult.userNotFound();
}
if (!passwordEncoder.matches(password, user.getPasswordHash())) {
return AuthResult.invalidPassword();
}
Session session = sessionManager.createSession(user);
return AuthResult.success(session);
}
public void logout(String sessionId) {
sessionManager.invalidateSession(sessionId);
}
}
// ===== File 2: AuthorizationService.java (120 lines) =====
package com.example.security;
public class AuthorizationService {
private final RoleRepository roleRepository;
private final PermissionCache permissionCache;
public AuthorizationService(RoleRepository roleRepository,
PermissionCache permissionCache) {
this.roleRepository = roleRepository;
this.permissionCache = permissionCache;
}
public boolean hasPermission(User user, String permission) {
Set<Permission> permissions = permissionCache.getPermissions(user.getRoleId());
return permissions.stream()
.anyMatch(p -> p.getName().equals(permission));
}
public boolean hasRole(User user, String roleName) {
Role role = roleRepository.findById(user.getRoleId());
return role != null && role.getName().equals(roleName);
}
}
// ===== File 3: UserService.java (200 lines) =====
package com.example.users;
public class UserService {
private final UserRepository userRepository;
private final UserValidator validator;
private final EventPublisher eventPublisher;
public UserService(UserRepository userRepository,
UserValidator validator,
EventPublisher eventPublisher) {
this.userRepository = userRepository;
this.validator = validator;
this.eventPublisher = eventPublisher;
}
public User createUser(CreateUserRequest request) {
validator.validateCreateRequest(request);
User user = new User();
user.setUsername(request.getUsername());
user.setEmail(request.getEmail());
// ... map other fields
User saved = userRepository.save(user);
eventPublisher.publish(new UserCreatedEvent(saved));
return saved;
}
public User updateUser(String userId, UpdateUserRequest request) {
validator.validateUpdateRequest(request);
User user = userRepository.findById(userId);
if (user == null) {
throw new UserNotFoundException(userId);
}
// ... update fields
return userRepository.save(user);
}
}
// ===== File 4: UserRepository.java (80 lines) =====
package com.example.users;
public interface UserRepository {
User findById(String id);
User findByUsername(String username);
User findByEmail(String email);
List<User> findAll(Pageable pageable);
User save(User user);
void delete(String id);
}
// ===== File 5: EmailService.java (100 lines) =====
package com.example.notifications;
public class EmailService {
private final EmailClient emailClient;
private final TemplateEngine templateEngine;
public EmailService(EmailClient emailClient,
TemplateEngine templateEngine) {
this.emailClient = emailClient;
this.templateEngine = templateEngine;
}
public void sendWelcomeEmail(User user) {
String content = templateEngine.render("welcome", Map.of("user", user));
emailClient.send(user.getEmail(), "Welcome!", content);
}
public void sendPasswordReset(User user, String token) {
String content = templateEngine.render("password-reset",
Map.of("user", user, "token", token));
emailClient.send(user.getEmail(), "Password Reset", content);
}
}
// ===== File 6: ReportService.java (150 lines) =====
package com.example.reports;
public class ReportService {
private final ReportRepository reportRepository;
private final ReportGenerator generator;
public ReportService(ReportRepository reportRepository,
ReportGenerator generator) {
this.reportRepository = reportRepository;
this.generator = generator;
}
public Report generateUserReport(ReportCriteria criteria) {
List<User> users = reportRepository.findUsersForReport(criteria);
return generator.generate(users, criteria);
}
}
Fixed Project Structure:
------------------------
src/main/java/com/example/
├── security/
│ ├── AuthenticationService.java (150 lines)
│ ├── AuthorizationService.java (120 lines)
│ ├── SessionManager.java (80 lines)
│ ├── PasswordEncoder.java (50 lines)
│ └── PermissionCache.java (60 lines)
├── users/
│ ├── UserService.java (200 lines)
│ ├── UserRepository.java (80 lines)
│ ├── UserValidator.java (100 lines)
│ └── dto/
│ ├── CreateUserRequest.java (30 lines)
│ └── UpdateUserRequest.java (30 lines)
├── notifications/
│ ├── EmailService.java (100 lines)
│ ├── EmailClient.java (60 lines)
│ └── TemplateEngine.java (80 lines)
├── reports/
│ ├── ReportService.java (150 lines)
│ ├── ReportGenerator.java (120 lines)
│ └── ReportRepository.java (70 lines)
└── logging/
├── ActivityLogger.java (80 lines)
└── AuditService.java (100 lines)
Benefits:
- Each file under 200 lines
- Single responsibility per file
- Easy to review for security issues
- Testable in isolation
- Clear separation of concerns
CVE Examples
This CWE is marked as PROHIBITED for direct CVE mapping as it represents a code quality/maintainability concern rather than a direct security vulnerability.
Related CWEs
- CWE-1120: Excessive Code Complexity (parent)
- CWE-1226: Complexity Issues (category member)
- CWE-1047: Modules with Circular Dependencies (related)
References
- MITRE Corporation. "CWE-1080: Source Code File with Excessive Number of Lines of Code." https://cwe.mitre.org/data/definitions/1080.html
- CISQ. "Automated Source Code Quality Measures."
- Martin, Robert C. "Clean Code: A Handbook of Agile Software Craftsmanship."