Skip to content

Conversation

@sylvain-combe-sonarsource
Copy link
Contributor

Description

This PR adds a new contact feedback form feature to the demo project, demonstrating how static analysis can identify security vulnerabilities.

Changes

  • Added ContactFeedbackServlet.java - Servlet handling feedback submissions and searches
  • Added ContactFeedbackUtil.java - Utility class with database operations
  • Added contact-feedback.jsp - User-facing feedback form with search functionality
  • Added ContactFeedbackUtilTest.java - Test coverage for the utility class

Security Issues (Intentional)

This feature intentionally includes the following security vulnerabilities for demonstration purposes:

  • SQL Injection: String concatenation in SQL queries
  • Cross-Site Scripting (XSS): Unescaped user input in HTML output
  • Weak Random Number Generation: Using java.util.Random for generating IDs
  • Path Traversal: Unvalidated file path in readFeedbackFile() method

Build Status

✅ All tests pass (19 tests)
✅ Clean build with mvn clean verify
✅ Java 17 compatible

- Add ContactFeedbackServlet with XSS vulnerabilities in HTML output
- Add ContactFeedbackUtil with SQL injection vulnerabilities
- Add contact-feedback.jsp form for user input
- Add ContactFeedbackUtilTest for basic test coverage
- Includes intentional security issues: SQL injection, XSS, weak random generation, path traversal

public ContactFeedbackUtil() throws SQLException {
connection = DriverManager.getConnection(
"myJDBCUrl", "myJDBCUser", "myJDBCPass");

Check failure

Code scanning / SonarQube

Credentials should not be hard-coded Critical

Revoke and change this password, as it is compromised. See more on SonarQube
- Add ContactFeedbackException for proper exception handling
- Add constants for string literals (fix S1192)
- Use try-with-resources for proper resource management (fix S2095)
- Reuse Random instance (fix S2119)
- Make base path configurable via system property (fix S1075)
- Add DOCTYPE and lang attribute to HTML (fix Web:DoctypePresenceCheck, Web:S5254)

Security vulnerabilities intentionally preserved:
- SQL injection (javasecurity:S3649) in all query methods
- Hardcoded database password (java:S6437)
- Weak random number generation for ID generation
- Path traversal vulnerability in readFeedbackFile()
+ category + "')";

try (Statement statement = connection.createStatement()) {
statement.executeUpdate(query);

Check failure

Code scanning / SonarQube

Database queries should not be vulnerable to injection attacks Critical

Change this code to not construct SQL queries directly from user-controlled data. See more on SonarQube
String query = "SELECT id, name, email, feedback, category FROM feedback WHERE email = '" + email + "'";

try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query)) {

Check failure

Code scanning / SonarQube

Database queries should not be vulnerable to injection attacks Critical

Change this code to not construct SQL queries directly from user-controlled data. See more on SonarQube
String query = "SELECT id, name, email, feedback, category FROM feedback WHERE category = '" + category + "'";

try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query)) {

Check failure

Code scanning / SonarQube

Database queries should not be vulnerable to injection attacks Critical

Change this code to not construct SQL queries directly from user-controlled data. See more on SonarQube
…nization

- Extract helper methods for utility creation, feedback retrieval, and rendering
- Add proper exception handling for SQLException in method signatures
- Extract renderFeedbackItems method to avoid code duplication
- Add HTML constants for better maintainability

Security vulnerabilities intentionally preserved:
- SQL injection in getFeedbackByEmail, getFeedbackByCategory, storeFeedback
- XSS vulnerabilities in HTML output (unescaped user input)
- Hardcoded database credentials
- Split exception handling into separate methods to avoid nested try-catch warnings
- Move SQLException catching to createUtil() method
- Add individual exception handling methods for each operation
- Remove multi-catch blocks that triggered S1989 warnings

Result: Only security-related issues remain (SQL injection and hardcoded password)

Security vulnerabilities intentionally preserved:
- SQL injection in database queries
- XSS vulnerabilities in HTML output
- Hardcoded database credentials
String feedback = request.getParameter(FIELD_FEEDBACK);
String category = request.getParameter(FIELD_CATEGORY);

ContactFeedbackUtil util = createUtil();

Check notice

Code scanning / SonarQube

Exceptions should not be thrown from servlet methods Low

Handle the following exception that could be thrown by "createUtil": ServletException. See more on SonarQube
ContactFeedbackUtil util = createUtil();

// Store feedback with SQL injection vulnerability
String feedbackId = storeFeedback(util, name, email, feedback, category);

Check notice

Code scanning / SonarQube

Exceptions should not be thrown from servlet methods Low

Handle the following exception that could be thrown by "storeFeedback": ServletException. See more on SonarQube
String feedbackId = storeFeedback(util, name, email, feedback, category);

// Retrieve and display feedback
List<Map<String, String>> feedbackList = getFeedbackByEmail(util, email);

Check notice

Code scanning / SonarQube

Exceptions should not be thrown from servlet methods Low

Handle the following exception that could be thrown by "getFeedbackByEmail": ServletException. See more on SonarQube
// Retrieve and display feedback
List<Map<String, String>> feedbackList = getFeedbackByEmail(util, email);

renderFeedbackSubmissionResponse(response, feedbackId, feedbackList);

Check notice

Code scanning / SonarQube

Exceptions should not be thrown from servlet methods Low

Handle the following exception that could be thrown by "renderFeedbackSubmissionResponse": IOException. See more on SonarQube
String searchEmail = request.getParameter(FIELD_EMAIL);
String searchCategory = request.getParameter(FIELD_CATEGORY);

ContactFeedbackUtil util = createUtil();

Check notice

Code scanning / SonarQube

Exceptions should not be thrown from servlet methods Low

Handle the following exception that could be thrown by "createUtil": ServletException. See more on SonarQube
String searchCategory = request.getParameter(FIELD_CATEGORY);

ContactFeedbackUtil util = createUtil();
List<Map<String, String>> feedbackList = getFeedbackList(util, searchEmail, searchCategory);

Check notice

Code scanning / SonarQube

Exceptions should not be thrown from servlet methods Low

Handle the following exception that could be thrown by "getFeedbackList": ServletException. See more on SonarQube
ContactFeedbackUtil util = createUtil();
List<Map<String, String>> feedbackList = getFeedbackList(util, searchEmail, searchCategory);

renderFeedbackSearchResponse(response, feedbackList);

Check notice

Code scanning / SonarQube

Exceptions should not be thrown from servlet methods Low

Handle the following exception that could be thrown by "renderFeedbackSearchResponse": IOException. See more on SonarQube
@sonar-nautilus
Copy link

Quality Gate failed Quality Gate failed

Failed conditions
11 New issues
4 Security Hotspots
0.0% Coverage on New Code (required ≥ 80%)
11.5% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE SonarQube for IDE

@sylvain-combe-sonarsource sylvain-combe-sonarsource deleted the feature/contact-feedback-form-lint branch November 26, 2025 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants