Note: Click on the image to see a larger (original) version.
Introduction
Static Application Security Testing (SAST) is a crucial practice within the Software Security Development Life Cycle (SSDLC) that enables developers to identify security vulnerabilities early in the code development phase. While understanding the concepts of SAST is important, implementing it effectively in real-world projects is what ensures robust and secure software delivery.
In this second part of our SAST series, we focus on integrating the SonarQube Cloud, a popular static analysis tool, into the IntelliJ IDEA and running it using Docker.
We will explore:
- SonarQube Cloud for SAST
- Local scanning with SonarQube Cloud via IntelliJ IDEA
- Local scanning using Docker Compose with SonarQube image
Tools:
- SonarQube Cloud
- Spring Boot
- IntelliJ IDEA
- Docker-Compose
Prerequisites:
Create a Spring Boot project using IntelliJ IDEA or the Spring Boot Initializr at https://start.spring.io/.
Click Next and generate the project without dependencies.
SonarQube Cloud for SAST
SonarQube Cloud offers a hassle-free way to start static code analysis without managing your own infrastructure. It provides cloud-hosted scanning capabilities that analyze code quality, security vulnerabilities, bugs, and code smells.
Setting Up SonarQube Cloud
- Create an account: Visit SonarQube’s official website and sign up for a free or paid cloud account.
- Create a new project: Once logged in, create a new project by providing your repository details.
- Generate an authentication token: For integrating scanning tools, generate a security token from your account settings. We must store it in a secret place, like in the GitHub Actions environment or repository secret.
- Configure project settings: We need to set Quality Gates, SLAs, and rules according to our security policy. For a free account, we cannot create the Quality Gates; we must use the default one.
SonarQube Cloud then becomes the central place to view detailed security reports and code quality metrics.
Overview of SonarQube’s cloud capabilities for static code analysis
SonarCloud is a fully managed SaaS platform for continuous static code analysis, designed to detect code quality issues, security vulnerabilities, and maintainability risks across modern software projects. It provides code coverage plugin integration that is used by 30+ different programming languages, including Java, Python, C#, JavaScript, TypeScript, and Go.
Capabilities:
-
Cloud-hosted and fully managed: SonarCloud removes the need for installation, hosting, or maintenance. This allows teams to focus solely on development and CI/CD pipelines. Use the cloud version if your company does not work under compliance regulations.
SonarSource manages:
- uptime
- scaling
- rule updates
- language analyzers
- security patches
-
Deep Static Code Analysis: SonarCloud performs comprehensive static analysis across many dimensions:
- Bug Detection. Identifies code paths that can lead to crashes, incorrect logic, or unintended behavior.
- Security vulnerability detection. Finds CWE-based, OWASP-aligned issues such as:
- SQL Injection
- Path traversal
- Input validation issues
- Hardcoded secrets
- Command injection
- Code Smells. Flags maintainability issues, duplicated code, bad design, and anti-patterns.
- Cognitive Complexity. Measures how difficult code is to understand and maintain.
- Multi-language support. Supports 30+ languages, including Java, Python, JavaScript, TypeScript, Go, C#, Kotlin, PHP, Terraform, YAML, and more.
-
Seamless CI/CD integration: SonarCloud integrates natively with:
- CI providers:
- GitHub Actions
- Azure Pipelines
- Bitbucket Pipelines
- GitLab CI
- Build tools: SonarQube provides integrations with build tools. For example, in our case, the Gradle Sonar plugin is used to run Sonar Scanner in the CI/CD pipeline.
- CI providers:
Pull request and branch analysis: SonarCloud performs inline analysis during PR reviews, preventing issues from reaching the main branch. The free plan does not support this.
-
Quality Gates: A Quality Gate defines the rules that code must satisfy before being merged. If a PR fails the Quality Gate, the CI pipeline can block the merge. Adding custom Quality Gates is not supported by the free plan.
Default checks include:
- No new critical or blocker issues.
- Code coverage must meet a minimum threshold.
- No new bugs or security vulnerabilities.
- No new code duplications.
Test coverage and code metrics: SonarCloud provides overall coverage and new code coverage, for example, for a specific PR or branch.
-
Organization and project dashboards: SonarCloud provides rich dashboards for:
- Centralized issue tracking.
- Historical trend charts for issues, code coverage, and duplications.
- Hotspot security review.
- Code coverage progress.
- History of activities for each branch or PR.
-
Notifications and integrations: Supports notifications via:
- GitHub checks.
- GitLab merge requests.
- Slack.
- Email.
- Webhooks.
Open APIs and extensions: SonarQube provides APIs to build custom dashboards and export metrics.
Local scanning with SonarQube Cloud via IntelliJ IDEA
Running local scans during development helps catch issues early before code is committed.
Installing and configuring the SonarQube plugin in IntelliJ IDEA
- Open IntelliJ IDEA.
- Navigate to File > Settings > Plugins and search for the "SonarQube" plugin.
- Install and restart the IDE. It must appear in the “Installed” section.
- Generate the authentication Sonar token. Go to the SonarCloud website, then My Account > Security > Generate Token, or click on this link https://sonarcloud.io/account/security/, and you will be redirected to the token generation page. Enter the name of the token, typically where you want to use it, and click the “Generate Token” button.
- Configure the plugin by adding your SonarQube Cloud server URL and authentication token. Click on the SonarQube plugin icon, then select the gear icon, as shown in the screenshot.
Enter the Project key of your SonarQube project and click “Configure the connection”.
You will see the Connection section, click the plus to add a new connection.
Enter the name of the connection and click “Next”.
Paste the generated token, or you can even create the token from this IDE window. Click “Next”, and the IDE will attempt to connect to Sonar Cloud. You will see that authentication is successful if the connection is established.
Running local scans
After configuration, you can run SonarQube scans directly from the IDE. The plugin highlights issues inline and provides quick access to detailed analysis reports. Click “Analyze All Project Files”.
You can see the results. In this case, it found the token in the gradle-local.properties file, which is ignored by the .gitignore file, and it is only for local purposes. However, you will still see it unless you exclude it from scanning. This plugin also allows you to do it.
Below you can see the result of this specific finding. Additionally, the plugin provides information on why this issue occurs and how to resolve it.
Benefits of local scanning:
- Immediate feedback on security and quality issues.
- Reduces the likelihood of pushing vulnerable code.
- Saves time by fixing problems early in the development workflow.
Local scanning using Docker Compose with SonarQube image
If you prefer running SonarQube locally, Docker provides an easy setup that eliminates the need for complex installation.
Setting up SonarQube locally via Docker Compose
Create a “docker-compose.yml” file with the following content:
version: "3.9"
services:
sonarqube:
image: sonarqube:latest
ports:
- "9000:9000"
environment:
SONAR_ES_BOOTSTRAP_CHECKS_DISABLE: "true"
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
volumes:
sonarqube_data:
sonarqube_extensions:
Here is the gradle-local.properties file.
Place it in the root of the project and add it to the .gitignore.
systemProp.sonar.qualitygate.wait=true
sonar.projectKey=sonarqube_actions_demo_key
sonar.organization=local-organization
sonar.projectName=sonarqube_actions_demo
sonar.token=sqp_b7dc6e025b58eb7455b11c6c468cda2b79eb6450b
sonar.host.url=http://localhost:9000
sonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml
Gradle configuration. The SonarQube plugin is required.
plugins {
id 'java'
id "org.sonarqube" version "7.0.0.6105"
id 'jacoco'
id 'org.springframework.boot' version '3.0.0'
id 'io.spring.dependency-management' version '1.1.7'
}
SonarQube properties
def localProps = new Properties()
def localFile = file("gradle-local.properties")
if (localFile.exists()) {
localProps.load(localFile.newDataInputStream())
}
sonar {
properties {
property "sonar.projectKey", System.getenv("SONAR_PROJECT_KEY") ?: localProps["sonar.projectKey"]
property "sonar.organization", System.getenv("SONAR_ORGANIZATION_KEY") ?: localProps["sonar.organization"]
property "sonar.projectName", System.getenv("SONAR_PROJECT_NAME") ?: localProps["sonar.projectName"]
property "sonar.token", System.getenv("SONAR_TOKEN") ?: localProps["sonar.token"]
property "sonar.host.url", System.getenv("SONAR_HOST_URL") ?: localProps["sonar.host.url"]
}
}
Run the following command to start the container: docker-compose up -d, or you can run it from your IntelliJ IDEA
You can see the container is up and running
Access SonarQube dashboard at http://localhost:9000. Login is admin, but you will need to change the password from admin to a new one.
Click Create project from the top right corner.
Enter the same name and project key as in your gradle-local.properties file. Then select to use the previous version.
Choose Locally as the Analysis Method
Type the name of the token and click Generate, then Continue, and set it in the gradle-local.properties file to the “sonar.token” property like
properties sonar.token=sqp_b7dc6e025b58eb7455b11c6c468cda2b79eb6450b
.
If you want to generate manually, you can do it as shown in the screenshot below.
Run the Sonar scan from the command line or from IntelliJ IDEA
Use this command ./gradlew sonar --info or run from your IntelliJ IDEA
You can view the result by going to the Projects tab. The metrics and coverage are for the main branch only and show overall coverage and metrics. For more details about the new code analysis, click on the project.
Comparing Local Docker Setup with Cloud Scanning
- Cloud: No maintenance, scalable, accessible anywhere.
- Local Docker: Full control, ideal if you have no internet connection for an extended period but need to review scan results, useful for sensitive projects.
Conclusion
This article demonstrates how to maximize the benefits of SonarCloud by scanning locally with IntelliJ IDEA or Docker. This helps prevent insecure code from being pushed even to a feature branch and allows developers to work more productively.
Closing
This article covered SonarQube Cloud configuration and IntelliJ IDEA integration, as well as running SonarQube locally with Docker. In “Automating code security in CI/CD: SonarCloud SAST guide (Part 3)”, we will explore practical integration examples, configuration patterns, and CI/CD pipelines.
Links
- SonarQube Cloud - https://sonarcloud.io/
- SonarQube documentation - https://docs.sonarsource.com/
Originally published on my personal blog: https://matevosian.tech/blog/post/SAST-part1-theory




















Top comments (0)