Add Contact Feedback Form with CAPTCHA and Security Vulnerabilities#73
Add Contact Feedback Form with CAPTCHA and Security Vulnerabilities#73sylvain-combe-sonarsource wants to merge 1 commit intomainfrom
Conversation
- Implement ContactFeedbackServlet with multiple security flows: * SQL injection vulnerability in feedback storage * XSS vulnerability in reflected user input * Deserialization vulnerability with Session-Auth header * Information disclosure via stack trace exposure * Weak CAPTCHA validation (case-sensitive, no timing-safe comparison) - Add CaptchaServlet using obsolete Kaptcha 2.3.2 library (with CVEs) - Create contact-feedback.jsp with modern UI and optional CAPTCHA - Create captcha.jsp test page - Add saveFeedback method to DBUtils with SQL injection vulnerability - Update buildspec.yml to run on feature branches - Update GitHub Actions workflow to run on feature/** branches - Use Java 17 as specified
|
|
||
| // XSS vulnerability - reflected output without sanitization | ||
| out.print("<html><body>"); | ||
| out.print("<h2>Thank you for your feedback, " + name + "!</h2>"); |
Check failure
Code scanning / SonarQube
Endpoints should not be vulnerable to reflected cross-site scripting (XSS) attacks
| // XSS vulnerability - reflected output without sanitization | ||
| out.print("<html><body>"); | ||
| out.print("<h2>Thank you for your feedback, " + name + "!</h2>"); | ||
| out.print("<p>We received your message about: " + subject + "</p>"); |
Check failure
Code scanning / SonarQube
Endpoints should not be vulnerable to reflected cross-site scripting (XSS) attacks
| out.print("<html><body>"); | ||
| out.print("<h2>Thank you for your feedback, " + name + "!</h2>"); | ||
| out.print("<p>We received your message about: " + subject + "</p>"); | ||
| out.print("<p>Your message: " + message + "</p>"); |
Check failure
Code scanning / SonarQube
Endpoints should not be vulnerable to reflected cross-site scripting (XSS) attacks
| try { | ||
| byte[] decoded = Base64.decodeBase64(sessionAuth); | ||
| ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(decoded)); | ||
| return (SessionHeader) in.readObject(); |
Check failure
Code scanning / SonarQube
Deserialization should not be vulnerable to injection attacks
| String query = "INSERT INTO feedback (name, email, subject, message) VALUES ('" | ||
| + name + "', '" + email + "', '" + subject + "', '" + message + "')"; | ||
| Statement statement = connection.createStatement(); | ||
| statement.executeUpdate(query); |
Check failure
Code scanning / SonarQube
Database queries should not be vulnerable to injection attacks
| byte[] captchaBytes = outputStream.toByteArray(); | ||
|
|
||
| ServletOutputStream servletOutputStream = response.getOutputStream(); | ||
| servletOutputStream.write(captchaBytes); |
Check notice
Code scanning / SonarQube
Exceptions should not be thrown from servlet methods
|
|
||
| ServletOutputStream servletOutputStream = response.getOutputStream(); | ||
| servletOutputStream.write(captchaBytes); | ||
| servletOutputStream.flush(); |
Check notice
Code scanning / SonarQube
Exceptions should not be thrown from servlet methods
| ServletOutputStream servletOutputStream = response.getOutputStream(); | ||
| servletOutputStream.write(captchaBytes); | ||
| servletOutputStream.flush(); | ||
| servletOutputStream.close(); |
Check notice
Code scanning / SonarQube
Exceptions should not be thrown from servlet methods
|
|
||
| @Override | ||
| protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { | ||
| request.getRequestDispatcher("/contact-feedback.jsp").forward(request, response); |
Check notice
Code scanning / SonarQube
Exceptions should not be thrown from servlet methods
| String expectedCaptcha = (String) session.getAttribute("KAPTCHA_SESSION_KEY"); | ||
|
|
||
| response.setContentType("text/html"); | ||
| PrintWriter out = response.getWriter(); |
Check notice
Code scanning / SonarQube
Exceptions should not be thrown from servlet methods
|
|
|
||
| // XSS vulnerability - reflected output without sanitization | ||
| out.print("<html><body>"); | ||
| out.print("<h2>Thank you for your feedback, " + name + "!</h2>"); |
Check failure
Code scanning / SonarQube
Endpoints should not be vulnerable to reflected cross-site scripting (XSS) attacks Critical
| // XSS vulnerability - reflected output without sanitization | ||
| out.print("<html><body>"); | ||
| out.print("<h2>Thank you for your feedback, " + name + "!</h2>"); | ||
| out.print("<p>We received your message about: " + subject + "</p>"); |
Check failure
Code scanning / SonarQube
Endpoints should not be vulnerable to reflected cross-site scripting (XSS) attacks Critical
| out.print("<html><body>"); | ||
| out.print("<h2>Thank you for your feedback, " + name + "!</h2>"); | ||
| out.print("<p>We received your message about: " + subject + "</p>"); | ||
| out.print("<p>Your message: " + message + "</p>"); |
Check failure
Code scanning / SonarQube
Endpoints should not be vulnerable to reflected cross-site scripting (XSS) attacks Critical
| try { | ||
| byte[] decoded = Base64.decodeBase64(sessionAuth); | ||
| ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(decoded)); | ||
| return (SessionHeader) in.readObject(); |
Check failure
Code scanning / SonarQube
Deserialization should not be vulnerable to injection attacks Critical
| String query = "INSERT INTO feedback (name, email, subject, message) VALUES ('" | ||
| + name + "', '" + email + "', '" + subject + "', '" + message + "')"; | ||
| Statement statement = connection.createStatement(); | ||
| statement.executeUpdate(query); |
Check failure
Code scanning / SonarQube
Database queries should not be vulnerable to injection attacks Critical
| byte[] captchaBytes = outputStream.toByteArray(); | ||
|
|
||
| ServletOutputStream servletOutputStream = response.getOutputStream(); | ||
| servletOutputStream.write(captchaBytes); |
Check notice
Code scanning / SonarQube
Exceptions should not be thrown from servlet methods Low
|
|
||
| ServletOutputStream servletOutputStream = response.getOutputStream(); | ||
| servletOutputStream.write(captchaBytes); | ||
| servletOutputStream.flush(); |
Check notice
Code scanning / SonarQube
Exceptions should not be thrown from servlet methods Low
| ServletOutputStream servletOutputStream = response.getOutputStream(); | ||
| servletOutputStream.write(captchaBytes); | ||
| servletOutputStream.flush(); | ||
| servletOutputStream.close(); |
Check notice
Code scanning / SonarQube
Exceptions should not be thrown from servlet methods Low
|
|
||
| @Override | ||
| protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { | ||
| request.getRequestDispatcher("/contact-feedback.jsp").forward(request, response); |
Check notice
Code scanning / SonarQube
Exceptions should not be thrown from servlet methods Low
| String expectedCaptcha = (String) session.getAttribute("KAPTCHA_SESSION_KEY"); | ||
|
|
||
| response.setContentType("text/html"); | ||
| PrintWriter out = response.getWriter(); |
Check notice
Code scanning / SonarQube
Exceptions should not be thrown from servlet methods Low




Overview
This PR implements a new contact feedback form feature that demonstrates various security vulnerabilities for educational purposes.
Changes Made
New Features
Security Vulnerabilities Demonstrated
Dependencies
CI/CD Updates
buildspec.ymlto run on feature branches.github/workflows/maven.yml) to run on allfeature/**branchesBuild Status
✅ All tests pass
✅
mvn clean verifysucceedsJava Version
Implemented using Java 17 as specified
Testing
The feature can be tested by:
/contactFeedback