CLI tool
david-a-wheeler/flawfinder avatar
david-a-wheeler/flawfinder

flawfinder: lexical vulnerability scanning for C and C++

a static analysis tool for finding vulnerabilities in C/C++ source code

588 stars89 forksPythonGPL-2.0

At a glance

What is it?
flawfinder is a Python static analysis tool that scans C and C++ source for potential security flaws by matching tokens, not by following control flow, which means it finds problems in code you cannot even build and it also produces false positives. The README is blunt about both, and that bluntness is the most useful thing about the tool.
Who is it for?
flawfinder fits a security reviewer who wants a fast first pass over a large C or C++ tree, especially one whose code does not compile or link, and who will triage the output by hand. It does not fit a team that needs a gate on a critical codebase, since it has no control flow or data flow analysis and the README says it will produce many false positives and miss many vulnerabilities.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 159 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A scanner that reads tokens, not semantics

The README describes the mechanism with unusual candour. More technically, flawfinder uses lexical scanning to find tokens such as function names that suggest likely vulnerabilities, estimates their level of risk for example by the text of the function calls, and reports the results. It does not use or have access to most information about control flow, data flow, data types, namespaces and scopes. The consequence follows directly: flawfinder will necessarily produce many false positives for vulnerabilities and fail to report many vulnerabilities.

The compensating advantage is stated just as plainly. Flawfinder can find vulnerabilities in programs that cannot be built or cannot be linked, and it does not get as confused by most macro definitions and other oddities that more sophisticated tools have trouble with. That is the case the tool actually serves. Vendor SDK headers, half-finished ports, code that only compiles on one platform, a tree where the build takes twenty minutes: lexical scanning does not need a working build, and it does not care about your preprocessor.

The project is by David A. Wheeler, is written in Python, is licensed GPL-2.0+, and the project website is dwheeler.com/flawfinder.

Risk levels from 0 to 5, and a default of 1

Findings carry a risk level from 0, very low risk, to 5, high risk, and by default findings of risk level 1 or higher are shown. The practical consequence is that the default output is broad, which is a deliberate choice for a first-pass triage tool rather than a CI gate.

Running the tool is a directory argument.

bash
flawfinder src/

And the current directory recursively is the same call with a dot.

bash
flawfinder ./

To raise the bar so only serious findings appear, there is a minimum level option.

bash
flawfinder --minlevel 4 ./

That flag is the one to think about before wiring this into a pipeline. The risk scale is not a probability, it is an ordering of how dangerous a class of finding is, so the level at which you cut the output is a policy decision about how much human attention the tool's findings can absorb.

Output formats are a strength rather than an afterthought. The README says flawfinder supports various output formats including SARIF, SonarQube and HTML, and the --html option generates output in HTML format, while --help gives a brief list of options. The manual page, flawfinder.1 or flawfinder.pdf, is the full reference, including how the tool supports CWE.

CWE compatibility and the rule list file

Flawfinder supports the Common Weakness Enumeration and is officially CWE-Compatible, which is what makes its findings actionable in an existing security workflow rather than a private numbering scheme. The repository layout shows how that support is wired: a cwe.l file at the top level, which is the mapping from the tool's own rule identifiers to CWE identifiers, and the manual page documents the same thing for users.

The repository is a single-script project with packaging around it. The top level holds flawfinder.py as the program itself, entrypoint.py for the container image, flawfinder.1 for the man page, a makefile, setup.py and setup.cfg, a flawfinder.spec for RPM packaging, a Dockerfile, a pylintrc, a ChangeLog, a release_process.md, a test/ directory and an INSTALL.md with the detailed installation instructions. The setup.py installs a script rather than a package, and the packaging metadata records the version as 2.0.20 with a Development Status of 5, Production/Stable.

The rule set itself is data rather than code, and that has a practical consequence. A false positive can usually be silenced by editing a rule, and a new dangerous function can be added the same way, without touching the scanner. The cost of that flexibility is that the accuracy of the tool depends on rules that live outside the program, and the release tags are where those rule updates would appear.

The GitHub Action, and a version number you have to notice

For GitHub users there is an action, and the README shows a workflow file to create under .github/workflows.

yml
- name: flawfinder_scan
  uses: david-a-wheeler/[email protected]
  with:
    arguments: '--sarif ./'
    output: 'flawfinder_results.sarif'

Two inputs are documented. The arguments input takes flawfinder command arguments, and the output input is the flawfinder output file name, which can be uploaded to GitHub. The README also points out the version number after the @ symbol, and that you can select a different version, and that the action name and version string can be found from the Marketplace by clicking the Use latest/xxx version button.

There is a detail to notice in that example, and it is the kind of thing that causes a failed workflow. The action reference pins 2.0.20 while the recent releases listed for the repository are 2.0.19-alpha1 from 2021-07-17 and 2.0.18 from 2021-07-01, the latter described as the initial release of the GitHub Action. The setup.py in the repository declares 2.0.20, so the action and the package are on a different numbering from the tags.

You can also make the action fail the build, by adding an option such as --error-level=4 to the arguments, which causes an error to be returned if flawfinder finds a vulnerability of level 4 or higher. The action.yml file in the repository is the reference for the exact input names.

