Какие ключевые задачи решает тестирование безопасности
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Ключевые задачи тестирования безопасности
Тестирование безопасности (Security Testing) — критический компонент SDLC, который выявляет уязвимости до попадания в production. Это не просто поиск ошибок, а стратегический процесс защиты приложения.
Основные задачи Security Testing
1. Выявление уязвимостей (Vulnerability Discovery)
Задача: Найти недостатки, которые может эксплуатировать злоумышленник
Типовые уязвимости:
// ❌ SQL Injection
public User findUser(String userId) {
String query = "SELECT * FROM users WHERE id = " + userId;
return repository.executeRaw(query);
// Хакер вводит: 1; DROP TABLE users; --
}
// ✅ Правильно
public User findUser(String userId) {
return repository.findById(userId);
// Параметризованный запрос защищен автоматически
}
// ❌ XSS (Cross-Site Scripting)
@GetMapping("/search")
public String search(@RequestParam String query) {
return "<h1>Results for " + query + "</h1>";
// Хакер вводит: <script>alert('hacked')</script>
}
// ✅ Правильно (Escaping/Encoding)
public String search(@RequestParam String query) {
String safe = HtmlUtils.htmlEscape(query);
return "<h1>Results for " + safe + "</h1>";
}
// ❌ Insecure Deserialization
ObjectInputStream ois = new ObjectInputStream(inputStream);
Object obj = ois.readObject(); // Опасно!
// ✅ Правильно
// Используй JSON вместо Java serialization
// Или используй List<Class<?>> allowedClasses = ...
OWASP Top 10 основные уязвимости:
- Injection attacks (SQL, NoSQL, Command Injection)
- Broken Authentication
- Sensitive Data Exposure
- XML External Entities (XXE)
- Broken Access Control
- Security Misconfiguration
- Cross-Site Scripting (XSS)
- Insecure Deserialization
- Using Components with Known Vulnerabilities
- Insufficient Logging & Monitoring
2. Проверка аутентификации и авторизации
Задача: Убедиться, что только авторизованные пользователи получают доступ к ресурсам
// Unit тест для проверки доступа
@Test
public void testUnauthorizedUserCannotAccessAdminPanel() {
User regularUser = createUser("user@example.com", "USER");
assertThrows(AccessDeniedException.class, () -> {
adminService.deleteUser(regularUser, targetUser);
});
}
// Integration тест
@Test
public void testJWTTokenValidation() {
String invalidToken = "invalid.token.here";
mockMvc.perform(get("/api/protected")
.header("Authorization", "Bearer " + invalidToken))
.andExpect(status().isUnauthorized());
}
// Spring Security config
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.logout();
return http.build();
}
}
Проверяемые элементы:
- Сильные пароли (минимум 12 символов, сложность)
- Защита от brute force (rate limiting)
- Двухфакторная аутентификация
- Session management (timeout, regeneration)
- Role-Based Access Control (RBAC)
3. Тестирование обработки входных данных
Задача: Убедиться, что приложение правильно валидирует и обрабатывает входные данные
// ❌ Опасно
@PostMapping("/api/users")
public User createUser(@RequestBody Map<String, Object> data) {
User user = new User();
user.setAdmin((Boolean) data.get("isAdmin")); // Хакер может установить себе admin!
return userRepository.save(user);
}
// ✅ Правильно
@PostMapping("/api/users")
public User createUser(@RequestBody @Valid CreateUserRequest request) {
User user = new User();
user.setEmail(request.getEmail());
user.setName(request.getName());
user.setRole("USER"); // Роль всегда присваивается серверной логикой
return userRepository.save(user);
}
@Data
class CreateUserRequest {
@NotNull
@Email
private String email;
@NotNull
@Size(min = 3, max = 100)
private String name;
}
// Тест валидации
@Test
public void testInvalidEmailIsRejected() {
CreateUserRequest request = new CreateUserRequest();
request.setEmail("not-an-email");
request.setName("Test");
Set<ConstraintViolation<CreateUserRequest>> violations =
validator.validate(request);
assertFalse(violations.isEmpty());
}
Типы проверок входных данных:
- Валидация формата (email, phone, credit card)
- Проверка граничных значений
- Проверка размера (buffer overflow prevention)
- Санитизация (удаление опасных символов)
- Whitelist валидация (разрешить только известные значения)
4. Защита чувствительных данных
Задача: Убедиться, что пароли, токены и ПДн не утекают
// ❌ Опасно — пароль в логах
logger.info("User login: " + username + " with password: " + password);
// ✅ Правильно
logger.info("User login: " + username);
// ❌ Опасно — plain text пароль
public boolean validatePassword(String inputPassword, String storedPassword) {
return inputPassword.equals(storedPassword);
}
// ✅ Правильно — bcrypt
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
public boolean validatePassword(String inputPassword, String hashedPassword) {
return passwordEncoder().matches(inputPassword, hashedPassword);
}
// Тест
@Test
public void testPasswordIsHashed() {
String rawPassword = "MySecurePassword123";
String hashedPassword = passwordEncoder().encode(rawPassword);
assertTrue(passwordEncoder().matches(rawPassword, hashedPassword));
assertNotEquals(rawPassword, hashedPassword);
}
Инструменты для проверки утечек:
- Сканирование логов на чувствительные данные
- Проверка .git истории (git-secrets)
- DAST сканеры для выявления утечек в HTTP ответах
- Проверка кэширования (Cache-Control headers)
5. Тестирование управления сессиями
Задача: Проверить, что сессии безопасны и не могут быть перехвачены
// Тест: Session Fixation Attack
@Test
public void testSessionRegenerationAfterLogin() {
String sessionBeforeLogin = getSessionId();
login("user", "password");
String sessionAfterLogin = getSessionId();
// Session должен измениться после аутентификации
assertNotEquals(sessionBeforeLogin, sessionAfterLogin);
}
// Конфиг защиты от session fixation
@Configuration
@EnableWebSecurity
public class SessionSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.sessionManagement()
.sessionFixationProtection(SessionFixationProtectionStrategy.MIGRATE_SESSION)
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.sessionConcurrency(c -> c.maximumSessions(1));
return http.build();
}
}
Проверяемые элементы:
- HttpOnly и Secure флаги на cookies
- Timeout сессии
- Logout удаляет сессию
- Защита от Session Fixation
- Защита от CSRF (Cross-Site Request Forgery)
6. Тестирование криптографии
Задача: Убедиться, что шифрование правильно реализовано
// ❌ Опасно — слабый алгоритм
MessageDigest md = MessageDigest.getInstance("MD5");
// ✅ Правильно
MessageDigest md = MessageDigest.getInstance("SHA-256");
// ❌ Опасно — фиксированная соль
String hash = bcrypt.hash(password, "fixedSalt");
// ✅ Правильно — случайная соль
String hash = bcrypt.hash(password); // Соль генерируется автоматически
// Тест
@Test
public void testDifferentHashesForSamePassword() {
String password = "MyPassword123";
String hash1 = passwordEncoder().encode(password);
String hash2 = passwordEncoder().encode(password);
assertNotEquals(hash1, hash2); // Разные хеши даже для одного пароля
assertTrue(passwordEncoder().matches(password, hash1));
assertTrue(passwordEncoder().matches(password, hash2));
}
Проверяемые элементы:
- Используются стандартные алгоритмы (AES-256, SHA-256, bcrypt)
- Не используются deprecated алгоритмы (DES, MD5)
- Правильная длина ключей (минимум 256 бит)
- IV (Initialization Vector) уникальный для каждого шифрования
7. Динамический анализ безопасности (DAST)
Задача: Тестирование работающего приложения на уязвимости
// OWASP ZAP через Maven
<plugin>
<groupId>org.zaproxy</groupId>
<artifactId>zaproxy-maven-plugin</artifactId>
<version>2.12.0</version>
<configuration>
<zapHomeDirectory>/path/to/zap</zapHomeDirectory>
</configuration>
</plugin>
// Или OWASP Dependency Check
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>8.4.0</version>
</plugin>
8. Тестирование управления ошибками
Задача: Ошибки не должны раскрывать внутреннюю архитектуру
// ❌ Опасно — раскрывает stack trace
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleException(Exception e) {
return ResponseEntity.status(500).body(e.toString()); // Stack trace видна!
}
// ✅ Правильно
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleException(Exception e) {
logger.error("Internal server error", e); // Log на сервере
return ResponseEntity.status(500).body(
new ErrorResponse("Internal server error", "ERR_INTERNAL")
);
}
Инструменты для Security Testing
| Инструмент | Назначение | Тип |
|---|---|---|
| OWASP ZAP | Dynamic security scanning | DAST |
| SonarQube | Code quality & security | SAST |
| Burp Suite | Web app testing | DAST |
| Checkmarx | Static analysis | SAST |
| Dependency-Check | Vulnerable dependencies | SAST |
| JUnit + Mockito | Unit security tests | Unit |
На собеседовании
Покажи понимание:
- OWASP Top 10 — основные типы уязвимостей
- Валидация входных данных — первая линия защиты
- Аутентификация и авторизация — правильная реализация
- Управление чувствительными данными — шифрование, хеширование
- Практические примеры — code examples проблем и решений
- Инструменты — какие инструменты используешь для тестирования
- Continuous Security — как интегрировать тестирование в CI/CD
Это покажет зрелый подход к разработке и понимание того, что security — это не отдельный feature, а часть каждой строки кода.