DEV Community

Cover image for Applying Checkov to Terraform as Code – A TFSEC Alternative
IKER ALBERTO SIERRA RUIZ
IKER ALBERTO SIERRA RUIZ

Posted on

Applying Checkov to Terraform as Code – A TFSEC Alternative

Static Application Security Testing (SAST) is a critical practice in modern DevSecOps. While tools like SonarQube, Snyk, and Veracode are popular, this article focuses on GitHub CodeQL – a semantic code analysis engine that treats code as a database. We will apply it to a vulnerable Java Spring Boot application to detect SQL Injection and Path Traversal.


🤔 Why CodeQL?

Unlike pattern-based scanners, CodeQL builds a relational database of your code, including abstract syntax trees, control flow graphs, and data flow graphs. This allows it to track tainted data across functions, classes, and files, drastically reducing false positives.


🚨 Target Application (Vulnerable Java App)

Let's look at a simple REST API with two vulnerable endpoints.

File: UserController.java

package com.demo.controller;

import com.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

@RestController
@RequestMapping("/api")
public class UserController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    // Vulnerability 1: SQL Injection
    @GetMapping("/users")
    public List<User> getUsers(@RequestParam("id") String userId) {
        String sql = "SELECT * FROM users WHERE id = " + userId; // Dangerous concatenation
        return jdbcTemplate.query(sql, (rs, rowNum) -> 
            new User(rs.getString("id"), rs.getString("name")));
    }

    // Vulnerability 2: Path Traversal
    @GetMapping("/file")
    public String readFile(@RequestParam("filename") String filename) throws Exception {
        return new String(Files.readAllBytes(Paths.get("/var/data/" + filename)));
    }
}
Enter fullscreen mode Exit fullscreen mode

🛠️ Installing and Configuring CodeQL CLI

You can run CodeQL locally to analyze your code before pushing it to a repository.

1. Download CodeQL from GitHub releases:

wget [https://github.com/github/codeql-cli-binaries/releases/latest/download/codeql-linux64.zip](https://github.com/github/codeql-cli-binaries/releases/latest/download/codeql-linux64.zip)
Enter fullscreen mode Exit fullscreen mode

2. Unzip and add to PATH:

unzip codeql-linux64.zip -d ~/tools/
export PATH=$PATH:~/tools/codeql/
Enter fullscreen mode Exit fullscreen mode

3. Create a CodeQL database from your source code:

codeql database create ./codeql-db --language=java --source-root=.
Enter fullscreen mode Exit fullscreen mode

4. Download the standard query suite:

git clone [https://github.com/github/codeql.git](https://github.com/github/codeql.git) ~/codeql-repo
Enter fullscreen mode Exit fullscreen mode

5. Run the analysis:

codeql database analyze ./codeql-db --format=sarif-latest --output=results.sarif ~/codeql-repo/java/ql/src/codeql-suites/java-security-and-quality.qls
Enter fullscreen mode Exit fullscreen mode

📊 Interpreting SARIF Results

The results.sarif file (in JSON format) will reveal the vulnerabilities found. For example:

  • Rule ID: java/sql-injection
  • Location: line 18, column 20
  • Code flow: from user-controlled parameter userId to the SQL query sink.

This confirms a critical SQL Injection vulnerability traced straight to the source.


🚀 CI/CD Integration with GitHub Actions

Running CodeQL locally is great, but automating it is better. Here is how to create a GitHub Actions workflow to scan your code automatically.

File: .github/workflows/codeql-analysis.yml

name: "CodeQL Security Scan"
on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  analyze:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-java@v4
      with:
        distribution: 'temurin'
        java-version: '17'
    - uses: github/codeql-action/init@v3
      with:
        languages: 'java-kotlin'
        queries: security-extended
    - uses: github/codeql-action/autobuild@v3
    - uses: github/codeql-action/analyze@v3
Enter fullscreen mode Exit fullscreen mode

On every pull request, CodeQL will run and upload the results directly to the "Security" tab of your repository.


⚙️ Custom Queries (Advanced)

Because CodeQL treats your code like a database, you can write custom queries to find specific anti-patterns. For example, to detect the use of printStackTrace():

File: CustomLogging.ql

import java

from MethodCall call, Method m
where m.hasName("printStackTrace") and call.getMethod() = m
select call, "Use of printStackTrace() may expose internal details."
Enter fullscreen mode Exit fullscreen mode

Run it with:

codeql query run CustomLogging.ql --database=./codeql-db
Enter fullscreen mode Exit fullscreen mode

🎯 Conclusion

CodeQL provides deep, semantic SAST analysis. Integrated into CI/CD, it becomes an automated gatekeeper against critical vulnerabilities like SQL Injection and Path Traversal. It is a powerful, enterprise-grade alternative to commercial tools, especially for teams already utilizing the GitHub ecosystem.

Top comments (0)