What is static analysis?
What is Static Analysis?
Static Analysis is the automated analysis of source code without executing the application.
When the analysis is performed during program execution then it is known as Dynamic Analysis.
Static Analysis is often used to detect:
- Security vulnerabilities.
- Performance issues.
- Non-compliance with standards.
- Use of out of date programming constructs.
How does a Static Analysis tool work?
The basic concept common to all Static Analysis tools is searching source code to identify specific coding patterns that have some sort of warning or information associated with them.
This could be as simple as "JUnit 5 test classes do not need to be 'public'". Or something complex to identify like "Untrusted String input being used in an SQL execution statement".
Static Analysis tools vary in how they implement this functionality.
- source code parsing technology to create an Abstract Syntax Tree (AST),
- text Regular Expression matching,
- a combination of the above.
Regular Expression matching on text is very flexible, easy to write rules to match, but can often lead to a lot of false positives and the matching rules are ignorant of the surrounding code context.
AST matching treats the source code as program code, and not just files filled with text, this allows for more specific, contextual matching and can reduce the number of false positives reported against the code.
Static Analysis in Continuous Integration
Static Analysis is often performed during the Continous Integration (CI) process to generate a report of compliance issues which can be reviewed to receive an objective view of the code-base over time.
Some people use Static Analysis as an objective measure of their code quality by configuring the static analysis tool to only measure specific parts of the code, and only report on a subset of rules.
The objectivity is provided by the rules used since these do not vary in their evaluation of code over time. Clearly, the combination of rules used and their configuration is a subjective decision and different teams choose to use different rules at different times.
Having the Static Analysis performed in CI is useful but might delay the feedback to the programmer. Programmers don't receive feedback when coding, they receive feedback later when the code is run through the Static Analysis tool. Another side-effect of running the Static Analysis in CI is that the results are easier to ignore.
To help make teams pay more attention to the results from Static Analysis it is usually possible to configure a threshold metric in the build process to fail the build if the metric is exceeded e.g. a number of rules triggered.
Static Analysis in the IDE
To receive feedback faster, there are many IDE plugins that run the Static Analysis rules in the IDE on demand, or periodically as the code changes.
The rule violations can then be seen in the IDE as the programmer is writing code, and to make the rules harder to ignore, the violations can often be configured to render as underlined code in the editor.
I personally find this a useful way to improve my coding, particularly when working with a new library that is covered by the Static Analysis tool. Although it can be 'noisy' with false positives, or rules you are not interested in. But this is solved by taking the extra step to configure the Static Analysis tool to ignore certain rules.
Fixing Code Based on Static Analysis Rules
With most Static Analysis tools, the fixing of the rule is left to the programmer, so they have to understand the cause of the rule violation and how to fix it.
Very few static analysis tools also include the ability to fix the violations because the fix is so often contextual to the team and the technology used and their agreed coding styles.
Default Rules
False confidence in the quality of the rules may arise when the Static Analysis tools come with default rules, it is tempting to believe that they cover all the issues that a programmer might encounter, and all the circumstances that rule should apply. Sometimes the circumstances in which a rule should apply can be subtle and may not be easy to detect.
The hope is that by using a Static Analysis tool, and researching the rules and violations in more detail, that programmers will develop the skill to detect and avoid the issue in the context of their specific domain.
When the domain requires contextual rules, the Static Analysis tools may not have any rules that match your domain or library, and additionally, the tools can often be difficult to configure and expand.
Annoyances
None of these 'annoyances' are insurmountable:
- false positives
- lack of fixes
- configuration to ignore rules
- adding context-specific rules
But they are often used as excuses to avoid using Static Analysis tools in the first place, which is a pity because the use of Static Analysis can be enormously useful, as a way to:
- highlight better approaches to junior developers
- gain fast feedback on clear coding violations
- identify obscure issues that the programmer has not encountered before
- reinforce that the programmer has adopted a good coding approach (when no violations are reported)
IDE Based Static Analysis Tools
As an individual contributor to a project, I like to use Static Analysis tools that run from within the IDE so that I receive fast feedback on my code.
This supplements any pull request review process, and CI integration that a project may have.
I try to identify tools that will give me an edge, and improve my individual workflow.
When tools run in the IDE, because they tend to share the same basic GUI and configuration approach, it can be tempting to view them interchangeably.
The tools may have overlapping functionality or rule sets but to gain maximum advantage I install multiple tools to take advantage of their strengths.
The Static Analysis IDE tools I actively use when coding are listed below:
- the inbuilt IntelliJ Inspections - common coding patterns
- SpotBugs - common errors
- SonarLint - common usage patterns
- CheckStyle - common style patterns
- Sensei from Secure Code Warrior - custom rule creation
I use them all because they work well together to augment and supplement each other.
IntelliJ Inspections
If you use IntelliJ then you are already using their Inspections.
These are Static Analysis rules which are flagged in the IDE. Some of them also have QuickFix options to rewrite the code to address the issue.
The rules are configurable on and off, and to choose the error level used to highlight it in the IDE.
There are a lot of good IntelliJ Inspections. I know that because I read through them while writing this. I use the IntelliJ Inspections as the defaults and haven't configured them, but to gain full value from the Inspections you should read through them, identify those relevant to your coding style, and configure the warning level so that you notice them in the code.
The great thing about the IntelliJ Inspections is that they come free with the IDE and they help build the muscle memory of:
- noticing warnings and errors in the source as you write code
- hovering the mouse over flagged code to learn the rule violations
- using alt+enter to apply a QuickFix for the issue
SpotBugs
The SpotBugs IntelliJ plugin uses Static Analysis to try and alert you to bugs in your code.
SpotBugs can be configured from the IntelliJ Preferences to scan your code, the actual rules used can be found in the Detector tab.
I tend to use SpotBugs after I've written and reviewed my code, then I'll run the 'Analyze Project Files Including Test Sources'.
This does help me identify bugs, dead code, and obvious optimizations. It also forces me to research some of the flagged violations to help me decide what to do.
SpotBugs will find issues but does not offer any QuickFix actions to attempt to resolve the issues.
SpotBugs is easy to configure and I find it to be a useful objective second opinion to consult in my IDE.
SonarLint
The SonarLint plugin.
SonarLint can be configured from the IntelliJ Preferences to select which rules the code is validated against.
By default, SonarLint runs in realtime and shows issues for the current code that you are editing.
SonarLint does not offer quick fixes but the documentation associated with the violation reports is usually clear and well documented.
I've found SonarLint to be useful in the past for alerting me to new Java features that I was aware of in the newer versions of Java.
CheckStyle
The CheckStyle plugin offers a mix of formatting and code-quality rules.
The CheckStyle plugin comes bundled with 'Sun Checks' and 'Google Checks'.
The definitions of these can be easily found online.
CheckStyle adds the most value when a project has spent the time creating its own ruleset. Then the IDE plugin can be configured to use that ruleset and programmers can perform a scan, prior to committing the code to CI.
CheckStyle is very often used as a build failing plugin for CI processes when the number of CheckStyle violations exceeds a threshold.
Sensei
Sensei uses Static Analysis based on an Abstract Syntax Tree (AST) for matching code and for creating QuickFixes, this allows for very specific identification of code with issues.
The AST allows QuickFixes associated with a recipe to understand the surrounding code e.g. when adding a new class into the code, any import for that class will only be added to the source file once, and not for each replacement.
Sensei was created to make it easy to build custom matching rules which may not exist, or which would be hard to configure, in other tools.
Rather than amend a configuration file, all the configuration can be performed in the GUI. When creating new recipes the GUI makes it easy to see which code the recipe matches. And when defining the QuickFixes the before and after state of the code can be compared immediately. This makes it easier to create very contextual recipes i.e. unique to teams, or technology, and even individual programmers.
I use Sensei in combination with other Static Analysis tools e.g. most Static Analysis tools will find issues, but not fix them. A common use case for Sensei is to replicate the other tool's matching search in Sensei, and expand it with a Quick Fix. This has the benefit that the custom fix applied already meets the coding standards for your project.
I periodically find myself creating Sensei recipes that already exist in the IntelliJ Intensions set because the Intension report doesn't quite match the context I've created or because the QuickFix provided by IntelliJ doesn't match the code pattern I want to use.
I augment the existing tools, rather than attempt to fully replace them.
Sensei can also be very useful when you identify a contextual variant of a common rule e.g. if you are using an SQL library not supported by the Static Analysis tool, but the common SQL rules in the Static Analysis engine still apply, then you can create library-specific variants of those rules using Sensei.
Sensei does not come out of the box with a lot of generic recipes like the Static Analysis tools mentioned, its strength is in making it easy to create new recipes, complete with QuickFixes configured to match your specific coding style and use-cases.
NOTE: we are working on a public repository of recipes to cover generic use-cases, and you can find it here.
Summary
I tend to pick tools that work together, are configurable, and easy to expand to meet my specific context. I've used Static Analysis tools in the IDE for years to help me identify issues, and learn more about the programming languages and libraries I use.
I use all of the tools mentioned in combination:
- IntelliJ Intentions helps flag common code issues out the box, often with associated QuickFixes.
- SpotBugs finds simple bugs I might have missed and alerts me to performance issues.
- SonarLint identifies Java features I was unaware of and prompts me to additional ways of modelling my code.
- CheckStyle helps me conform to an agreed coding style that is also enforced during CI.
- Sensei helps me create QuickFixes to augment common scenarios found by Static Analysis tools and create specific project or technology recipes that can be hard to configure in another tool.
---
Install Sensei from within IntelliJ using "Preferences \ Plugins" (Mac) or "Settings \ Plugins" (Windows) then just search for "sensei secure code".
You can find a repository of example code and recipes for common use-cases in the Secure Code Warrior GitHub account, in the `sensei-blog-examples` project.
https://github.com/securecodewarrior/sensei-blog-examples
Learn about Static Analysis and how can it help you write better code with examples of 5 IDE based approaches and plugins.
Alan Richardson has more than twenty years of professional IT experience, working as a developer and at every level of the testing hierarchy from Tester through to Head of Testing. Head of Developer Relations at Secure Code Warrior, he works directly with teams, to improve the development of quality secure code. Alan is the author of four books including “Dear Evil Tester”, and “Java For Testers”. Alan has also created online training courses to help people learn Technical Web Testing and Selenium WebDriver with Java. Alan posts his writing and training videos on SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, and CompendiumDev.co.uk.
Secure Code Warrior is here for your organization to help you secure code across the entire software development lifecycle and create a culture in which cybersecurity is top of mind. Whether you’re an AppSec Manager, Developer, CISO, or anyone involved in security, we can help your organization reduce risks associated with insecure code.
Book a demoAlan Richardson has more than twenty years of professional IT experience, working as a developer and at every level of the testing hierarchy from Tester through to Head of Testing. Head of Developer Relations at Secure Code Warrior, he works directly with teams, to improve the development of quality secure code. Alan is the author of four books including “Dear Evil Tester”, and “Java For Testers”. Alan has also created online training courses to help people learn Technical Web Testing and Selenium WebDriver with Java. Alan posts his writing and training videos on SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, and CompendiumDev.co.uk.
What is Static Analysis?
Static Analysis is the automated analysis of source code without executing the application.
When the analysis is performed during program execution then it is known as Dynamic Analysis.
Static Analysis is often used to detect:
- Security vulnerabilities.
- Performance issues.
- Non-compliance with standards.
- Use of out of date programming constructs.
How does a Static Analysis tool work?
The basic concept common to all Static Analysis tools is searching source code to identify specific coding patterns that have some sort of warning or information associated with them.
This could be as simple as "JUnit 5 test classes do not need to be 'public'". Or something complex to identify like "Untrusted String input being used in an SQL execution statement".
Static Analysis tools vary in how they implement this functionality.
- source code parsing technology to create an Abstract Syntax Tree (AST),
- text Regular Expression matching,
- a combination of the above.
Regular Expression matching on text is very flexible, easy to write rules to match, but can often lead to a lot of false positives and the matching rules are ignorant of the surrounding code context.
AST matching treats the source code as program code, and not just files filled with text, this allows for more specific, contextual matching and can reduce the number of false positives reported against the code.
Static Analysis in Continuous Integration
Static Analysis is often performed during the Continous Integration (CI) process to generate a report of compliance issues which can be reviewed to receive an objective view of the code-base over time.
Some people use Static Analysis as an objective measure of their code quality by configuring the static analysis tool to only measure specific parts of the code, and only report on a subset of rules.
The objectivity is provided by the rules used since these do not vary in their evaluation of code over time. Clearly, the combination of rules used and their configuration is a subjective decision and different teams choose to use different rules at different times.
Having the Static Analysis performed in CI is useful but might delay the feedback to the programmer. Programmers don't receive feedback when coding, they receive feedback later when the code is run through the Static Analysis tool. Another side-effect of running the Static Analysis in CI is that the results are easier to ignore.
To help make teams pay more attention to the results from Static Analysis it is usually possible to configure a threshold metric in the build process to fail the build if the metric is exceeded e.g. a number of rules triggered.
Static Analysis in the IDE
To receive feedback faster, there are many IDE plugins that run the Static Analysis rules in the IDE on demand, or periodically as the code changes.
The rule violations can then be seen in the IDE as the programmer is writing code, and to make the rules harder to ignore, the violations can often be configured to render as underlined code in the editor.
I personally find this a useful way to improve my coding, particularly when working with a new library that is covered by the Static Analysis tool. Although it can be 'noisy' with false positives, or rules you are not interested in. But this is solved by taking the extra step to configure the Static Analysis tool to ignore certain rules.
Fixing Code Based on Static Analysis Rules
With most Static Analysis tools, the fixing of the rule is left to the programmer, so they have to understand the cause of the rule violation and how to fix it.
Very few static analysis tools also include the ability to fix the violations because the fix is so often contextual to the team and the technology used and their agreed coding styles.
Default Rules
False confidence in the quality of the rules may arise when the Static Analysis tools come with default rules, it is tempting to believe that they cover all the issues that a programmer might encounter, and all the circumstances that rule should apply. Sometimes the circumstances in which a rule should apply can be subtle and may not be easy to detect.
The hope is that by using a Static Analysis tool, and researching the rules and violations in more detail, that programmers will develop the skill to detect and avoid the issue in the context of their specific domain.
When the domain requires contextual rules, the Static Analysis tools may not have any rules that match your domain or library, and additionally, the tools can often be difficult to configure and expand.
Annoyances
None of these 'annoyances' are insurmountable:
- false positives
- lack of fixes
- configuration to ignore rules
- adding context-specific rules
But they are often used as excuses to avoid using Static Analysis tools in the first place, which is a pity because the use of Static Analysis can be enormously useful, as a way to:
- highlight better approaches to junior developers
- gain fast feedback on clear coding violations
- identify obscure issues that the programmer has not encountered before
- reinforce that the programmer has adopted a good coding approach (when no violations are reported)
IDE Based Static Analysis Tools
As an individual contributor to a project, I like to use Static Analysis tools that run from within the IDE so that I receive fast feedback on my code.
This supplements any pull request review process, and CI integration that a project may have.
I try to identify tools that will give me an edge, and improve my individual workflow.
When tools run in the IDE, because they tend to share the same basic GUI and configuration approach, it can be tempting to view them interchangeably.
The tools may have overlapping functionality or rule sets but to gain maximum advantage I install multiple tools to take advantage of their strengths.
The Static Analysis IDE tools I actively use when coding are listed below:
- the inbuilt IntelliJ Inspections - common coding patterns
- SpotBugs - common errors
- SonarLint - common usage patterns
- CheckStyle - common style patterns
- Sensei from Secure Code Warrior - custom rule creation
I use them all because they work well together to augment and supplement each other.
IntelliJ Inspections
If you use IntelliJ then you are already using their Inspections.
These are Static Analysis rules which are flagged in the IDE. Some of them also have QuickFix options to rewrite the code to address the issue.
The rules are configurable on and off, and to choose the error level used to highlight it in the IDE.
There are a lot of good IntelliJ Inspections. I know that because I read through them while writing this. I use the IntelliJ Inspections as the defaults and haven't configured them, but to gain full value from the Inspections you should read through them, identify those relevant to your coding style, and configure the warning level so that you notice them in the code.
The great thing about the IntelliJ Inspections is that they come free with the IDE and they help build the muscle memory of:
- noticing warnings and errors in the source as you write code
- hovering the mouse over flagged code to learn the rule violations
- using alt+enter to apply a QuickFix for the issue
SpotBugs
The SpotBugs IntelliJ plugin uses Static Analysis to try and alert you to bugs in your code.
SpotBugs can be configured from the IntelliJ Preferences to scan your code, the actual rules used can be found in the Detector tab.
I tend to use SpotBugs after I've written and reviewed my code, then I'll run the 'Analyze Project Files Including Test Sources'.
This does help me identify bugs, dead code, and obvious optimizations. It also forces me to research some of the flagged violations to help me decide what to do.
SpotBugs will find issues but does not offer any QuickFix actions to attempt to resolve the issues.
SpotBugs is easy to configure and I find it to be a useful objective second opinion to consult in my IDE.
SonarLint
The SonarLint plugin.
SonarLint can be configured from the IntelliJ Preferences to select which rules the code is validated against.
By default, SonarLint runs in realtime and shows issues for the current code that you are editing.
SonarLint does not offer quick fixes but the documentation associated with the violation reports is usually clear and well documented.
I've found SonarLint to be useful in the past for alerting me to new Java features that I was aware of in the newer versions of Java.
CheckStyle
The CheckStyle plugin offers a mix of formatting and code-quality rules.
The CheckStyle plugin comes bundled with 'Sun Checks' and 'Google Checks'.
The definitions of these can be easily found online.
CheckStyle adds the most value when a project has spent the time creating its own ruleset. Then the IDE plugin can be configured to use that ruleset and programmers can perform a scan, prior to committing the code to CI.
CheckStyle is very often used as a build failing plugin for CI processes when the number of CheckStyle violations exceeds a threshold.
Sensei
Sensei uses Static Analysis based on an Abstract Syntax Tree (AST) for matching code and for creating QuickFixes, this allows for very specific identification of code with issues.
The AST allows QuickFixes associated with a recipe to understand the surrounding code e.g. when adding a new class into the code, any import for that class will only be added to the source file once, and not for each replacement.
Sensei was created to make it easy to build custom matching rules which may not exist, or which would be hard to configure, in other tools.
Rather than amend a configuration file, all the configuration can be performed in the GUI. When creating new recipes the GUI makes it easy to see which code the recipe matches. And when defining the QuickFixes the before and after state of the code can be compared immediately. This makes it easier to create very contextual recipes i.e. unique to teams, or technology, and even individual programmers.
I use Sensei in combination with other Static Analysis tools e.g. most Static Analysis tools will find issues, but not fix them. A common use case for Sensei is to replicate the other tool's matching search in Sensei, and expand it with a Quick Fix. This has the benefit that the custom fix applied already meets the coding standards for your project.
I periodically find myself creating Sensei recipes that already exist in the IntelliJ Intensions set because the Intension report doesn't quite match the context I've created or because the QuickFix provided by IntelliJ doesn't match the code pattern I want to use.
I augment the existing tools, rather than attempt to fully replace them.
Sensei can also be very useful when you identify a contextual variant of a common rule e.g. if you are using an SQL library not supported by the Static Analysis tool, but the common SQL rules in the Static Analysis engine still apply, then you can create library-specific variants of those rules using Sensei.
Sensei does not come out of the box with a lot of generic recipes like the Static Analysis tools mentioned, its strength is in making it easy to create new recipes, complete with QuickFixes configured to match your specific coding style and use-cases.
NOTE: we are working on a public repository of recipes to cover generic use-cases, and you can find it here.
Summary
I tend to pick tools that work together, are configurable, and easy to expand to meet my specific context. I've used Static Analysis tools in the IDE for years to help me identify issues, and learn more about the programming languages and libraries I use.
I use all of the tools mentioned in combination:
- IntelliJ Intentions helps flag common code issues out the box, often with associated QuickFixes.
- SpotBugs finds simple bugs I might have missed and alerts me to performance issues.
- SonarLint identifies Java features I was unaware of and prompts me to additional ways of modelling my code.
- CheckStyle helps me conform to an agreed coding style that is also enforced during CI.
- Sensei helps me create QuickFixes to augment common scenarios found by Static Analysis tools and create specific project or technology recipes that can be hard to configure in another tool.
---
Install Sensei from within IntelliJ using "Preferences \ Plugins" (Mac) or "Settings \ Plugins" (Windows) then just search for "sensei secure code".
You can find a repository of example code and recipes for common use-cases in the Secure Code Warrior GitHub account, in the `sensei-blog-examples` project.
https://github.com/securecodewarrior/sensei-blog-examples
What is Static Analysis?
Static Analysis is the automated analysis of source code without executing the application.
When the analysis is performed during program execution then it is known as Dynamic Analysis.
Static Analysis is often used to detect:
- Security vulnerabilities.
- Performance issues.
- Non-compliance with standards.
- Use of out of date programming constructs.
How does a Static Analysis tool work?
The basic concept common to all Static Analysis tools is searching source code to identify specific coding patterns that have some sort of warning or information associated with them.
This could be as simple as "JUnit 5 test classes do not need to be 'public'". Or something complex to identify like "Untrusted String input being used in an SQL execution statement".
Static Analysis tools vary in how they implement this functionality.
- source code parsing technology to create an Abstract Syntax Tree (AST),
- text Regular Expression matching,
- a combination of the above.
Regular Expression matching on text is very flexible, easy to write rules to match, but can often lead to a lot of false positives and the matching rules are ignorant of the surrounding code context.
AST matching treats the source code as program code, and not just files filled with text, this allows for more specific, contextual matching and can reduce the number of false positives reported against the code.
Static Analysis in Continuous Integration
Static Analysis is often performed during the Continous Integration (CI) process to generate a report of compliance issues which can be reviewed to receive an objective view of the code-base over time.
Some people use Static Analysis as an objective measure of their code quality by configuring the static analysis tool to only measure specific parts of the code, and only report on a subset of rules.
The objectivity is provided by the rules used since these do not vary in their evaluation of code over time. Clearly, the combination of rules used and their configuration is a subjective decision and different teams choose to use different rules at different times.
Having the Static Analysis performed in CI is useful but might delay the feedback to the programmer. Programmers don't receive feedback when coding, they receive feedback later when the code is run through the Static Analysis tool. Another side-effect of running the Static Analysis in CI is that the results are easier to ignore.
To help make teams pay more attention to the results from Static Analysis it is usually possible to configure a threshold metric in the build process to fail the build if the metric is exceeded e.g. a number of rules triggered.
Static Analysis in the IDE
To receive feedback faster, there are many IDE plugins that run the Static Analysis rules in the IDE on demand, or periodically as the code changes.
The rule violations can then be seen in the IDE as the programmer is writing code, and to make the rules harder to ignore, the violations can often be configured to render as underlined code in the editor.
I personally find this a useful way to improve my coding, particularly when working with a new library that is covered by the Static Analysis tool. Although it can be 'noisy' with false positives, or rules you are not interested in. But this is solved by taking the extra step to configure the Static Analysis tool to ignore certain rules.
Fixing Code Based on Static Analysis Rules
With most Static Analysis tools, the fixing of the rule is left to the programmer, so they have to understand the cause of the rule violation and how to fix it.
Very few static analysis tools also include the ability to fix the violations because the fix is so often contextual to the team and the technology used and their agreed coding styles.
Default Rules
False confidence in the quality of the rules may arise when the Static Analysis tools come with default rules, it is tempting to believe that they cover all the issues that a programmer might encounter, and all the circumstances that rule should apply. Sometimes the circumstances in which a rule should apply can be subtle and may not be easy to detect.
The hope is that by using a Static Analysis tool, and researching the rules and violations in more detail, that programmers will develop the skill to detect and avoid the issue in the context of their specific domain.
When the domain requires contextual rules, the Static Analysis tools may not have any rules that match your domain or library, and additionally, the tools can often be difficult to configure and expand.
Annoyances
None of these 'annoyances' are insurmountable:
- false positives
- lack of fixes
- configuration to ignore rules
- adding context-specific rules
But they are often used as excuses to avoid using Static Analysis tools in the first place, which is a pity because the use of Static Analysis can be enormously useful, as a way to:
- highlight better approaches to junior developers
- gain fast feedback on clear coding violations
- identify obscure issues that the programmer has not encountered before
- reinforce that the programmer has adopted a good coding approach (when no violations are reported)
IDE Based Static Analysis Tools
As an individual contributor to a project, I like to use Static Analysis tools that run from within the IDE so that I receive fast feedback on my code.
This supplements any pull request review process, and CI integration that a project may have.
I try to identify tools that will give me an edge, and improve my individual workflow.
When tools run in the IDE, because they tend to share the same basic GUI and configuration approach, it can be tempting to view them interchangeably.
The tools may have overlapping functionality or rule sets but to gain maximum advantage I install multiple tools to take advantage of their strengths.
The Static Analysis IDE tools I actively use when coding are listed below:
- the inbuilt IntelliJ Inspections - common coding patterns
- SpotBugs - common errors
- SonarLint - common usage patterns
- CheckStyle - common style patterns
- Sensei from Secure Code Warrior - custom rule creation
I use them all because they work well together to augment and supplement each other.
IntelliJ Inspections
If you use IntelliJ then you are already using their Inspections.
These are Static Analysis rules which are flagged in the IDE. Some of them also have QuickFix options to rewrite the code to address the issue.
The rules are configurable on and off, and to choose the error level used to highlight it in the IDE.
There are a lot of good IntelliJ Inspections. I know that because I read through them while writing this. I use the IntelliJ Inspections as the defaults and haven't configured them, but to gain full value from the Inspections you should read through them, identify those relevant to your coding style, and configure the warning level so that you notice them in the code.
The great thing about the IntelliJ Inspections is that they come free with the IDE and they help build the muscle memory of:
- noticing warnings and errors in the source as you write code
- hovering the mouse over flagged code to learn the rule violations
- using alt+enter to apply a QuickFix for the issue
SpotBugs
The SpotBugs IntelliJ plugin uses Static Analysis to try and alert you to bugs in your code.
SpotBugs can be configured from the IntelliJ Preferences to scan your code, the actual rules used can be found in the Detector tab.
I tend to use SpotBugs after I've written and reviewed my code, then I'll run the 'Analyze Project Files Including Test Sources'.
This does help me identify bugs, dead code, and obvious optimizations. It also forces me to research some of the flagged violations to help me decide what to do.
SpotBugs will find issues but does not offer any QuickFix actions to attempt to resolve the issues.
SpotBugs is easy to configure and I find it to be a useful objective second opinion to consult in my IDE.
SonarLint
The SonarLint plugin.
SonarLint can be configured from the IntelliJ Preferences to select which rules the code is validated against.
By default, SonarLint runs in realtime and shows issues for the current code that you are editing.
SonarLint does not offer quick fixes but the documentation associated with the violation reports is usually clear and well documented.
I've found SonarLint to be useful in the past for alerting me to new Java features that I was aware of in the newer versions of Java.
CheckStyle
The CheckStyle plugin offers a mix of formatting and code-quality rules.
The CheckStyle plugin comes bundled with 'Sun Checks' and 'Google Checks'.
The definitions of these can be easily found online.
CheckStyle adds the most value when a project has spent the time creating its own ruleset. Then the IDE plugin can be configured to use that ruleset and programmers can perform a scan, prior to committing the code to CI.
CheckStyle is very often used as a build failing plugin for CI processes when the number of CheckStyle violations exceeds a threshold.
Sensei
Sensei uses Static Analysis based on an Abstract Syntax Tree (AST) for matching code and for creating QuickFixes, this allows for very specific identification of code with issues.
The AST allows QuickFixes associated with a recipe to understand the surrounding code e.g. when adding a new class into the code, any import for that class will only be added to the source file once, and not for each replacement.
Sensei was created to make it easy to build custom matching rules which may not exist, or which would be hard to configure, in other tools.
Rather than amend a configuration file, all the configuration can be performed in the GUI. When creating new recipes the GUI makes it easy to see which code the recipe matches. And when defining the QuickFixes the before and after state of the code can be compared immediately. This makes it easier to create very contextual recipes i.e. unique to teams, or technology, and even individual programmers.
I use Sensei in combination with other Static Analysis tools e.g. most Static Analysis tools will find issues, but not fix them. A common use case for Sensei is to replicate the other tool's matching search in Sensei, and expand it with a Quick Fix. This has the benefit that the custom fix applied already meets the coding standards for your project.
I periodically find myself creating Sensei recipes that already exist in the IntelliJ Intensions set because the Intension report doesn't quite match the context I've created or because the QuickFix provided by IntelliJ doesn't match the code pattern I want to use.
I augment the existing tools, rather than attempt to fully replace them.
Sensei can also be very useful when you identify a contextual variant of a common rule e.g. if you are using an SQL library not supported by the Static Analysis tool, but the common SQL rules in the Static Analysis engine still apply, then you can create library-specific variants of those rules using Sensei.
Sensei does not come out of the box with a lot of generic recipes like the Static Analysis tools mentioned, its strength is in making it easy to create new recipes, complete with QuickFixes configured to match your specific coding style and use-cases.
NOTE: we are working on a public repository of recipes to cover generic use-cases, and you can find it here.
Summary
I tend to pick tools that work together, are configurable, and easy to expand to meet my specific context. I've used Static Analysis tools in the IDE for years to help me identify issues, and learn more about the programming languages and libraries I use.
I use all of the tools mentioned in combination:
- IntelliJ Intentions helps flag common code issues out the box, often with associated QuickFixes.
- SpotBugs finds simple bugs I might have missed and alerts me to performance issues.
- SonarLint identifies Java features I was unaware of and prompts me to additional ways of modelling my code.
- CheckStyle helps me conform to an agreed coding style that is also enforced during CI.
- Sensei helps me create QuickFixes to augment common scenarios found by Static Analysis tools and create specific project or technology recipes that can be hard to configure in another tool.
---
Install Sensei from within IntelliJ using "Preferences \ Plugins" (Mac) or "Settings \ Plugins" (Windows) then just search for "sensei secure code".
You can find a repository of example code and recipes for common use-cases in the Secure Code Warrior GitHub account, in the `sensei-blog-examples` project.
https://github.com/securecodewarrior/sensei-blog-examples
Click on the link below and download the PDF of this resource.
Secure Code Warrior is here for your organization to help you secure code across the entire software development lifecycle and create a culture in which cybersecurity is top of mind. Whether you’re an AppSec Manager, Developer, CISO, or anyone involved in security, we can help your organization reduce risks associated with insecure code.
View reportBook a demoAlan Richardson has more than twenty years of professional IT experience, working as a developer and at every level of the testing hierarchy from Tester through to Head of Testing. Head of Developer Relations at Secure Code Warrior, he works directly with teams, to improve the development of quality secure code. Alan is the author of four books including “Dear Evil Tester”, and “Java For Testers”. Alan has also created online training courses to help people learn Technical Web Testing and Selenium WebDriver with Java. Alan posts his writing and training videos on SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, and CompendiumDev.co.uk.
What is Static Analysis?
Static Analysis is the automated analysis of source code without executing the application.
When the analysis is performed during program execution then it is known as Dynamic Analysis.
Static Analysis is often used to detect:
- Security vulnerabilities.
- Performance issues.
- Non-compliance with standards.
- Use of out of date programming constructs.
How does a Static Analysis tool work?
The basic concept common to all Static Analysis tools is searching source code to identify specific coding patterns that have some sort of warning or information associated with them.
This could be as simple as "JUnit 5 test classes do not need to be 'public'". Or something complex to identify like "Untrusted String input being used in an SQL execution statement".
Static Analysis tools vary in how they implement this functionality.
- source code parsing technology to create an Abstract Syntax Tree (AST),
- text Regular Expression matching,
- a combination of the above.
Regular Expression matching on text is very flexible, easy to write rules to match, but can often lead to a lot of false positives and the matching rules are ignorant of the surrounding code context.
AST matching treats the source code as program code, and not just files filled with text, this allows for more specific, contextual matching and can reduce the number of false positives reported against the code.
Static Analysis in Continuous Integration
Static Analysis is often performed during the Continous Integration (CI) process to generate a report of compliance issues which can be reviewed to receive an objective view of the code-base over time.
Some people use Static Analysis as an objective measure of their code quality by configuring the static analysis tool to only measure specific parts of the code, and only report on a subset of rules.
The objectivity is provided by the rules used since these do not vary in their evaluation of code over time. Clearly, the combination of rules used and their configuration is a subjective decision and different teams choose to use different rules at different times.
Having the Static Analysis performed in CI is useful but might delay the feedback to the programmer. Programmers don't receive feedback when coding, they receive feedback later when the code is run through the Static Analysis tool. Another side-effect of running the Static Analysis in CI is that the results are easier to ignore.
To help make teams pay more attention to the results from Static Analysis it is usually possible to configure a threshold metric in the build process to fail the build if the metric is exceeded e.g. a number of rules triggered.
Static Analysis in the IDE
To receive feedback faster, there are many IDE plugins that run the Static Analysis rules in the IDE on demand, or periodically as the code changes.
The rule violations can then be seen in the IDE as the programmer is writing code, and to make the rules harder to ignore, the violations can often be configured to render as underlined code in the editor.
I personally find this a useful way to improve my coding, particularly when working with a new library that is covered by the Static Analysis tool. Although it can be 'noisy' with false positives, or rules you are not interested in. But this is solved by taking the extra step to configure the Static Analysis tool to ignore certain rules.
Fixing Code Based on Static Analysis Rules
With most Static Analysis tools, the fixing of the rule is left to the programmer, so they have to understand the cause of the rule violation and how to fix it.
Very few static analysis tools also include the ability to fix the violations because the fix is so often contextual to the team and the technology used and their agreed coding styles.
Default Rules
False confidence in the quality of the rules may arise when the Static Analysis tools come with default rules, it is tempting to believe that they cover all the issues that a programmer might encounter, and all the circumstances that rule should apply. Sometimes the circumstances in which a rule should apply can be subtle and may not be easy to detect.
The hope is that by using a Static Analysis tool, and researching the rules and violations in more detail, that programmers will develop the skill to detect and avoid the issue in the context of their specific domain.
When the domain requires contextual rules, the Static Analysis tools may not have any rules that match your domain or library, and additionally, the tools can often be difficult to configure and expand.
Annoyances
None of these 'annoyances' are insurmountable:
- false positives
- lack of fixes
- configuration to ignore rules
- adding context-specific rules
But they are often used as excuses to avoid using Static Analysis tools in the first place, which is a pity because the use of Static Analysis can be enormously useful, as a way to:
- highlight better approaches to junior developers
- gain fast feedback on clear coding violations
- identify obscure issues that the programmer has not encountered before
- reinforce that the programmer has adopted a good coding approach (when no violations are reported)
IDE Based Static Analysis Tools
As an individual contributor to a project, I like to use Static Analysis tools that run from within the IDE so that I receive fast feedback on my code.
This supplements any pull request review process, and CI integration that a project may have.
I try to identify tools that will give me an edge, and improve my individual workflow.
When tools run in the IDE, because they tend to share the same basic GUI and configuration approach, it can be tempting to view them interchangeably.
The tools may have overlapping functionality or rule sets but to gain maximum advantage I install multiple tools to take advantage of their strengths.
The Static Analysis IDE tools I actively use when coding are listed below:
- the inbuilt IntelliJ Inspections - common coding patterns
- SpotBugs - common errors
- SonarLint - common usage patterns
- CheckStyle - common style patterns
- Sensei from Secure Code Warrior - custom rule creation
I use them all because they work well together to augment and supplement each other.
IntelliJ Inspections
If you use IntelliJ then you are already using their Inspections.
These are Static Analysis rules which are flagged in the IDE. Some of them also have QuickFix options to rewrite the code to address the issue.
The rules are configurable on and off, and to choose the error level used to highlight it in the IDE.
There are a lot of good IntelliJ Inspections. I know that because I read through them while writing this. I use the IntelliJ Inspections as the defaults and haven't configured them, but to gain full value from the Inspections you should read through them, identify those relevant to your coding style, and configure the warning level so that you notice them in the code.
The great thing about the IntelliJ Inspections is that they come free with the IDE and they help build the muscle memory of:
- noticing warnings and errors in the source as you write code
- hovering the mouse over flagged code to learn the rule violations
- using alt+enter to apply a QuickFix for the issue
SpotBugs
The SpotBugs IntelliJ plugin uses Static Analysis to try and alert you to bugs in your code.
SpotBugs can be configured from the IntelliJ Preferences to scan your code, the actual rules used can be found in the Detector tab.
I tend to use SpotBugs after I've written and reviewed my code, then I'll run the 'Analyze Project Files Including Test Sources'.
This does help me identify bugs, dead code, and obvious optimizations. It also forces me to research some of the flagged violations to help me decide what to do.
SpotBugs will find issues but does not offer any QuickFix actions to attempt to resolve the issues.
SpotBugs is easy to configure and I find it to be a useful objective second opinion to consult in my IDE.
SonarLint
The SonarLint plugin.
SonarLint can be configured from the IntelliJ Preferences to select which rules the code is validated against.
By default, SonarLint runs in realtime and shows issues for the current code that you are editing.
SonarLint does not offer quick fixes but the documentation associated with the violation reports is usually clear and well documented.
I've found SonarLint to be useful in the past for alerting me to new Java features that I was aware of in the newer versions of Java.
CheckStyle
The CheckStyle plugin offers a mix of formatting and code-quality rules.
The CheckStyle plugin comes bundled with 'Sun Checks' and 'Google Checks'.
The definitions of these can be easily found online.
CheckStyle adds the most value when a project has spent the time creating its own ruleset. Then the IDE plugin can be configured to use that ruleset and programmers can perform a scan, prior to committing the code to CI.
CheckStyle is very often used as a build failing plugin for CI processes when the number of CheckStyle violations exceeds a threshold.
Sensei
Sensei uses Static Analysis based on an Abstract Syntax Tree (AST) for matching code and for creating QuickFixes, this allows for very specific identification of code with issues.
The AST allows QuickFixes associated with a recipe to understand the surrounding code e.g. when adding a new class into the code, any import for that class will only be added to the source file once, and not for each replacement.
Sensei was created to make it easy to build custom matching rules which may not exist, or which would be hard to configure, in other tools.
Rather than amend a configuration file, all the configuration can be performed in the GUI. When creating new recipes the GUI makes it easy to see which code the recipe matches. And when defining the QuickFixes the before and after state of the code can be compared immediately. This makes it easier to create very contextual recipes i.e. unique to teams, or technology, and even individual programmers.
I use Sensei in combination with other Static Analysis tools e.g. most Static Analysis tools will find issues, but not fix them. A common use case for Sensei is to replicate the other tool's matching search in Sensei, and expand it with a Quick Fix. This has the benefit that the custom fix applied already meets the coding standards for your project.
I periodically find myself creating Sensei recipes that already exist in the IntelliJ Intensions set because the Intension report doesn't quite match the context I've created or because the QuickFix provided by IntelliJ doesn't match the code pattern I want to use.
I augment the existing tools, rather than attempt to fully replace them.
Sensei can also be very useful when you identify a contextual variant of a common rule e.g. if you are using an SQL library not supported by the Static Analysis tool, but the common SQL rules in the Static Analysis engine still apply, then you can create library-specific variants of those rules using Sensei.
Sensei does not come out of the box with a lot of generic recipes like the Static Analysis tools mentioned, its strength is in making it easy to create new recipes, complete with QuickFixes configured to match your specific coding style and use-cases.
NOTE: we are working on a public repository of recipes to cover generic use-cases, and you can find it here.
Summary
I tend to pick tools that work together, are configurable, and easy to expand to meet my specific context. I've used Static Analysis tools in the IDE for years to help me identify issues, and learn more about the programming languages and libraries I use.
I use all of the tools mentioned in combination:
- IntelliJ Intentions helps flag common code issues out the box, often with associated QuickFixes.
- SpotBugs finds simple bugs I might have missed and alerts me to performance issues.
- SonarLint identifies Java features I was unaware of and prompts me to additional ways of modelling my code.
- CheckStyle helps me conform to an agreed coding style that is also enforced during CI.
- Sensei helps me create QuickFixes to augment common scenarios found by Static Analysis tools and create specific project or technology recipes that can be hard to configure in another tool.
---
Install Sensei from within IntelliJ using "Preferences \ Plugins" (Mac) or "Settings \ Plugins" (Windows) then just search for "sensei secure code".
You can find a repository of example code and recipes for common use-cases in the Secure Code Warrior GitHub account, in the `sensei-blog-examples` project.
https://github.com/securecodewarrior/sensei-blog-examples
Table of contents
Alan Richardson has more than twenty years of professional IT experience, working as a developer and at every level of the testing hierarchy from Tester through to Head of Testing. Head of Developer Relations at Secure Code Warrior, he works directly with teams, to improve the development of quality secure code. Alan is the author of four books including “Dear Evil Tester”, and “Java For Testers”. Alan has also created online training courses to help people learn Technical Web Testing and Selenium WebDriver with Java. Alan posts his writing and training videos on SeleniumSimplified.com, EvilTester.com, JavaForTesters.com, and CompendiumDev.co.uk.
Secure Code Warrior is here for your organization to help you secure code across the entire software development lifecycle and create a culture in which cybersecurity is top of mind. Whether you’re an AppSec Manager, Developer, CISO, or anyone involved in security, we can help your organization reduce risks associated with insecure code.
Book a demoDownloadResources to get you started
Benchmarking Security Skills: Streamlining Secure-by-Design in the Enterprise
The Secure-by-Design movement is the future of secure software development. Learn about the key elements companies need to keep in mind when they think about a Secure-by-Design initiative.
DigitalOcean Decreases Security Debt with Secure Code Warrior
DigitalOcean's use of Secure Code Warrior training has significantly reduced security debt, allowing teams to focus more on innovation and productivity. The improved security has strengthened their product quality and competitive edge. Looking ahead, the SCW Trust Score will help them further enhance security practices and continue driving innovation.
Resources to get you started
OWASP Top 10 For LLM Applications: What’s New, Changed, and How to Stay Secure
Stay ahead in securing LLM applications with the latest OWASP Top 10 updates. Discover what's new, what’s changed, and how Secure Code Warrior equips you with up-to-date learning resources to mitigate risks in Generative AI.
Trust Score Reveals the Value of Secure-by-Design Upskilling Initiatives
Our research has shown that secure code training works. Trust Score, using an algorithm drawing on more than 20 million learning data points from work by more than 250,000 learners at over 600 organizations, reveals its effectiveness in driving down vulnerabilities and how to make the initiative even more effective.
Reactive Versus Preventive Security: Prevention Is a Better Cure
The idea of bringing preventive security to legacy code and systems at the same time as newer applications can seem daunting, but a Secure-by-Design approach, enforced by upskilling developers, can apply security best practices to those systems. It’s the best chance many organizations have of improving their security postures.
The Benefits of Benchmarking Security Skills for Developers
The growing focus on secure code and Secure-by-Design principles requires developers to be trained in cybersecurity from the start of the SDLC, with tools like Secure Code Warrior’s Trust Score helping measure and improve their progress.