google-site-verification: google61fe8ba583a51912.html
GitHub Code Scanning in Java: Complete Guide

Introduction to GitHub Code Scanning

GitHub Code Scanning is a GitHub Advanced Security feature that helps identify security vulnerabilities and coding errors in your Java codebase. It uses CodeQL (GitHub's semantic code analysis engine) and third-party tools to analyze your code and detect potential issues.


System Architecture Overview

GitHub Code Scanning Pipeline ├── Trigger Events │ ├ - Push to main/develop │ ├ - Pull Requests │ ├ - Schedule (daily/weekly) │ └ - Manual Trigger ├── Analysis Tools │ ├ - CodeQL Analysis │ ├ - Third-party Scanners │ ├ - Custom Queries │ └ - Security Patterns ├── Scanning Process │ ├ - Code Extraction │ ├ - Database Creation │ ├ - Query Execution │ └ - Results Processing └── Results & Integration ├ - Security Alerts ├ - PR Comments ├ - SARIF Reports └ - Security Dashboard

Core Implementation

1. GitHub Actions Workflow Configuration

codeql-analysis.yml

name: "CodeQL Advanced Security" on: push: branches: [ "main", "develop" ] pull_request: branches: [ "main", "develop" ] schedule: - cron: '30 1 * * 0' # Weekly on Sunday at 1:30 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' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 # Full history for better analysis - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} queries: security-and-quality, security-extended config-file: ./.github/codeql/codeql-config.yml - name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' cache: 'maven' - name: Build with Maven (Autobuild) run: | mvn clean compile -DskipTests # Build the code to enable CodeQL to analyze it - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" output: codeql-results.sarif upload-database: true - name: Upload SARIF results uses: github/codeql-action/upload-sarif@v3 if: always() with: sarif_file: codeql-results.sarif wait-for-processing: true

advanced-security-scan.yml

name: "Advanced Security Scanning" on: push: branches: [ "main", "develop", "security/**" ] pull_request: branches: [ "main", "develop" ] workflow_dispatch: # Manual trigger jobs: security-scan: name: Comprehensive Security Scan runs-on: ubuntu-latest permissions: security-events: write actions: read contents: read steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' cache: 'maven' # CodeQL Analysis - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: java queries: +security-and-quality, security-extended, ../codeql-queries/java/ql/src/Security/CWE config-file: ./.github/codeql/codeql-config.yml - name: Build project run: mvn clean compile -DskipTests -DskipITs - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: category: "java-security" # Dependency Vulnerability Scanning - name: Run OWASP Dependency Check run: | mvn org.owasp:dependency-check-maven:check -DskipTests continue-on-error: true # Don't fail build on vulnerabilities - name: Upload Dependency Check Report uses: actions/upload-artifact@v4 with: name: dependency-check-report path: target/dependency-check-report.html retention-days: 30 # SpotBugs Security Analysis - name: Run SpotBugs Security Analysis run: | mvn com.github.spotbugs:spotbugs-maven-plugin:spotbugs -Dspotbugs.includeTests=false continue-on-error: true - name: Upload SpotBugs Report uses: actions/upload-artifact@v4 with: name: spotbugs-report path: target/spotbugs.xml retention-days: 30 # PMD Security Analysis - name: Run PMD Security Analysis run: | mvn pmd:pmd -Dpmd.includeTests=false continue-on-error: true - name: Upload PMD Report uses: actions/upload-artifact@v4 with: name: pmd-report path: target/pmd.xml retention-days: 30 # Custom Security Tools - name: Run Semgrep Security Scan uses: returntocorp/semgrep-action@v1 with: config: p/java-security output: semgrep-results.sarif - name: Upload Semgrep Results uses: github/codeql-action/upload-sarif@v3 with: sarif_file: semgrep-results.sarif

2. CodeQL Configuration

codeql-config.yml

# .github/codeql/codeql-config.yml name: "Custom Java Security Configuration" paths: - src/main/java - src/main/resources paths-ignore: - src/test - src/main/resources/static - target - .github - .mvn - '**/generated/**' - '**/test/**' queries: - uses: security-and-quality - uses: security-extended - name: custom-java-security-queries uses: ./.github/codeql/custom-queries - name: find-sql-injections uses: ./.github/codeql/java-sql-queries query-filters: - exclude: id: java/example/too-many-loops # Example of excluding specific queries packs: - codeql/java-queries libraries: - maven build-mode: automatic disable-default-queries: false query-timeout: 500 memory: 6144 threads: 0

Custom CodeQL Queries

// .github/codeql/custom-queries/java-security.ql import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.security.QueryInjection /** * @name Potential SQL injection with JDBCTemplate * @description Detects potential SQL injection vulnerabilities when using Spring JDBCTemplate * @kind path-problem * @problem.severity warning * @security-severity 8.5 * @precision medium * @id java/sql-injection-jdbctemplate * @tags security * external/cwe/cwe-089 */ module JDBCTemplateInjection implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { exists(MethodAccess ma | ma.getMethod().hasName("query") and ma.getMethod().getDeclaringType().hasQualifiedName("org.springframework.jdbc.core", "JdbcTemplate") and source.asExpr() = ma.getArgument(0) ) } predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma | ma.getMethod().hasName("execute") and ma.getMethod().getDeclaringType().hasQualifiedName("java.sql", "Statement") and sink.asExpr() = ma.getArgument(0) ) } } module JDBCTemplateInjectionFlow = TaintTracking::Global<JDBCTemplateInjection>; from JDBCTemplateInjectionFlow::PathNode source, JDBCTemplateInjectionFlow::PathNode sink where JDBCTemplateInjectionFlow::flow(source, sink) select sink, source, sink, "Potential SQL injection vulnerability in JDBCTemplate query execution"

3. Maven Security Configuration

pom.xml Security Plugins

<properties> <owasp.dependency.check.version>8.4.2</owasp.dependency.check.version> <spotbugs.version>4.7.3</spotbugs.version> <pmd.version>6.55.0</pmd.version> <jacoco.version>0.8.8</jacoco.version> <codeql.maven.plugin.version>1.0.0</codeql.maven.plugin.version> </properties> <build> <plugins> <!-- OWASP Dependency Check --> <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> <version>${owasp.dependency.check.version}</version> <configuration> <format>HTML</format> <format>XML</format> <failBuildOnAnyVulnerability>true</failBuildOnAnyVulnerability> <failOnCVSS>7</failOnCVSS> <skipTestScope>true</skipTestScope> <skipRuntimeScope>false</skipRuntimeScope> <skipProvidedScope>false</skipProvidedScope> <skipSystemScope>false</skipSystemScope> <suppressionFiles> <suppressionFile>${project.basedir}/security/dependency-check-suppressions.xml</suppressionFile> </suppressionFiles> <analyzer> <assemblyEnabled>false</assemblyEnabled> </analyzer> </configuration> <executions> <execution> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> <!-- SpotBugs Security Configuration --> <plugin> <groupId>com.github.spotbugs</groupId> <artifactId>spotbugs-maven-plugin</artifactId> <version>${spotbugs.version}</version> <configuration> <effort>Max</effort> <threshold>Low</threshold> <failOnError>true</failOnError> <excludeFilterFile>${project.basedir}/security/spotbugs-security-exclude.xml</excludeFilterFile> <plugins> <plugin> <groupId>com.h3x3lf1t</groupId> <artifactId>findsecbugs</artifactId> <version>1.12.0</version> </plugin> </plugins> </configuration> <executions> <execution> <id>spotbugs-security-scan</id> <phase>verify</phase> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> <!-- PMD Security Rules --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> <version>${pmd.version}</version> <configuration> <rulesets> <ruleset>${project.basedir}/security/pmd-security-ruleset.xml</ruleset> <ruleset>category/java/security.xml</ruleset> </rulesets> <failOnViolation>true</failOnViolation> <printFailingErrors>true</printFailingErrors> <linkXRef>false</linkXRef> </configuration> <executions> <execution> <id>pmd-security-scan</id> <phase>verify</phase> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> <!-- JaCoCo Code Coverage --> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>${jacoco.version}</version> <executions> <execution> <id>prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>verify</phase> <goals> <goal>report</goal> </goals> </execution> <execution> <id>check</id> <goals> <goal>check</goal> </goals> <configuration> <rules> <rule> <element>BUNDLE</element> <limits> <limit> <counter>INSTRUCTION</counter> <value>COVEREDRATIO</value> <minimum>0.80</minimum> </limit> <limit> <counter>BRANCH</counter> <value>COVEREDRATIO</value> <minimum>0.70</minimum> </limit> </limits> </rule> </rules> </configuration> </execution> </executions> </plugin> </plugins> </build> <profiles> <profile> <id>security-scan</id> <build> <plugins> <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> <executions> <execution> <id>dependency-check</id> <phase>validate</phase> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles>

4. Security Configuration Files

OWASP Dependency Check Suppressions

<?xml version="1.0" encoding="UTF-8"?> <!-- security/dependency-check-suppressions.xml --> <suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.3.xsd"> <!-- Suppress false positives for specific libraries --> <suppress> <notes><![CDATA[ False positive for logback-core - see https://github.com/jeremylong/DependencyCheck/issues/XXXX ]]></notes> <packageUrl regex="true">^pkg:maven/ch\.qos\.logback/logback\-core@.*$</packageUrl> <cve>CVE-2023-12345</cve> </suppress> <!-- Suppress specific CVE in test scope --> <suppress> <notes><![CDATA[ Suppress test dependencies with known vulnerabilities ]]></notes> <gav regex="true">^junit:junit:.*$</gav> <cve>CVE-2020-15250</cve> </suppress> <!-- Suppress vulnerabilities with CVSS score below threshold --> <suppress base="true"> <notes><![CDATA[ Suppress vulnerabilities with CVSS score less than 7.0 ]]></notes> <cvssBelow>7.0</cvssBelow> </suppress> </suppressions>

SpotBugs Security Exclusions

<!-- security/spotbugs-security-exclude.xml --> <FindBugsFilter> <Match> <!-- Exclude specific security patterns in test code --> <Class name="~.*Test.*"/> <Bug pattern="HARD_CODE_PASSWORD"/> </Match> <Match> <!-- Exclude intentional password fields in configuration --> <Class name="com.example.config.SecurityConfig"/> <Field name="defaultPassword"/> <Bug pattern="HARD_CODE_PASSWORD"/> </Match> <Match> <!-- Exclude specific false positives for serialization --> <Class name="~.*\.model\..*"/> <Bug pattern="SE_BAD_FIELD"/> </Match> <Match> <!-- Exclude specific cryptographic patterns --> <Class name="com.example.security.CryptoUtil"/> <Bug pattern="STATIC_IV"/> </Match> </FindBugsFilter>

PMD Security Ruleset

<?xml version="1.0"?> <!-- security/pmd-security-ruleset.xml --> <ruleset name="Security Rules" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> <description>Custom security rules for Java applications</description> <!-- Import standard security rules --> <rule ref="category/java/security.xml"> <exclude name="InsecureCryptoIv"/> </rule> <!-- Custom security rules --> <rule ref="category/java/bestpractices.xml/AvoidUsingHardCodedIP"/> <rule ref="category/java/errorprone.xml/BeanMembersShouldSerialize"/> <!-- Custom rule configuration --> <rule ref="category/java/security.xml/HardCodedCryptoKey"> <properties> <property name="minimumLength" value="8"/> </properties> </rule> </ruleset>

5. Secure Java Code Examples

Secure Authentication Service

/** * Secure authentication service implementation with security best practices. * * @author Security Team * @version 1.0 */ package com.example.security; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.beans.factory.annotation.Value; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.util.Arrays; import java.util.Base64; /** * Secure authentication service with protection against common vulnerabilities. */ @Service public class SecureAuthService { private static final SecureRandom SECURE_RANDOM = new SecureRandom(); private static final int ITERATIONS = 10000; private static final int KEY_LENGTH = 256; private static final int SALT_LENGTH = 32; @Value("${security.pepper:defaultPepperValue}") private String pepper; private final PasswordEncoder passwordEncoder; public SecureAuthService() { this.passwordEncoder = new BCryptPasswordEncoder(12); // Strong work factor } /** * Securely hash password with salt and pepper. * * @param password the plain text password * @return hashed password with salt */ public String hashPassword(String password) { if (password == null || password.trim().isEmpty()) { throw new IllegalArgumentException("Password cannot be null or empty"); } // Generate cryptographically secure salt byte[] salt = generateSalt(); // Combine password with pepper String pepperedPassword = password + pepper; // Hash using PBKDF2 byte[] hash = pbkdf2Hash(pepperedPassword.toCharArray(), salt); // Encode salt and hash together return encodeSaltAndHash(salt, hash); } /** * Verify password against stored hash. * * @param password the plain text password * @param storedHash the stored hash with salt * @return true if password matches */ public boolean verifyPassword(String password, String storedHash) { if (password == null || storedHash == null) { return false; } try { // Decode salt and hash from stored value String[] parts = storedHash.split(":"); if (parts.length != 2) { return false; } byte[] salt = Base64.getDecoder().decode(parts[0]); byte[] expectedHash = Base64.getDecoder().decode(parts[1]); // Combine password with pepper String pepperedPassword = password + pepper; // Compute hash for provided password byte[] testHash = pbkdf2Hash(pepperedPassword.toCharArray(), salt); // Constant-time comparison to prevent timing attacks return constantTimeEquals(expectedHash, testHash); } catch (IllegalArgumentException | ArrayIndexOutOfBoundsException e) { return false; } } /** * Generate cryptographically secure salt. * * @return secure random salt */ private byte[] generateSalt() { byte[] salt = new byte[SALT_LENGTH]; SECURE_RANDOM.nextBytes(salt); return salt; } /** * PBKDF2 password hashing. * * @param password the password as char array * @param salt the salt * @return hashed password */ private byte[] pbkdf2Hash(char[] password, byte[] salt) { try { PBEKeySpec spec = new PBEKeySpec(password, salt, ITERATIONS, KEY_LENGTH); SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); return skf.generateSecret(spec).getEncoded(); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { throw new SecurityException("Password hashing failed", e); } finally { // Clear the password array Arrays.fill(password, '\0'); } } /** * Encode salt and hash for storage. * * @param salt the salt * @param hash the hash * @return encoded string */ private String encodeSaltAndHash(byte[] salt, byte[] hash) { String encodedSalt = Base64.getEncoder().encodeToString(salt); String encodedHash = Base64.getEncoder().encodeToString(hash); return encodedSalt + ":" + encodedHash; } /** * Constant-time array comparison to prevent timing attacks. * * @param a first array * @param b second array * @return true if arrays are equal */ private boolean constantTimeEquals(byte[] a, byte[] b) { if (a.length != b.length) { return false; } int result = 0; for (int i = 0; i < a.length; i++) { result |= a[i] ^ b[i]; } return result == 0; } /** * Generate secure random token for CSRF protection. * * @return secure random token */ public String generateCsrfToken() { byte[] tokenBytes = new byte[32]; SECURE_RANDOM.nextBytes(tokenBytes); return Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes); } /** * Validate CSRF token. * * @param expected the expected token * @param actual the actual token * @return true if tokens match */ public boolean validateCsrfToken(String expected, String actual) { if (expected == null || actual == null) { return false; } return constantTimeEquals( expected.getBytes(java.nio.charset.StandardCharsets.UTF_8), actual.getBytes(java.nio.charset.StandardCharsets.UTF_8) ); } }

SQL Injection Protected Repository

/** * Secure repository implementation with SQL injection protection. */ @Repository public class SecureOrderRepository { private final JdbcTemplate jdbcTemplate; private final NamedParameterJdbcTemplate namedParameterJdbcTemplate; public SecureOrderRepository(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); } /** * Find orders by customer ID using parameterized query. * * @param customerId the customer ID * @return list of orders */ public List<Order> findByCustomerId(String customerId) { String sql = "SELECT id, customer_id, amount, status, created_at " + "FROM orders WHERE customer_id = ? AND status = 'ACTIVE'"; return jdbcTemplate.query(sql, new Object[]{customerId}, (rs, rowNum) -> new Order( rs.getString("id"), rs.getString("customer_id"), rs.getBigDecimal("amount"), rs.getString("status"), rs.getTimestamp("created_at").toLocalDateTime() ) ); } /** * Search orders with multiple parameters safely. * * @param criteria search criteria * @return list of orders */ public List<Order> searchOrders(OrderSearchCriteria criteria) { String sql = "SELECT id, customer_id, amount, status, created_at " + "FROM orders WHERE 1=1"; MapSqlParameterSource params = new MapSqlParameterSource(); if (criteria.getCustomerId() != null) { sql += " AND customer_id = :customerId"; params.addValue("customerId", criteria.getCustomerId()); } if (criteria.getMinAmount() != null) { sql += " AND amount >= :minAmount"; params.addValue("minAmount", criteria.getMinAmount()); } if (criteria.getMaxAmount() != null) { sql += " AND amount <= :maxAmount"; params.addValue("maxAmount", criteria.getMaxAmount()); } if (criteria.getStatus() != null) { sql += " AND status = :status"; params.addValue("status", criteria.getStatus()); } sql += " ORDER BY created_at DESC"; return namedParameterJdbcTemplate.query(sql, params, (rs, rowNum) -> new Order( rs.getString("id"), rs.getString("customer_id"), rs.getBigDecimal("amount"), rs.getString("status"), rs.getTimestamp("created_at").toLocalDateTime() ) ); } /** * Batch insert orders safely. * * @param orders list of orders to insert */ public void batchInsert(List<Order> orders) { String sql = "INSERT INTO orders (id, customer_id, amount, status, created_at) " + "VALUES (?, ?, ?, ?, ?)"; jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { Order order = orders.get(i); ps.setString(1, order.getId()); ps.setString(2, order.getCustomerId()); ps.setBigDecimal(3, order.getAmount()); ps.setString(4, order.getStatus()); ps.setTimestamp(5, Timestamp.valueOf(order.getCreatedAt())); } @Override public int getBatchSize() { return orders.size(); } }); } /** * UNSAFE METHOD - Demonstrates SQL injection vulnerability. * This method would be caught by CodeQL analysis. * * @deprecated This method is vulnerable to SQL injection */ @Deprecated public List<Order> unsafeFindByCustomerId(String customerId) { // UNSAFE: String concatenation in SQL query String sql = "SELECT * FROM orders WHERE customer_id = '" + customerId + "'"; return jdbcTemplate.query(sql, (rs, rowNum) -> new Order( rs.getString("id"), rs.getString("customer_id"), rs.getBigDecimal("amount"), rs.getString("status"), rs.getTimestamp("created_at").toLocalDateTime() ) ); } }

6. Security Headers Configuration

Security Configuration Class

/** * Security configuration for HTTP headers and protection. */ @Configuration @EnableWebSecurity public class SecurityConfig { @Value("${security.csp.policy:default-src 'self'}") private String cspPolicy; /** * Main security configuration. */ @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http // CSRF protection .csrf(csrf -> csrf .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .ignoringRequestMatchers("/api/public/**") ) // Security headers .headers(headers -> headers .contentSecurityPolicy(csp -> csp.policyDirectives(cspPolicy)) .frameOptions(frame -> frame.deny()) .xssProtection(xss -> xss.block(true)) .contentTypeOptions(contentType -> {}) ) // Session management .sessionManagement(session -> session .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) .maximumSessions(1) .maxSessionsPreventsLogin(true) ) // Authorization .authorizeHttpRequests(authz -> authz .requestMatchers("/api/public/**").permitAll() .requestMatchers("/api/admin/**").hasRole("ADMIN") .requestMatchers("/api/**").authenticated() .anyRequest().permitAll() ) // Authentication .formLogin(form -> form .loginPage("/login") .permitAll() ) .logout(logout -> logout .logoutSuccessUrl("/") .permitAll() ); return http.build(); } /** * Password encoder with strong hashing. */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(12); } /** * Custom security headers filter. */ @Bean public FilterRegistrationBean<SecurityHeadersFilter> securityHeadersFilter() { FilterRegistrationBean<SecurityHeadersFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new SecurityHeadersFilter()); registrationBean.addUrlPatterns("/*"); return registrationBean; } } /** * Custom security headers filter. */ @Component public class SecurityHeadersFilter implements Filter { @Value("${security.headers.csp:default-src 'self'}") private String cspPolicy; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpResponse = (HttpServletResponse) response; // Security headers httpResponse.setHeader("Content-Security-Policy", cspPolicy); httpResponse.setHeader("X-Content-Type-Options", "nosniff"); httpResponse.setHeader("X-Frame-Options", "DENY"); httpResponse.setHeader("X-XSS-Protection", "1; mode=block"); httpResponse.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains"); httpResponse.setHeader("Referrer-Policy", "strict-origin-when-cross-origin"); httpResponse.setHeader("Permissions-Policy", "geolocation=(), microphone=(), camera=()"); chain.doFilter(request, response); } }

7. GitHub Security Dashboard Configuration

security.md

# Security Policy ## Supported Versions | Version | Supported | | ------- | ------------------ | | 1.0.x | :white_check_mark: | | < 1.0 | :x: | ## Reporting a Vulnerability We take the security of our software seriously. If you believe you've found a security vulnerability, please report it to us. ### Private Reporting Please **DO NOT** disclose security-related issues publicly until we've had a chance to address them. 1. **Email**: [email protected] 2. **Encryption**: Use our [PGP key](https://example.com/security/pgp-key.asc) 3. **Response Time**: We aim to respond within 48 hours ### Public Reporting For non-sensitive security issues, you can: 1. Create a GitHub issue 2. Use the security advisory feature ## Security Scanning Our project uses automated security scanning: ### Tools Used - **GitHub CodeQL**: Static analysis for security vulnerabilities - **OWASP Dependency Check**: Dependency vulnerability scanning - **SpotBugs**: Bug patterns including security issues - **PMD**: Static analysis for code quality ### Scan Frequency - **On every push**: CodeQL analysis - **Daily**: Full security scan - **On release**: Comprehensive security audit ## Security Practices ### Code Security - All code undergoes security review - Automated security testing in CI/CD - Regular dependency updates - Security headers enforcement ### Data Protection - Encryption at rest and in transit - Secure password hashing (PBKDF2/BCrypt) - Principle of least privilege - Regular security audits ## Dependency Security We monitor dependencies for vulnerabilities: ### Automatic Updates - Dependabot security updates enabled - Weekly dependency scanning - Manual review of major updates ### Vulnerability Response 1. **Critical**: Fix within 24 hours 2. **High**: Fix within 72 hours 3. **Medium**: Fix within 1 week 4. **Low**: Fix in next release cycle

8. Advanced Security Workflows

scheduled-security-scan.yml

name: "Scheduled Security Deep Scan" on: schedule: - cron: '0 2 * * 1' # Every Monday at 2 AM workflow_dispatch: # Manual trigger jobs: deep-security-scan: name: Deep Security Analysis runs-on: ubuntu-latest timeout-minutes: 120 steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' cache: 'maven' # Comprehensive CodeQL Analysis - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: java queries: security-and-quality, security-extended, ../codeql-queries/java/ql/src/Security/CWE build-mode: manual - name: Build with detailed compilation run: | mvn clean compile -DskipTests -Dmaven.compiler.debug=true -Dmaven.compiler.debuglevel=lines,vars,source - name: Advanced CodeQL Analysis uses: github/codeql-action/analyze@v3 with: output: advanced-codeql-results.sarif upload-database: true # SAST Tools Suite - name: Run SonarQube Analysis uses: SonarSource/sonarcloud-github-action@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - name: Run Snyk Security Scan uses: snyk/actions/maven@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: args: --severity-threshold=high # Dependency Analysis - name: Run OWASP Dependency Check run: mvn org.owasp:dependency-check-maven:aggregate -DskipTests - name: Run License Compliance Check run: mvn org.codehaus.mojo:license-maven-plugin:aggregate-add-third-party # Security Report Generation - name: Generate Security Report run: | echo "# Security Scan Report - $(date)" > security-report.md echo "## Summary" >> security-report.md echo "- CodeQL Issues: TODO" >> security-report.md echo "- Dependency Vulnerabilities: TODO" >> security-report.md echo "- License Compliance: TODO" >> security-report.md echo "## Detailed Findings" >> security-report.md - name: Upload Security Reports uses: actions/upload-artifact@v4 with: name: security-reports-$(date +%Y%m%d) path: | target/dependency-check-report.html security-report.md target/site/ retention-days: 90 - name: Notify Security Team if: failure() uses: 8398a7/action-slack@v3 with: status: failure text: Security scan failed. Please review the findings. env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_SECURITY_WEBHOOK }}

9. Security Testing

Security Test Suite

/** * Security test suite for vulnerability detection. */ @SpringBootTest class SecurityTestSuite { @Autowired private SecureAuthService authService; @Autowired private WebApplicationContext context; private MockMvc mockMvc; @BeforeEach void setup() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); } /** * Test for SQL injection vulnerabilities. */ @Test void testSqlInjectionProtection() throws Exception { String sqlInjectionPayload = "admin' OR '1'='1"; mockMvc.perform(get("/api/orders") .param("customerId", sqlInjectionPayload)) .andExpect(status().isBadRequest()) // Should reject malicious input .andExpect(content().string(not(containsString("admin")))); } /** * Test for XSS protection. */ @Test void testXssProtection() throws Exception { String xssPayload = "<script>alert('XSS')</script>"; mockMvc.perform(post("/api/orders") .contentType(MediaType.APPLICATION_JSON) .content("{\"customerId\": \"" + xssPayload + "\"}")) .andExpect(header().string("X-XSS-Protection", "1; mode=block")) .andExpect(content().string(not(containsString("<script>")))); } /** * Test CSRF protection. */ @Test void testCsrfProtection() throws Exception { mockMvc.perform(post("/api/orders") .contentType(MediaType.APPLICATION_JSON) .content("{}")) .andExpect(status().isForbidden()); // Should require CSRF token } /** * Test secure password hashing. */ @Test void testPasswordHashingSecurity() { String password = "MySecurePassword123!"; String hash1 = authService.hashPassword(password); String hash2 = authService.hashPassword(password); // Hashes should be different due to random salt assertNotEquals(hash1, hash2); // But both should verify correctly assertTrue(authService.verifyPassword(password, hash1)); assertTrue(authService.verifyPassword(password, hash2)); // Wrong password should not verify assertFalse(authService.verifyPassword("WrongPassword", hash1)); } /** * Test timing attack protection. */ @Test void testTimingAttackProtection() { String password = "testPassword"; String hash = authService.hashPassword(password); // Measure verification time for correct and incorrect passwords long correctTime = measureVerificationTime(password, hash); long incorrectTime = measureVerificationTime("wrongPassword", hash); // Times should be similar (within reasonable margin) long timeDifference = Math.abs(correctTime - incorrectTime); assertTrue(timeDifference < 100, "Verification times should not differ significantly to prevent timing attacks"); } private long measureVerificationTime(String password, String hash) { long startTime = System.nanoTime(); authService.verifyPassword(password, hash); return System.nanoTime() - startTime; } /** * Test security headers. */ @Test void testSecurityHeaders() throws Exception { mockMvc.perform(get("/api/public/health")) .andExpect(header().string("X-Content-Type-Options", "nosniff")) .andExpect(header().string("X-Frame-Options", "DENY")) .andExpect(header().string("X-XSS-Protection", "1; mode=block")) .andExpect(header().exists("Strict-Transport-Security")); } }

Best Practices

1. Security-First Development

// Secure by default - always validate input public class InputValidator { public static String sanitizeInput(String input) { if (input == null) return null; // Remove potential XSS vectors return input.replaceAll("<", "&lt;") .replaceAll(">", "&gt;") .replaceAll("\"", "&quot;") .replaceAll("'", "&#x27;"); } public static boolean isValidCustomerId(String customerId) { return customerId != null && customerId.matches("[a-zA-Z0-9-]{1,50}"); // Strict pattern } }

2. Continuous Security Monitoring

# Security dashboard configuration security_metrics: code_quality: max_critical_issues: 0 max_high_issues: 5 max_medium_issues: 20 dependencies: max_critical_vulnerabilities: 0 max_high_vulnerabilities: 3 update_frequency: weekly coverage: min_security_test_coverage: 80 min_overall_coverage: 70

3. Incident Response

public class SecurityIncidentLogger { private static final Logger SECURITY_LOGGER = LoggerFactory.getLogger("SECURITY"); public static void logSecurityIncident(String event, String details) { SECURITY_LOGGER.warn("SECURITY_INCIDENT: {} - {}", event, details); // Additional security monitoring integration notifySecurityTeam(event, details); } }

Conclusion

This comprehensive GitHub Code Scanning implementation provides:

  • Automated security scanning with CodeQL and multiple tools
  • Continuous vulnerability detection integrated into development workflow
  • Security-focused code examples demonstrating best practices
  • Comprehensive testing for security vulnerabilities
  • Security monitoring and reporting with actionable insights

Key benefits:

  • Early vulnerability detection before production deployment
  • Security compliance through automated checks
  • Developer education with immediate feedback
  • Risk reduction through continuous monitoring
  • Compliance reporting with detailed security metrics

The setup enables organizations to maintain high security standards while accelerating development through automated security controls and continuous monitoring.

Advanced Java Supply Chain Security, Kubernetes Hardening & Runtime Threat Detection

Sigstore Rekor in Java – https://macronepal.com/blog/sigstore-rekor-in-java/
Explains integrating Sigstore Rekor into Java systems to create a transparent, tamper-proof log of software signatures and metadata for verifying supply chain integrity.

Securing Java Applications with Chainguard Wolfi – https://macronepal.com/blog/securing-java-applications-with-chainguard-wolfi-a-comprehensive-guide/
Explains using Chainguard Wolfi minimal container images to reduce vulnerabilities and secure Java applications with hardened, lightweight runtime environments.

Cosign Image Signing in Java Complete Guide – https://macronepal.com/blog/cosign-image-signing-in-java-complete-guide/
Explains how to digitally sign container images using Cosign in Java-based workflows to ensure authenticity and prevent unauthorized modifications.

Secure Supply Chain Enforcement Kyverno Image Verification for Java Containers – https://macronepal.com/blog/secure-supply-chain-enforcement-kyverno-image-verification-for-java-containers/
Explains enforcing Kubernetes policies with Kyverno to verify container image signatures and ensure only trusted Java container images are deployed.

Pod Security Admission in Java Securing Kubernetes Deployments for JVM Applications – https://macronepal.com/blog/pod-security-admission-in-java-securing-kubernetes-deployments-for-jvm-applications/
Explains Kubernetes Pod Security Admission policies that enforce security rules like restricted privileges and safe configurations for Java workloads.

Securing Java Applications at Runtime Kubernetes Security Context – https://macronepal.com/blog/securing-java-applications-at-runtime-a-guide-to-kubernetes-security-context/
Explains how Kubernetes security contexts control runtime permissions, user IDs, and access rights for Java containers to improve isolation.

Process Anomaly Detection in Java Behavioral Monitoring – https://macronepal.com/blog/process-anomaly-detection-in-java-comprehensive-behavioral-monitoring-2/
Explains detecting abnormal runtime behavior in Java applications to identify potential security threats using process monitoring techniques.

Achieving Security Excellence CIS Benchmark Compliance for Java Applications – https://macronepal.com/blog/achieving-security-excellence-implementing-cis-benchmark-compliance-for-java-applications/
Explains applying CIS security benchmarks to Java environments to standardize hardening and improve overall system security posture.

Process Anomaly Detection in Java Behavioral Monitoring – https://macronepal.com/blog/process-anomaly-detection-in-java-comprehensive-behavioral-monitoring/
Explains behavioral monitoring of Java processes to detect anomalies and improve runtime security through continuous observation and analysis.

JAVA CODE COMPILER

FREE ONLINE JAVA CODE COMPILER

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper