diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 0000000..6c0df92
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -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}}"
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7974262
--- /dev/null
+++ b/.gitignore
@@ -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
\ No newline at end of file
diff --git a/README.md b/README.md
index 3b81e20..ee621d5 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,56 @@
-# coding-agent-example-java-codeql-autobuild
\ No newline at end of file
+# 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.
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..8dd88b8
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,94 @@
+
+
+ 4.0.0
+
+ com.example
+ vulnerable-app
+ 1.0.0
+ jar
+
+ Vulnerable Java Application - Test2
+ A simple Java application with intentional vulnerabilities for CodeQL scanning demonstration
+
+
+ 11
+ 11
+ UTF-8
+
+
+
+
+
+
+ com.google.guava
+ guava
+ 32.1.1-jre
+
+
+
+ org.slf4j
+ slf4j-api
+ 2.0.7
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.12.0
+
+
+
+
+ mysql
+ mysql-connector-java
+ 8.0.33
+
+
+
+
+ org.springframework
+ spring-web
+ 5.3.21
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.13.3
+
+
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 11
+ 11
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M7
+
+
+
+
diff --git a/src/main/java/com/example/app/VulnerableApplication.java b/src/main/java/com/example/app/VulnerableApplication.java
new file mode 100644
index 0000000..f2570d0
--- /dev/null
+++ b/src/main/java/com/example/app/VulnerableApplication.java
@@ -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.");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/database/UserDatabase.java b/src/main/java/com/example/database/UserDatabase.java
new file mode 100644
index 0000000..a111788
--- /dev/null
+++ b/src/main/java/com/example/database/UserDatabase.java
@@ -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);
+
+ 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());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/ldap/LdapAuth.java b/src/main/java/com/example/ldap/LdapAuth.java
new file mode 100644
index 0000000..1acfa4d
--- /dev/null
+++ b/src/main/java/com/example/ldap/LdapAuth.java
@@ -0,0 +1,82 @@
+package com.example.ldap;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingEnumeration;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchResult;
+import java.util.Hashtable;
+
+/**
+ * LDAP authentication with intentional LDAP injection vulnerability
+ * to demonstrate CodeQL detection capabilities.
+ */
+public class LdapAuth {
+
+ private static final String LDAP_URL = "ldap://localhost:389";
+ private static final String BASE_DN = "dc=example,dc=com";
+
+ /**
+ * VULNERABLE: LDAP injection vulnerability - user input directly concatenated
+ * This should trigger a high/critical CodeQL alert
+ */
+ public boolean authenticateUser(String username, String password) {
+ try {
+ Hashtable env = new Hashtable<>();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.PROVIDER_URL, LDAP_URL);
+
+ DirContext ctx = new InitialDirContext(env);
+
+ // VULNERABILITY: Direct concatenation allows LDAP injection
+ String filter = "(&(uid=" + username + ")(userPassword=" + password + "))";
+
+ System.out.println("LDAP filter: " + filter);
+
+ NamingEnumeration results = ctx.search(BASE_DN, filter, null);
+ boolean authenticated = results.hasMore();
+
+ results.close();
+ ctx.close();
+
+ return authenticated;
+
+ } catch (Exception e) {
+ System.err.println("LDAP authentication failed: " + e.getMessage());
+ return false;
+ }
+ }
+
+ /**
+ * VULNERABLE: Another LDAP injection pattern
+ */
+ public String getUserInfo(String userId) {
+ try {
+ Hashtable env = new Hashtable<>();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.PROVIDER_URL, LDAP_URL);
+
+ DirContext ctx = new InitialDirContext(env);
+
+ // VULNERABILITY: LDAP injection in search filter
+ String searchFilter = "(uid=" + userId + ")";
+ NamingEnumeration results = ctx.search(BASE_DN, searchFilter, null);
+
+ if (results.hasMore()) {
+ SearchResult result = results.next();
+ Attributes attrs = result.getAttributes();
+ return attrs.toString();
+ }
+
+ results.close();
+ ctx.close();
+
+ } catch (Exception e) {
+ System.err.println("LDAP search failed: " + e.getMessage());
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/security/CryptoUtils.java b/src/main/java/com/example/security/CryptoUtils.java
new file mode 100644
index 0000000..1bbdc04
--- /dev/null
+++ b/src/main/java/com/example/security/CryptoUtils.java
@@ -0,0 +1,77 @@
+package com.example.security;
+
+import java.util.Random;
+import java.security.MessageDigest;
+
+/**
+ * Security utilities with intentional cryptographic vulnerabilities
+ * to demonstrate CodeQL detection capabilities.
+ */
+public class CryptoUtils {
+
+ // VULNERABLE: Using weak random number generator
+ private static final Random random = new Random();
+
+ /**
+ * VULNERABLE: Uses weak random number generation for security tokens
+ * This should trigger a CodeQL alert for insecure randomness
+ */
+ public String generateToken() {
+ StringBuilder token = new StringBuilder();
+
+ // VULNERABILITY: Using java.util.Random for security-sensitive operations
+ for (int i = 0; i < 32; i++) {
+ int randomChar = random.nextInt(36);
+ if (randomChar < 10) {
+ token.append((char) ('0' + randomChar));
+ } else {
+ token.append((char) ('a' + randomChar - 10));
+ }
+ }
+
+ return token.toString();
+ }
+
+ /**
+ * VULNERABLE: Uses weak random for session IDs
+ */
+ public String generateSessionId() {
+ // VULNERABILITY: Predictable session ID generation
+ long sessionId = System.currentTimeMillis() + random.nextInt(1000);
+ return Long.toString(sessionId);
+ }
+
+ /**
+ * VULNERABLE: Weak hash function usage
+ */
+ public String hashPassword(String password) {
+ try {
+ // VULNERABILITY: Using MD5 for password hashing (weak algorithm)
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ byte[] hash = md.digest(password.getBytes());
+
+ StringBuilder hexString = new StringBuilder();
+ for (byte b : hash) {
+ String hex = Integer.toHexString(0xff & b);
+ if (hex.length() == 1) {
+ hexString.append('0');
+ }
+ hexString.append(hex);
+ }
+
+ return hexString.toString();
+
+ } catch (Exception e) {
+ System.err.println("Hashing failed: " + e.getMessage());
+ return password; // VULNERABILITY: Fallback to plaintext
+ }
+ }
+
+ /**
+ * VULNERABLE: Hard-coded encryption key
+ */
+ public String getEncryptionKey() {
+ // VULNERABILITY: Hard-coded secret key
+ return "MySecretKey123456789";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/web/FileController.java b/src/main/java/com/example/web/FileController.java
new file mode 100644
index 0000000..23853f4
--- /dev/null
+++ b/src/main/java/com/example/web/FileController.java
@@ -0,0 +1,122 @@
+package com.example.web;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.FileWriter;
+
+/**
+ * File controller with intentional path traversal vulnerabilities
+ * to demonstrate CodeQL detection capabilities.
+ */
+public class FileController {
+
+ private static final String BASE_DIR = "/tmp/uploads/";
+
+ /**
+ * VULNERABLE: Path traversal vulnerability - no input validation
+ * This should trigger a high/critical CodeQL alert
+ */
+ public String readFile(String filename) {
+ try {
+ // VULNERABILITY: Direct concatenation allows path traversal attacks
+ File file = new File(BASE_DIR + filename);
+
+ System.out.println("Reading file: " + file.getAbsolutePath());
+
+ if (!file.exists()) {
+ System.out.println("File does not exist: " + filename);
+ return null;
+ }
+
+ StringBuilder content = new StringBuilder();
+ try (BufferedReader reader = new BufferedReader(
+ new InputStreamReader(new FileInputStream(file)))) {
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ content.append(line).append("\n");
+ }
+ }
+
+ return content.toString();
+
+ } catch (Exception e) {
+ System.err.println("Error reading file: " + e.getMessage());
+ return null;
+ }
+ }
+
+ /**
+ * VULNERABLE: Another path traversal vulnerability in file writing
+ */
+ public boolean writeFile(String filename, String content) {
+ try {
+ // VULNERABILITY: No validation on filename parameter
+ File file = new File(BASE_DIR + filename);
+
+ // Create parent directories if they don't exist
+ file.getParentFile().mkdirs();
+
+ try (FileWriter writer = new FileWriter(file)) {
+ writer.write(content);
+ }
+
+ System.out.println("File written: " + file.getAbsolutePath());
+ return true;
+
+ } catch (Exception e) {
+ System.err.println("Error writing file: " + e.getMessage());
+ return false;
+ }
+ }
+
+ /**
+ * VULNERABLE: Command injection vulnerability
+ */
+ public String executeCommand(String userCommand) {
+ try {
+ // VULNERABILITY: Direct execution of user input
+ Process process = Runtime.getRuntime().exec("sh -c " + userCommand);
+
+ StringBuilder output = new StringBuilder();
+ try (BufferedReader reader = new BufferedReader(
+ new InputStreamReader(process.getInputStream()))) {
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ output.append(line).append("\n");
+ }
+ }
+
+ return output.toString();
+
+ } catch (Exception e) {
+ System.err.println("Command execution failed: " + e.getMessage());
+ return null;
+ }
+ }
+
+ /**
+ * VULNERABLE: Another command injection pattern using ProcessBuilder
+ */
+ public String executeSystemCommand(String cmd) {
+ try {
+ // VULNERABILITY: ProcessBuilder with unsanitized input
+ ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", cmd);
+ Process process = pb.start();
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ StringBuilder result = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ result.append(line).append("\n");
+ }
+
+ return result.toString();
+ } catch (Exception e) {
+ return "Error: " + e.getMessage();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/example/VulnerableApplicationTest.java b/src/test/java/com/example/VulnerableApplicationTest.java
new file mode 100644
index 0000000..86750ac
--- /dev/null
+++ b/src/test/java/com/example/VulnerableApplicationTest.java
@@ -0,0 +1,44 @@
+package com.example;
+
+import com.example.app.VulnerableApplication;
+import com.example.database.UserDatabase;
+import com.example.security.CryptoUtils;
+import com.example.web.FileController;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * Basic tests to verify the application compiles and runs
+ */
+public class VulnerableApplicationTest {
+
+ @Test
+ public void testUserDatabaseCreation() {
+ UserDatabase db = new UserDatabase();
+ assertNotNull("UserDatabase should be created", db);
+ }
+
+ @Test
+ public void testCryptoUtilsCreation() {
+ CryptoUtils crypto = new CryptoUtils();
+ assertNotNull("CryptoUtils should be created", crypto);
+
+ String token = crypto.generateToken();
+ assertNotNull("Token should be generated", token);
+ assertTrue("Token should have length", token.length() > 0);
+ }
+
+ @Test
+ public void testFileControllerCreation() {
+ FileController controller = new FileController();
+ assertNotNull("FileController should be created", controller);
+ }
+
+ @Test
+ public void testHashPasswordReturnsValue() {
+ CryptoUtils crypto = new CryptoUtils();
+ String hash = crypto.hashPassword("testpassword");
+ assertNotNull("Hash should not be null", hash);
+ assertTrue("Hash should have content", hash.length() > 0);
+ }
+}
\ No newline at end of file