-
Notifications
You must be signed in to change notification settings - Fork 0
Create Java application with intentional vulnerabilities and CodeQL autobuild workflow #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a12aebb
fbbaa2e
518113c
18d8375
66dab75
5e73a07
a229811
37090d9
8a968b1
3b4ecf5
16c8b4f
e2a1073
a567bbd
c9d90bc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| name: "CodeQL Analysis" | ||
|
|
||
| on: | ||
| push: | ||
| branches: [ "main", "master" ] | ||
| pull_request: | ||
| branches: [ "main", "master" ] | ||
| schedule: | ||
| - cron: '15 2 * * 1' # Weekly on Mondays at 2:15 AM | ||
|
|
||
| jobs: | ||
| analyze: | ||
| name: Analyze Java Code | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| actions: read | ||
| contents: read | ||
| security-events: write | ||
|
|
||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| language: [ 'java' ] | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up JDK 11 | ||
| uses: actions/setup-java@v3 | ||
| with: | ||
| java-version: '11' | ||
| distribution: 'temurin' | ||
|
|
||
| - name: Initialize CodeQL | ||
| uses: github/codeql-action/init@v3 | ||
| with: | ||
| languages: ${{ matrix.language }} | ||
| queries: +security-and-quality | ||
| build-mode: none | ||
| dependency-caching: true | ||
|
|
||
| # Autobuild attempts to build any compiled languages (Java, C#, Go, etc.) | ||
| # If this step fails, remove it and run the build manually instead | ||
| #- name: Autobuild | ||
| # uses: github/codeql-action/autobuild@v3 | ||
|
|
||
| - name: Perform CodeQL Analysis | ||
| uses: github/codeql-action/analyze@v3 | ||
| with: | ||
| category: "/language:${{matrix.language}}" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| # Maven | ||
| target/ | ||
| pom.xml.tag | ||
| pom.xml.releaseBackup | ||
| pom.xml.versionsBackup | ||
| pom.xml.next | ||
| release.properties | ||
| dependency-reduced-pom.xml | ||
| buildNumber.properties | ||
| .mvn/timing.properties | ||
| .mvn/wrapper/maven-wrapper.jar | ||
|
|
||
| # Compiled class files | ||
| *.class | ||
|
|
||
| # Log files | ||
| *.log | ||
|
|
||
| # IDE files | ||
| .idea/ | ||
| *.iws | ||
| *.iml | ||
| *.ipr | ||
| .vscode/ | ||
| .settings/ | ||
| .project | ||
| .classpath | ||
|
|
||
| # OS generated files | ||
| .DS_Store | ||
| Thumbs.db | ||
|
|
||
| # Temporary files | ||
| *.tmp | ||
| *.bak | ||
| *.swp | ||
| *~.nib | ||
|
|
||
| # Package files | ||
| *.jar | ||
| *.war | ||
| *.nar | ||
| *.ear | ||
| *.zip | ||
| *.tar.gz | ||
| *.rar |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,56 @@ | ||
| # coding-agent-example-java-codeql-autobuild | ||
| # coding-agent-example-java-codeql-autobuild | ||
|
|
||
| A demonstration Java application with intentional security vulnerabilities for CodeQL scanning. | ||
|
|
||
| ## Overview | ||
|
|
||
| This repository contains a simple Java application built with Maven that includes several common security vulnerabilities designed to be detected by GitHub's CodeQL static analysis tool. | ||
|
|
||
| ## Application Structure | ||
|
|
||
| - **Main Application**: `com.example.app.VulnerableApplication` - Entry point that demonstrates various vulnerabilities | ||
| - **Database Layer**: `com.example.database.UserDatabase` - Contains SQL injection vulnerabilities | ||
| - **Security Utils**: `com.example.security.CryptoUtils` - Contains weak cryptographic implementations | ||
| - **Web/File Handling**: `com.example.web.FileController` - Contains path traversal and command injection vulnerabilities | ||
| - **LDAP Authentication**: `com.example.ldap.LdapAuth` - Contains LDAP injection vulnerabilities | ||
|
|
||
| ## Intentional Vulnerabilities | ||
|
|
||
| This application contains the following types of security vulnerabilities: | ||
|
|
||
| 1. **SQL Injection** - Direct string concatenation in SQL queries | ||
| 2. **Command Injection** - Unsanitized user input passed to system commands | ||
| 3. **Path Traversal** - File operations without path validation | ||
| 4. **LDAP Injection** - Unescaped user input in LDAP filters | ||
| 5. **Weak Cryptography** - Use of MD5 and weak random number generation | ||
| 6. **Hard-coded Secrets** - Embedded credentials and encryption keys | ||
|
|
||
| ## CodeQL Analysis | ||
|
|
||
| The repository includes a GitHub Actions workflow (`.github/workflows/codeql-analysis.yml`) that: | ||
|
|
||
| - Runs CodeQL analysis on push and pull requests | ||
| - Uses the autobuild functionality for Java | ||
| - Includes security-and-quality queries for comprehensive coverage | ||
| - Runs weekly scheduled scans | ||
|
|
||
| ## Building and Running | ||
|
|
||
| ```bash | ||
| # Compile the application | ||
| mvn clean compile | ||
|
|
||
| # Run tests | ||
| mvn test | ||
|
|
||
| # Run the application (demonstrates vulnerabilities) | ||
| mvn exec:java -Dexec.mainClass="com.example.app.VulnerableApplication" | ||
| ``` | ||
|
|
||
| ## Warning | ||
|
|
||
| ⚠️ **This application contains intentional security vulnerabilities and should never be deployed in a production environment.** It is designed solely for educational purposes and CodeQL demonstration. | ||
|
|
||
| ## License | ||
|
|
||
| This project is for educational and demonstration purposes only. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 | ||
| http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
|
|
||
| <groupId>com.example</groupId> | ||
| <artifactId>vulnerable-app</artifactId> | ||
| <version>1.0.0</version> | ||
| <packaging>jar</packaging> | ||
|
|
||
| <name>Vulnerable Java Application - Test2</name> | ||
| <description>A simple Java application with intentional vulnerabilities for CodeQL scanning demonstration</description> | ||
|
|
||
| <properties> | ||
| <maven.compiler.source>11</maven.compiler.source> | ||
| <maven.compiler.target>11</maven.compiler.target> | ||
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
| </properties> | ||
|
|
||
| <dependencies> | ||
| <!-- NOTE: Some dependency versions below may have known vulnerabilities. | ||
| This is intentional for demonstration purposes. In a real application, | ||
| always use the latest secure versions of dependencies. --> | ||
|
|
||
| <dependency> | ||
| <groupId>com.google.guava</groupId> | ||
| <artifactId>guava</artifactId> | ||
| <version>32.1.1-jre</version> | ||
| </dependency> | ||
|
|
||
| <dependency> | ||
| <groupId>org.slf4j</groupId> | ||
| <artifactId>slf4j-api</artifactId> | ||
| <version>2.0.7</version> | ||
| </dependency> | ||
|
|
||
| <dependency> | ||
| <groupId>org.apache.commons</groupId> | ||
| <artifactId>commons-lang3</artifactId> | ||
| <version>3.12.0</version> | ||
| </dependency> | ||
|
|
||
| <!-- Database connectivity for SQL injection demos --> | ||
| <dependency> | ||
| <groupId>mysql</groupId> | ||
| <artifactId>mysql-connector-java</artifactId> | ||
| <version>8.0.33</version> | ||
| </dependency> | ||
|
|
||
| <!-- Web framework for HTTP vulnerabilities --> | ||
| <dependency> | ||
| <groupId>org.springframework</groupId> | ||
| <artifactId>spring-web</artifactId> | ||
| <version>5.3.21</version> | ||
| </dependency> | ||
|
|
||
| <!-- JSON processing --> | ||
| <dependency> | ||
| <groupId>com.fasterxml.jackson.core</groupId> | ||
| <artifactId>jackson-databind</artifactId> | ||
| <version>2.13.3</version> | ||
| </dependency> | ||
|
|
||
| <!-- Testing --> | ||
| <dependency> | ||
| <groupId>junit</groupId> | ||
| <artifactId>junit</artifactId> | ||
| <version>4.13.2</version> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| </dependencies> | ||
|
|
||
| <build> | ||
| <plugins> | ||
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-compiler-plugin</artifactId> | ||
| <version>3.8.1</version> | ||
| <configuration> | ||
| <source>11</source> | ||
| <target>11</target> | ||
| </configuration> | ||
| </plugin> | ||
|
|
||
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-surefire-plugin</artifactId> | ||
| <version>3.0.0-M7</version> | ||
| </plugin> | ||
| </plugins> | ||
| </build> | ||
| </project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| package com.example.app; | ||
|
|
||
| import com.example.database.UserDatabase; | ||
| import com.example.security.CryptoUtils; | ||
| import com.example.web.FileController; | ||
| import com.example.ldap.LdapAuth; | ||
|
|
||
| /** | ||
| * Main application class demonstrating various Java vulnerabilities | ||
| * that should be detected by CodeQL scanning. | ||
| */ | ||
| public class VulnerableApplication { | ||
|
|
||
| public static void main(String[] args) { | ||
| System.out.println("Starting Vulnerable Application..."); | ||
|
|
||
| // Demonstrate various vulnerable components | ||
| UserDatabase userDb = new UserDatabase(); | ||
| CryptoUtils crypto = new CryptoUtils(); | ||
| FileController fileController = new FileController(); | ||
| LdapAuth ldapAuth = new LdapAuth(); | ||
|
|
||
| // Example usage that would trigger vulnerabilities | ||
| String userInput = args.length > 0 ? args[0] : "admin"; | ||
| String password = args.length > 1 ? args[1] : "password123"; | ||
|
|
||
| // SQL Injection vulnerability | ||
| userDb.authenticateUser(userInput, password); | ||
| userDb.deleteUser(userInput); | ||
|
|
||
| // Weak cryptography | ||
| String token = crypto.generateToken(); | ||
| System.out.println("Generated token: " + token); | ||
|
|
||
| // Path traversal vulnerability | ||
| String filename = args.length > 2 ? args[2] : "../../etc/passwd"; | ||
| fileController.readFile(filename); | ||
|
|
||
| // Command injection | ||
| String command = args.length > 3 ? args[3] : "ls -la"; | ||
| fileController.executeCommand(command); | ||
| fileController.executeSystemCommand(command); | ||
|
|
||
| // LDAP injection | ||
| ldapAuth.authenticateUser(userInput, password); | ||
| ldapAuth.getUserInfo(userInput); | ||
|
|
||
| System.out.println("Application completed."); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,90 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package com.example.database; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.sql.Connection; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.sql.DriverManager; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.sql.ResultSet; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.sql.Statement; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Database class with intentional SQL injection vulnerabilities | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * to demonstrate CodeQL detection capabilities. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public class UserDatabase { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String DB_URL = "jdbc:mysql://localhost:3306/testdb"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String DB_USER = "root"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static final String DB_PASSWORD = "password"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * VULNERABLE: SQL Injection vulnerability - user input directly concatenated | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * This should trigger a high/critical CodeQL alert | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public boolean authenticateUser(String username, String password) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Statement stmt = conn.createStatement(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // VULNERABILITY: Direct string concatenation leads to SQL injection | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String query = "SELECT * FROM users WHERE username = '" + username + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "' AND password = '" + password + "'"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| System.out.println("Executing query: " + query); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ResultSet rs = stmt.executeQuery(query); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| boolean authenticated = rs.next(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rs.close(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stmt.close(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| conn.close(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return authenticated; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (Exception e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| System.err.println("Database error: " + e.getMessage()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * VULNERABLE: Another SQL injection point | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void updateUserProfile(String userId, String email, String fullName) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Statement stmt = conn.createStatement(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // VULNERABILITY: String concatenation in UPDATE statement | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String updateQuery = "UPDATE users SET email = '" + email + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "', full_name = '" + fullName + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "' WHERE user_id = " + userId; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stmt.executeUpdate(updateQuery); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check failureCode scanning / CodeQL Query built by concatenation with a possibly-untrusted string High
Query built by concatenation with
this expression Error loading related location Loading Query built by concatenation with this expression Error loading related location Loading
Copilot AutofixAI 4 months ago General fix: Detailed description: What needs to be changed:
Suggested changeset
1
src/main/java/com/example/database/UserDatabase.java
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stmt.close(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| conn.close(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (Exception e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| System.err.println("Update failed: " + e.getMessage()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * VULNERABLE: Dynamic query construction - another SQL injection pattern | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public void deleteUser(String userIdParam) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Statement stmt = conn.createStatement(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // VULNERABILITY: Direct concatenation in DELETE statement | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String sql = "DELETE FROM users WHERE id = " + userIdParam; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stmt.executeUpdate(sql); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stmt.close(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| conn.close(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (Exception e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| System.err.println("Delete failed: " + e.getMessage()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check failure
Code scanning / CodeQL
Query built by concatenation with a possibly-untrusted string High
Copilot Autofix
AI 4 months ago
To fix the problem, all SQL queries using user input must be refactored to use parameterized/prepared statements rather than direct string concatenation. Specifically for the error on line 32 (and similar patterns elsewhere), the query should be changed to include
?placeholders for inputs, and then the input values set using the appropriatesetStringmethods before execution. This means changing theauthenticateUsermethod to use aPreparedStatement, constructing the query as"SELECT * FROM users WHERE username = ? AND password = ?", then setting the values for both placeholders usingsetString(1, username)andsetString(2, password)respectively. Similar changes should be made to the other methods (updateUserProfile,deleteUser) to replace concatenated statements with parameterized queries, usingPreparedStatementand passing the variables safely to the SQL engine.Changes should occur only in code snippets shown (within src/main/java/com/example/database/UserDatabase.java), and only in the affected methods. Additional required imports (for
PreparedStatement) should also be added. Functionality is preserved: the logic now runs with safe, parameterized queries.