Ravindra BagaleCourses & study guides Track your progress

Guides

How to Use SonarQube for Code Analysis (Community Build, Step by Step)

To use SonarQube for code analysis, start the server (the quickest way is docker run -d -p 9000:9000 sonarqube:community), create a project and an analysis token, and run the scanner for your language from your project folder. SonarQube then shows bugs, vulnerabilities, security hotspots and code smells. Add a quality gate to CI so new code with serious issues cannot be merged.

Quick answer

docker run -d --name sonarqube -p 9000:9000 sonarqube:community
# open http://<server>:9000, log in admin/admin, change the password,
# create a project "orders-api" and a token, then from the project folder:
mvn clean verify sonar:sonar -Dsonar.projectKey=orders-api \
  -Dsonar.host.url=http://<server>:9000 -Dsonar.token=<token>

A live example first

We run SonarQube on a t3.medium EC2 instance (it needs about 2 GB of RAM; a t2.micro is too small), in a private subnet reached over a VPN.

  1. Set the kernel value that Elasticsearch inside SonarQube needs, then start it:
sudo sysctl -w vm.max_map_count=524288
docker run -d --name sonarqube -p 9000:9000 sonarqube:community
docker logs -f sonarqube | grep -m1 "SonarQube is operational"
  1. Open http://<private-ip>:9000, log in with admin / admin, and set a new password when asked.
  2. Click Create project → Local project, name it orders-api, and pick "Use the global setting" for new code.
  3. Choose Locally, generate a token, and choose your build tool.

Now we scan a small Spring Boot app that has this method:

String sql = "SELECT * FROM orders WHERE customer = '" + name + "'";
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
mvn clean verify sonar:sonar -Dsonar.projectKey=orders-api \
  -Dsonar.host.url=http://10.0.2.15:9000 -Dsonar.token=sqp_xxx

The project page shows 1 Vulnerability (or a Security Hotspot, depending on the rules) on that line, with a message along the lines of "Change this code to not construct SQL queries directly from user-controlled data." We change it to a PreparedStatement with ? and scan again. The finding disappears and the quality gate shows Passed. Friends, the tool explained the risk in plain words and pointed to the exact line.

How does SonarQube work?

SonarQube in a pipeline Code is scanned, results go to the SonarQube server, the quality gate decides and the pipeline passes or fails. SonarQube in a pipeline CodecommitScannermvn/cliServerrulesQuality gatenew codeMergepass/fail you Static analysis checks your own code before it is merged

The scanner sends results to the server, and the quality gate decides if new code can be merged.

There are two parts. The server stores rules, history and results and shows the web UI. The scanner runs where your code is (your laptop or a CI runner), reads the code, and sends a report to the server. The server then applies the quality gate. The default gate, "Sonar way", focuses on new code, so an old project can start today without fixing ten years of issues first.

What the results mean

Type Meaning Example
Bug Code that will probably break Null pointer on a path you can reach
Vulnerability Code that can be attacked SQL built from user input
Security Hotspot Sensitive code a human must review Hard-coded IP, weak hash, CORS *
Code smell Hard to maintain A 300-line method, duplicated blocks
Coverage Lines run by tests Needs a test report (JaCoCo, lcov, coverage.xml)

Scan each language

Java (Maven or Gradle)

mvn clean verify sonar:sonar -Dsonar.projectKey=orders-api -Dsonar.token=$SONAR_TOKEN

For Gradle, add the org.sonarqube plugin and run ./gradlew sonar. Add JaCoCo to get coverage.

.NET

dotnet tool install --global dotnet-sonarscanner
dotnet sonarscanner begin /k:"billing-api" /d:sonar.host.url="http://10.0.2.15:9000" /d:sonar.token="$SONAR_TOKEN"
dotnet build
dotnet sonarscanner end /d:sonar.token="$SONAR_TOKEN"

Node.js / TypeScript, Python, PHP, Go and Ruby (sonar-scanner CLI)

Create sonar-project.properties in the project root:

sonar.projectKey=web-frontend
sonar.sources=src
sonar.exclusions=**/node_modules/**,**/vendor/**
sonar.javascript.lcov.reportPaths=coverage/lcov.info

Then run the scanner in Docker so you do not install anything:

docker run --rm -e SONAR_HOST_URL=http://10.0.2.15:9000 -e SONAR_TOKEN=$SONAR_TOKEN \
  -v "$PWD:/usr/src" sonarsource/sonar-scanner-cli
Language Coverage report key
JavaScript / TypeScript sonar.​javascript.​lcov.​reportPaths
Python sonar.​python.​coverage.​reportPaths (coverage.xml)
PHP sonar.​php.​coverage.​reportPaths (clover.xml)
Go sonar.​go.​coverage.​reportPaths (coverage.out)

Add the quality gate to CI

GitHub Actions

- uses: SonarSource/sonarqube-scan-action@v4
  env:
    SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
    SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
- uses: SonarSource/sonarqube-quality-gate-action@v1
  timeout-minutes: 5
  env:
    SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

Jenkins

Install the SonarQube Scanner plugin, then use withSonarQubeEnv('sonar') { sh 'mvn sonar:sonar' } followed by waitForQualityGate abortPipeline: true.

Keep SonarQube itself secure

  1. Change the default admin password on first login.
  2. In Administration → Security, turn on Force user authentication.
  3. Keep it in a private subnet, reached through a VPN or bastion.
  4. Use project tokens in CI, stored as CI secrets, never in the repo.
  5. Use PostgreSQL for anything beyond a lab (the built-in H2 database is for evaluation only).

Real example

In October 2020 the FBI published a flash alert saying that attackers had been stealing source code from US government agencies and companies through SonarQube servers exposed to the internet with default settings, such as the default admin password. A tool meant to make code safer leaked it instead. That is why step 1 above is "change the password" and step 3 is "keep it private".

Mistakes to avoid

  1. Gating on overall code on day one. The project fails forever. Gate on new code.
  2. Marking every hotspot "Safe" without reading. Each one needs a short reason.
  3. Thinking SonarQube replaces other tests. Pair it with dependency scanning (Trivy) and DAST in staging.

Summary table

Step Command / place
Run the server docker run -​p 9000:​9000 sonarqube:​community
Java mvn sonar:sonar / ./gradlew sonar
.NET dotnet sonarscanner begin/​end
JS, Python, PHP, Go sonar-​scanner-​cli + sonar-​project.​properties
CI gate Quality gate action / waitForQualityGate
Secure it New password, force auth, private network

Quick quiz: check what you learned

  1. What kind of testing does SonarQube do?

    1. Static analysis of source code
    2. Load testing of web servers
    3. Scanning cloud IP addresses
    4. Fuzzing a running binary
    Show answer

    A. SonarQube reads the code without running it.

  2. What is a quality gate?

    1. Pass or fail rules for new code
    2. A firewall in front of the server
    3. A Docker network for scanners
    4. A list of approved IDE plugins
    Show answer

    A. The gate checks conditions such as new critical issues and coverage.

  3. Which tool fits library CVEs better than SonarQube Community?

    1. Trivy or Dependency-Check
    2. The SonarLint IDE plugin
    3. A Git pre-push hook only
    4. The Jenkins Blue Ocean UI
    Show answer

    A. SCA tools match library versions against CVE databases.

  4. Why keep SonarQube off the public internet?

    1. It stores your source code
    2. It needs port 22 to work
    3. It blocks the CI runners
    4. It can only run on a VPN
    Show answer

    A. An exposed instance can leak private code.

Frequently asked questions

What is SonarQube used for?

SonarQube reads your source code without running it (static analysis) and reports bugs, security vulnerabilities, security hotspots, code smells, duplication and test coverage.

Is SonarQube free?

The Community Build is free and open source and covers many languages. Paid editions add branch analysis, more security rules and more languages.

What is a security hotspot?

Code that touches something sensitive, such as a hard-coded IP or a weak hash, that a person must review. It is not always a bug.

What is a quality gate?

A set of pass/fail conditions, like "no new critical vulnerabilities" and "80% coverage on new code". CI can stop a merge when it fails.

Does SonarQube find vulnerable libraries?

Mostly no in the Community Build. Use Trivy, OWASP Dependency-Check or npm audit for library CVEs. SonarQube focuses on your own code.

Should SonarQube be open to the internet?

No. It holds your source code. Keep it behind a VPN or private network, with a strong admin password and no anonymous access.