SonarQube integration, and the encoding trap in Python 3

Flawfinder integrates with the SonarQube cxx plugin, and the process is a two step one. You add the flawfinder rules in SonarQube under Administration, CXX External Analyers, Other Rule Definitions, by running flawfinder once to list the rules in the form SonarQube expects.

bash
flawfinder --listrules --sonar [...]

Then in your CI/CD run you generate the output that SonarQube can read.

bash
flawfinder -CDQ --sonar [...]

The output is redirected to a file that SonarQube then loads through the sonar.cxx.other.reportPaths option.

The one genuinely thorny problem in the README is character encoding. Flawfinder must be able to correctly interpret your source code's character encoding, and in the vast majority of cases this is not a problem, especially if the source is correctly encoded in UTF-8 and the system is configured for UTF-8. But it is possible for flawfinder to halt on a character encoding problem when running Python 3, with errors of the form Error: encoding error in FILENAME 'ENCODING' codec can't decode byte. The README explains that Python 3 fails to provide useful built-ins to deal with this, which makes it non-trivial to fix without external libraries, which the project is trying to avoid. The simplest solution given is to convert the source and the system configuration to UTF-8, using the system tool iconv or the Python program cvt2utf, which installs with pip install cvt2utf. In a legacy codebase with Latin-1 headers, this is the failure mode you will actually hit.

Where a lexical scanner is the wrong tool

Three cases point elsewhere. The first is a project that needs a finding to mean the code is exploitable. Since the tool has no control flow or data flow information, a match on a dangerous function name says nothing about whether untrusted input reaches it, and in a codebase that uses a wrapper correctly, most matches are noise. A tool with data flow analysis answers that question; this one does not, by design.

The second is a language other than C or C++. The scanner is built around the token and function names of C and C++ and the weakness classes that apply to them, so it has nothing to say about a Go service or a Python web app.

The third is a regulated pipeline that needs a defensible audit trail. The README is upfront that the output will contain false positives, and a security report full of findings a reviewer must dismiss one by one is a different artefact from a finding that has been proven. The README also says the tool can serve as a simple introduction to static source code analysis tools more generally, and that is the honest way to position it: it is a teaching tool and a triage aid, and the projects that use it in anger tend to use it as a filter that points an analyst at the code worth reading.

There is one modern alternative worth naming, and the README itself points at it: flawfinder can be used alongside AI-based code analysis tools, where its output is used to quickly identify which areas of code deserve closer attention and an AI system then examines them in more detail. The division of labour there is the sensible one, and it is the opposite of treating a lexical match as a vulnerability.

Editorial conclusion

flawfinder fits a security reviewer who wants a fast first pass over a large C or C++ tree, especially one whose code does not compile or link, and who will triage the output by hand. It does not fit a team that needs a gate on a critical codebase, since it has no control flow or data flow analysis and the README says it will produce many false positives and miss many vulnerabilities. Before you rely on it, read the Under the hood section so you know what a finding means, and set the minimum level deliberately, because the default of 1 is noisier than most CI budgets allow. The release situation also matters, since the tags stop at 2.0.19-alpha1 from 2021 while the setup.py version is 2.0.20, and the last push was on 2026-05-17.

Frequently asked questions

What does flawfinder actually do to find vulnerabilities?

It uses lexical scanning to find tokens such as function names that suggest likely vulnerabilities, estimates their level of risk for example by the text of the function calls, and reports the results. It does not use or have access to most information about control flow, data flow, data types, namespaces and scopes, so the README says it will necessarily produce many false positives and fail to report many vulnerabilities.

How do I install and run flawfinder?

Install it with pip or with your system's package manager, since flawfinder has packages for many systems, and it also supports make install style source installation, with more detail in INSTALL.md. You can run it without installing, but the README says it is easiest that way. To scan a tree, pass the directory, for example flawfinder src/ or flawfinder ./ for the current directory recursively.

What do the flawfinder risk levels mean?

Hits are given a risk level from 0, very low risk, to 5, high risk, and by default findings of risk level 1 or higher are shown. You can raise the threshold with the --minlevel option, for example flawfinder --minlevel 4 ./, which is the setting to use in CI when the default output is too noisy.

Does flawfinder support CWE and SARIF output?

Yes. Flawfinder supports the Common Weakness Enumeration and is officially CWE-Compatible, and it supports various output formats including SARIF, SonarQube and HTML. The cwe.l file in the repository holds the CWE mapping, and there is also a SonarQube integration that uses the --listrules and -CDQ --sonar options.

What happens when flawfinder hits a character encoding error?

It can halt when running Python 3, with an error such as encoding error in FILENAME 'ENCODING' codec can't decode byte, because Python 3 fails to provide useful built-ins for the problem and the project is trying to avoid external libraries. The README points to converting the source and system configuration to UTF-8, using the system tool iconv or the cvt2utf program installed with pip install cvt2utf.

Official sources

  1. david-a-wheeler/flawfinder on GitHub
  2. Issues
  3. License: GPL-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/david-a-wheeler-flawfinder.svg)](https://hysenlabs.com/projects/david-a-wheeler-flawfinder)

Was this useful?