Безопасность Java приложений: топ-10 уязвимостей для начинающих

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Безопасность Java приложений: топ-10 уязвимостей для начинающих

Java остаётся одним из самых популярных языков для создания корпоративных и веб-приложений. Однако даже надёжная платформа не гарантирует безопасность кода. По данным OWASP, большинство взломов происходят из-за ошибок разработчиков, а не из-за уязвимостей в JVM. В этой статье мы разберём топ-10 уязвимостей Java-приложений, которые должен знать каждый начинающий разработчик. Вы получите не только теоретические знания, но и практические примеры кода с объяснением, как избежать опасных ошибок.

1. SQL-инъекции (SQL Injection)

Самая распространённая угроза. Злоумышленник может выполнить произвольный SQL-запрос, если вы конкатенируете строки напрямую.

Плохой пример (уязвимый код):

String query = "SELECT * FROM users WHERE username = '" + userName + "' AND pass = '" + password + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);

Решение: используйте PreparedStatement с параметризованными запросами.

String query = "SELECT * FROM users WHERE username = ? AND pass = ?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, userName);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();

2. Межсайтовый скриптинг (XSS)

Если вы выводите пользовательские данные в HTML без экранирования, злоумышленник может внедрить JavaScript-код.

Уязвимый код (JSP):

<%= request.getParameter("message") %>

Защита: экранируйте вывод с помощью библиотек (например, OWASP Java Encoder) или используйте шаблонизаторы с автоэкранированием (Thymeleaf, JSP с JSTL).

<c:out value="${message}" />

3. Небезопасная десериализация

Java-десериализация может привести к удалённому выполнению кода (RCE), если злоумышленник передаёт специально сформированный поток байтов.

Плохая практика:

ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Object obj = ois.readObject(); // что угодно может быть восстановлено

Рекомендации:

  • Никогда не десериализуйте данные из ненадёжных источников.
  • Используйте белые списки классов (look-ahead object input stream).
  • Рассмотрите альтернативы (JSON, Protobuf).

4. Внедрение команд ОС (Command Injection)

Если ваше приложение вызывает системные команды с пользовательскими данными, возможна инъекция.

Опасный код:

Runtime.getRuntime().exec("ping " + userInput); // userInput = 127.0.0.1; rm -rf /

Защита: избегайте вызова shell-команд, используйте встроенные Java-библиотеки. Если вызов неизбежен — валидируйте входные данные строгим белым списком.

5. Недостатки аутентификации и управления сессиями

Слабая сессионная защита — частая проблема. Например, использование предсказуемых идентификаторов сессий или хранение паролей в открытом виде.

  • Генерируйте сессионные ID с помощью SecureRandom.
  • Используйте современные хеши (bcrypt, scrypt, Argon2) для паролей.
  • Устанавливайте тайм-ауты сессий и флаги HttpOnly/Secure для cookies.

6. Небезопасная конфигурация (Security Misconfiguration)

Оставленные debug-режимы, стандартные пароли, открытые порты — всё это даёт злоумышленнику информацию о системе.

Что проверить в Spring Boot:

  • Отключите Actuator endpoints в продакшене или защитите их.
  • Не используйте spring.jpa.show-sql=true в production.
  • Удалите стандартные заголовки сервера.

7. XML External Entities (XXE)

Если вы парсите XML-документы, злоумышленник может внедрить внешнюю сущность, которая прочитает файлы на сервере или вызовет DoS.

Уязвимый парсер:

DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.parse(inputStream); // XXE возможна

Защита: отключите внешние сущности и DTD:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);

8. Утечка конфиденциальных данных в логах

Логирование паролей, токенов или кредитных карт — грубая ошибка.

Пример ошибки:

log.info("User login: " + username + " password: " + password);

Решение: никогда не логируйте секреты. Используйте маскирование или фильтры в Logback/Log4j.

9. Недостаточная проверка доступа (Broken Access Control)

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

Уязвимость: если в запросе передаётся userId=123, а сервер не проверяет, что текущий пользователь — владелец этого ID.

Исправление: всегда проверяйте, что аутентифицированный пользователь имеет право на запрашиваемый ресурс (например, через Spring Security @PreAuthorize).

10. Использование компонентов с известными уязвимостями

Библиотеки с уязвимостями (Log4Shell, старые версии Jackson) — прямой путь к компрометации.

Блоги

Рекомендаций по книгам