Gymterview
middle

Что такое OWASP Top 10 и какие уязвимости наиболее актуальны для Java-разработчика?

OWASP Top 10 — регулярно обновляемый список десяти наиболее критичных уязвимостей веб-приложений, публикуемый организацией OWASP (Open Web Application Security Project). Текущая версия — 2021 года.

A01: Broken Access Control (Нарушение контроля доступа)

Пользователь получает доступ к ресурсам, которые ему не положены.

Пример
// УЯЗВИМЫЙ КОД: нет проверки владельца
@GetMapping("/api/accounts/{id}")
public Account getAccount(@PathVariable Long id) {
    return accountRepository.findById(id).orElseThrow();
}

// БЕЗОПАСНЫЙ КОД: проверка принадлежности
@GetMapping("/api/accounts/{id}")
public Account getAccount(@PathVariable Long id, Authentication auth) {
    Account account = accountRepository.findById(id).orElseThrow();
    if (!account.getOwner().equals(auth.getName())) {
        throw new AccessDeniedException("Нет доступа к чужому счёту");
    }
    return account;
}

A02: Cryptographic Failures (Криптографические ошибки)

Пример
// НЕПРАВИЛЬНО
String hashedPassword = DigestUtils.md5Hex(password); // MD5 небезопасен!

// ПРАВИЛЬНО
String hashedPassword = new BCryptPasswordEncoder(12).encode(password);

A03: Injection (Внедрение)

Пример
// УЯЗВИМЫЙ КОД
String query = "SELECT * FROM users WHERE login = '" + userInput + "'";

// БЕЗОПАСНЫЙ КОД: параметризованные запросы
@Query("SELECT u FROM User u WHERE u.login = :login")
User findByLogin(@Param("login") String login);

A04: Insecure Design (Небезопасный дизайн)

Отсутствие лимитов на операции, недостаточная валидация бизнес-логики.

Пример
// НЕБЕЗОПАСНО: нет лимита на перебор кодов подтверждения
@PostMapping("/api/confirm-transfer")
public void confirm(@RequestBody ConfirmRequest request) {
    if (request.getCode().equals(expectedCode)) { ... }
}

// БЕЗОПАСНО: ограничение попыток
@PostMapping("/api/confirm-transfer")
public void confirm(@RequestBody ConfirmRequest request) {
    if (attemptCounter.incrementAndGet(request.getTransferId()) > 3) {
        throw new TooManyAttemptsException("Превышен лимит попыток");
    }
    // ...
}

A05: Security Misconfiguration (Неправильная настройка безопасности)

Пример
# НЕПРАВИЛЬНО: стандартные настройки в production
management:
  endpoints:
    web:
      exposure:
        include: "*"    # Все actuator-эндпоинты открыты!

# ПРАВИЛЬНО
management:
  endpoints:
    web:
      exposure:
        include: health,info,prometheus

A07: Cross-Site Scripting (XSS)

Пример
// УЯЗВИМО: th:utext не экранирует HTML
// <p th:utext="${name}"></p>

// БЕЗОПАСНО: th:text экранирует HTML
// <p th:text="${name}"></p>

A08: Cross-Site Request Forgery (CSRF)

Пример
// Spring Security: CSRF включён по умолчанию
http.csrf(csrf -> csrf
    .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
);
// Для REST API с JWT — CSRF можно отключить

A10: Server-Side Request Forgery (SSRF)

Пример
// УЯЗВИМО: пользователь указывает URL
@GetMapping("/api/fetch")
public String fetch(@RequestParam String url) {
    return restTemplate.getForObject(url, String.class);
}

// БЕЗОПАСНО: белый список доменов
private static final Set<String> ALLOWED_HOSTS = Set.of("api.cbr.ru");

@GetMapping("/api/fetch")
public String fetch(@RequestParam String url) {
    URI uri = URI.create(url);
    if (!ALLOWED_HOSTS.contains(uri.getHost())) {
        throw new SecurityException("Запрещённый хост");
    }
    return restTemplate.getForObject(url, String.class);
}

Знание OWASP Top 10 — обязательное требование. Код проходит security review и статический анализ (SonarQube, Checkmarx) перед выходом в production.

На собеседовании: интервьюер хочет услышать не просто перечисление категорий, а конкретные примеры уязвимого и исправленного кода на Java. Частая ошибка — не знать SSRF и Security Misconfiguration (часто спрашивают про открытые Actuator-эндпоинты).