Since ChatGPT hit the world stage, generative AI (GenAI) and its applications have popped up in virtually every sector.
Yet, few have managed to create as sustained and quantifiable an impact as code generation tools for software developers.
With the help of AI coding assistants, developers are seeing enhanced productivity and reduced time spent on routine and common coding tasks.
Among the most widely adopted assistants today is Amazon Q, a state-of-the-art tool that integrates directly into your IDE.
It generates, tests, and debugs code using advanced reasoning and multistep planning.
Amazon Q even allows for integration with enterprise data, thus enabling the developer to generate documentation, discover insights, and summarize data.
Ensuring the Quality of AI-Generated Code
Although the potential productivity gains of using AI pair programming are massive, developers must perform the requisite checks to ensure quality AI-generated code. Tools like Amazon Q have been trained on billions of lines of publicly available code, varying widely in quality and vulnerability.
If you’re a user of code-generating AI tools, you cannot take the generated code at face value.
When using Amazon Q to produce critical, production-grade code, you have good reason to check your code carefully.
First, Amazon Q tends to index on code standards and styles that it has been trained on.
These standards may not necessarily align with the standards set internally at your company.
Second (and perhaps more obviously), you must be proactive about preventing the introduction of errors or vulnerabilities in AI-suggested code.
Yes, AI-suggested code can have security flaws.
In many cases, the code generated by Amazon Q may “just work” but may introduce subtle edge cases that can become a problem in production.
AI assistance is attractive because it saves time.
Why should a developer lose that saved time manually checking the AI-generated code for security flaws?
A better solution is to leverage reliable, robust, and secure tools—tools that can analyze your code to sniff out security issues.
Linters and static code analysis tools continuously evaluate your code and flag issues/errors during development itself (before compilation or interpretation).
In this post, we’ll look at how tools like SonarLint and SonarQube can boost code quality and security by supplementing your use of Amazon Q within a Java development context.
Let’s dive in, starting with how to set up our tools within Visual Studio Code (VSCode).
VSCode is the go-to editor for software developers today. You can download VSCode for free.
Setting Up Amazon Q in VSCode
With VSCode open, we visit the Visual Studio Extension marketplace to download the Amazon Q extension.
Amazon Q has a free tier that you can use with an AWS Builder ID.
Once you’ve signed in, you can interact with Amazon Q in various ways, including:
- Code auto-completion as you write code.
- Triggered checks for minor security vulnerabilities, such as secret keys being exposed in a committed file.
- Chatting with Amazon Q to write new code or transform existing code (for example, from one version of the language to another).
Setting Up SonarLint in VSCode
With Amazon Q installed, let’s now move on to installing the SonarLint extension. As the name suggests, SonarLint is a free advanced linting tool that is capable of the following:
- Giving real-time feedback on AI-generated code in a non-intrusive manner. SonarLint can detect common coding mistakes, tricky bugs, and security hotspots.
- Providing contextual assistance (unlike many linting tools) on how to fix outstanding issues, why the issue is something worth fixing, and the risks involved with ignoring the issue.
- Guiding developer education via SonarLint. With continuous usage of SonarLint, developers become more aware of the vulnerabilities they will face in production.
Just as with Amazon Q, the SonarLint extension is easy to download and install through the Visual Studio Extension marketplace.
By default, SonarLint analyzes the code present in the files currently open in the IDE.
While very useful, SonarLint’s true capabilities are unlocked when it’s integrated with SonarCloud or SonarQube.
This integration ensures code quality checks that enrich the CI/CD pipeline, ensuring any new code (both edits and additions) is clean across the entire project.
Amazon Q and SonarLint Working Together
Let’s see SonarLint in action. With the help of Amazon Q, we’ve written a simple HelloWorld program in Java. Of course, this code is simply for demonstration purposes. It’s not something we would use in production.
SonarLint immediately flags the issues it sees.
For example, SonarLint recommends using a logger instead of a System.out. Loggers are preferable because they are easily accessible, uniformly formatted, properly recorded, and capture logs securely, even when dealing with sensitive data.
Hovering over the recommendation opens a tab with a detailed explanation on why this is an issue and quick fixes that are possible.
Working with SonarQube
By itself, SonarLint is an excellent tool for small projects with a handful of files. However, if you’re working on critical production code and need deeper analysis, it makes sense to run SonarLint alongside SonarQube in connected mode.
SonarQube performs static code analysis and offers the following advantages:
- Sharing of team decisions on quality profiles, project settings, and rule descriptions.
- Smart notifications that are triggered whenever a new issue is discovered, improving overall software quality and delivery.
- Seamless integration with SonarLint so you can address issues with it directly in your IDE.
- Ability to concentrate only on new code.
- Ability to detect over 140 types of secrets across 81 different cloud services.
- Tackling other advanced issues in the IDE such as data flow bugs and taint vulnerabilities.
Setting Up SonarQube
SonarQube offers a 14-day free trial on both its Developer and Enterprise editions with a work email (no credit card required).
You can also download a Community edition to get started with the tool. For this demo, we’ll use the Community edition.
Once you’ve downloaded the Community edition, follow the instructions to unzip the folder and spin up an instance of SonarQube.
- Ensure Java 17 is installed on your local machine.
- Unzip the folder in C:\sonarqube (Windows) or /opt/sonarqube (Mac and Linux).
- Start the server by running the following:
Once the server has been spun up, navigate to localhost:9000 in your browser.
You’ll see a login form.
Enter admin for both the username and password, and you will see a screen that asks you to create a new project—either locally or through a platform like GitHub or Bitbucket.
For this demo, we’ll proceed with creating a local project.
Choose any name or project key (we’ll use SonarQube for this demo). In the next window, use the default global settings.
Once you’ve created a project, you will be asked to choose an analysis method.
For this, we’ll choose the Locally option.
In order to run SonarQube on our local project, we need to generate a token that identifies our project to SonarQube. We generate the token and copy it.
Running SonarQube
Now, we’re ready to run SonarQube on our project!
As you build out your Java projects—and as you use Amazon Q to help you by generating code—analyzing the code with SonarQube will help you catch security issues that you may not be aware of.
To demonstrate SonarQube, we’ve cloned a Java project with some security issues in it.
Next, we run SonarQube using the following Maven command (as instructed in the SonarQube dashboard).
This automatically triggers an analysis of our entire codebase. Soon after, we see the results in our SonarQube web UI.
SonarQube has identified several security, reliability, and maintainability issues.
We can click each issue to take a deeper look. We can then go back to our code in the IDE and look at fixes using SonarLint.
For example, SonarQube is exceptional at finding compromised passwords.
SonarQube also finds more nuanced security issues.
For example, it examines our use of HttpServletRequest, correctly deducing that the highlighted function uses a session ID that is supplied by the client.
Because of this, the ID may not be valid or might even be spoofed.
Deeper SAST
SonarQube and SonarCloud also have a feature called deeper SAST which allows them to identify taint vulnerabilities such as SQL injections or deserialization in external libraries.
These vulnerabilities can be extremely hard for a developer to spot as the threat takes shape across multiple files.
To demonstrate the capabilities of deeper SAST, we analyzed code from another Java project with security vulnerabilities.
We wanted to look more carefully at the code from this pull request.
In the code for UserController.java, there’s a call to setSavepoint, which comes from an external library, com.mysql.cj.jdbc.ConnectionImpl.
When we analyze the code with Deeper SAST from SonarQube, we’re shown the following security issue:
Sonar alerts us to the vulnerability here, that the third-party setSavepoint library function is vulnerable to an SQL injection if you supply a user-controlled argument.
Since the username value comes from a request parameter which a malicious user could manipulate, we’re fortunate that Sonar’s deeper SAST catches this for us.
Even when code is AI-generated from Amazon Q, the likelihood of introducing vulnerabilities such as these is significant.
AI code-generation tools will import and use third-party libraries— especially if you’re already using them in your project—so you need robust security analysis to ensure that this usage is safe.
Advanced Security Analysis with Sonar
Enhance your code's security and quality with Sonar’s suite of tools. By combining Amazon Q, SonarLint, and SonarQube, developers can significantly boost productivity with AI assistance while ensuring their code remains secure and stable.
Sonar's comprehensive analysis goes beyond surface-level checks, addressing critical vulnerabilities like taint analysis, and providing deep static analysis for production-grade code.
SonarQube
SonarQube is essential for maintaining high-quality, secure code in production environments. It offers thorough static analysis to detect and resolve complex issues throughout your codebase. Integrating seamlessly into your CI/CD pipeline, SonarQube enforces best practices and keeps your code free from vulnerabilities, even in AI-assisted projects.
SonarCloud
For cloud-based development, SonarCloud is the ultimate tool to ensure code quality and security in collaborative settings. Seamlessly integrated with cloud CI/CD pipelines, it helps teams detect and address issues early, ensuring AI-generated code is reliable, maintainable, and secure.
SonarLint
SonarLint is your in-IDE tool for instant code quality feedback. It helps you catch and fix issues in real-time as you code, whether you're working with Amazon Q or writing from scratch. With SonarLint, ensure your code is clean, reliable, and secure.