Intro
Ensuring code quality and security in Java applications is a complex task. Poor coding practices, such as code duplication, complex structures, or lack of documentation, can compromise your code's maintainability, readability, and efficiency. In addition, malicious entities can exploit vulnerabilities, leading to unauthorized access, data breaches, and service interruptions.
Static code analysis and vulnerability scanning help you maintain the integrity and security of software applications you develop at the earliest point in the Software Development Life Cycle (SDLC), reducing the work and lowering the cost to test, find, and fix issues found later in the SDLC. Static code analysis identifies issues in the codebase that lead to unstable and unmaintainable software. Vulnerability scanning, also known as Static Application Security Testing (SAST), identifies security weaknesses, which is especially useful as cyber threats become more sophisticated.
That is where SonarCloud comes into play.SonarCloud is a cloud-based solution that offers a comprehensive code quality and security analysis, including automatic analysis, bug detection, security vulnerability detection, and technical debt detection in Java projects and beyond
In this step-by-step guide, you'll learn how to use SonarCloud to continuously scan a project in GitHub using a GitHub Action workflow.
Create an Organization on GitHub
To integrate SonarCloud with GitHub, you must first set up a GitHub Organization.
Log in to your GitHub account (or create a new one). At the top right of the GitHub home page, click on + and select New organization:
Choose Create a free organization:
Name your organization. Pick any name you like. Throughout the rest of this guide, the name demo-github-organization will be used. Simply replace it with the name you chose as you cut and paste from this guide.
Add your contact email and indicate that this organization belongs to your personal account. Verify your account and accept the terms of service:
Click Next to see the new organization page.
Fork a Demo Repository
For the purpose of this tutorial, you'll fork this repository containing the source code of a sample Java application with bugs, vulnerabilities, and bad code. Later in this tutorial, you'll see how SonarCloud finds these issues.
Open the repository in a browser and click Fork:
In the Owner drop-down, choose the GitHub organization you created earlier from the options listed:
Check Copy the main branch only and click Create fork.
Set Up SonarCloud
Next, you'll set up your SonarCloud account and organization and configure SonarCloud to analyze the project repository.
Sign up for a free SonarCloud account using your GitHub account. Authorize SonarCloud to verify your GitHub account when prompted:
On the welcome page, click Import an organization:
On the next screen, you'll see your GitHub organization, which, in this case, is demo-github-organization. Select it:
The next screen asks you to select the repositories on which SonarCloud needs to act. Choose All repositories for this tutorial and click Install:
On the next page, choose the free plan and click Create Organization to create an organization in SonarCloud:
In the Analyze projects screen, you'll see the forked repository. Select it and click Set Up:
In the project setup screen, you must choose what the new code for this project will be based on. Choose Previous version and click Create project:
When prompted to choose the analysis method, select With GitHub Actions since you're integrating SonarCloud analysis with GitHub Actions in this tutorial.
The next screen will show a secret value for the field SONAR_TOKEN.
Note that part of the value in this screenshot was removed for security reasons.
Copy the entire token value since you'll need it to configure the secret in the GitHub repository. Then, navigate to your GitHub repository, click Settings, select Secrets and variables from the side menu, and click Actions.
Click New repository secret and add `SONAR_TOKEN` as your repository secret.
Set Up Build Integration with SonarCloud
Next, you need to define a GitHub Actions workflow YML file to integrate SonarCloud into your build pipeline.
Clone your repository onto your local machine using this command:
git clone https://github.com/demo-github-organization/sample_java_project_with_bugs_vulnerabilities_and_bad_code.git
Switch to the project directory 'sample_java_project_with_bugs_vulnerabilities_and_bad_code', create a new directory named '.github,' and create another directory in this one named 'workflows.' In the 'workflows' directory, create a new file named 'build.yml' and place the content below in it to integrate SonarCloud with the build pipeline:
Next, edit the file build.gradle in the demo project directory to configure your SonarCloud's sonar.organization and sonar.projectKey variables.
Replace the value of sonar.projectKey <demo-github-organization_sample_java_project_with_bugs_vulnerabilities_and_bad_code> with your unique project key. You can get the project key information by navigating to <https://sonarcloud.io/organizations/demo-github-organization/projects_management> in a browser. Remember to replace the 'demo-github-organization' with your organization value. You should see a screen as below:
Replace the value of sonar.organization <demo-github-organization> with your organization key. By default, the organization key is your organization's name.
Stage these changes, then commit and push the changes to your repository using the following commands:
git add .
git commit -am "Integrate SonarCloud with GitHub Actions Workflow"
git push
Go to your repository in a browser and choose the Actions tab. Your workflow will be triggered automatically after a while.
GitHub will generate a runner to execute your action workflow. Depending on the runner's availability on the free plan, it might take a few to several minutes.
Wait for the build to complete.
Examine Analysis Results in SonarCloud
Once the build is successful, head to your SonarCloud account in your browser, where you'll see a screen that displays your GitHub repository with a summary of analysis results.
Click on the demo project's repository link to get an overview page of the project:
Click on the link in the number of issues reported in the main branch:
It will take you to a screen where you can view the list of all issues reported by SonarCloud:
As you can see, SonarCloud analyzed the repository's main branch. SonarCloud reported eleven issues, all in UserController.java, which will take an estimated two hours and eleven minutes to fix. All the issues are listed along with their descriptions. You can click on each issue for more details on the findings.
Fix a Reported Issue
Let's look at one of the reported security issues and fix it by creating a pull request.
To see only the security issues reported, use the left-hand Filters pane and select Security from the Software Quality menu.
Click on the first issue, Revoke and change the password, as it is compromised, for more details.
The root cause of this issue is that the key/secret value is hard-coded in the UserController.java file. If you click How can I fix it?, you will see a compliant solution suggested by SonarCloud. In this case, it tells you to get the secret key value from the system environment.
To develop a fix for this security issue, open a terminal and set the directory to your local cloned repository. Then, create a branch using the command below:
git checkout -b security_fix/get_the_key_from_environment
Open the UserController.java file in your favorite IDE and find the following statement:
private static final String KEY = "ThisIsASecretKey";
Change it to the following:
private static final String KEY = System.getenv("ENCRYPTION_KEY");
A system environment variable ENCRYPTION_KEY will now be used for getting the value for the secret KEY.
Stage these changes, then commit and push the changes to your repository using the following commands in the terminal:
git add .
git commit -am "Security fix to replace hard coded key with system environment"
git push origin security_fix/get_the_key_from_environment
Analyze A Pull Request Using SonarCloud
Head to your GitHub repository in a browser. You'll see a highlighted box that says you have a new branch and a possible pull request to create:
Create a pull request by clicking Compare & pull request and then Create pull request:
The next screen shows details of the pull request. Towards the bottom, you can see that the GitHub Actions workflow for the pull request has started:
After the workflow is successful, you will see the analysis results from SonarCloud showing that there are no new issues reported on the code in the pull request:
Proceed by clicking Merge pull request at the bottom of the screen to merge your changes to the main branch. This action will trigger another workflow execution on the main branch.
Once the workflow action is completed, head to the screen in SonarCloud that shows the reported issues. The total number of issues is now down to ten:
And there's only one security issue left:
You can follow this same process to understand the other issues—whether bugs, code smells, or the other security vulnerability—and address them using SonarCloud.
Conclusion
Congratulations! You now know how to complete a SonarCloud analysis of a Java project stored on GitHub.
As you can see, integrating SonarCloud into your development workflow can help maintain high code quality and ensure the security of your Java applications.
In addition to uncovering bugs and security weaknesses, SonarCloud helps you implement Clean Code principles and realize the benefits of Clean Code early in the development cycle, saving you time and money and improving your security posture.
This guide was written by Rajkumar Venkatasamy at Draft.dev.
- August 5, 2024