1307 lines
54 KiB
Groff
1307 lines
54 KiB
Groff
'\"
|
|
.\" (C) Copyright 2001-2018 David A. Wheeler (dwheeler@dwheeler.com)
|
|
.\"
|
|
.\" This program is free software; you can redistribute it and/or modify
|
|
.\" it under the terms of the GNU General Public License as published by
|
|
.\" the Free Software Foundation; either version 2 of the License, or
|
|
.\" (at your option) any later version.
|
|
.\"
|
|
.\" This program is distributed in the hope that it will be useful,
|
|
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
.\" GNU General Public License for more details.
|
|
.\"
|
|
.\" You should have received a copy of the GNU General Public License
|
|
.\" along with this program; if not, write to the Free Software
|
|
.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
.\"
|
|
.\"
|
|
.\"
|
|
.\" Man page created 17 May 2001 by David A. Wheeler (dwheeler@dwheeler.com)
|
|
.\"
|
|
.TH FLAWFINDER 1 "4 Apr 2018" "Flawfinder" "Flawfinder"
|
|
.SH NAME
|
|
flawfinder \- lexically find potential security flaws ("hits") in source code
|
|
.SH SYNOPSIS
|
|
.B flawfinder
|
|
.\" Documentation:
|
|
.RB [ \-\-help | \-h ]
|
|
.RB [ \-\-version ]
|
|
.RB [ \-\-listrules ]
|
|
.br
|
|
.\" Selecting Input Data:
|
|
.RB [ \-\-allowlink ]
|
|
.RB [ \-\-followdotdir ]
|
|
.RB [ \-\-nolink ]
|
|
.br
|
|
.RB [ \-\-patch=\fIfilename\fR | \-P\ \fIfilename\fR ]
|
|
.br
|
|
.\" Selecting Hits to Display:
|
|
.RB [ \-\-inputs | \-I ]
|
|
[ \fB\-\-minlevel=\fR\fIX\fR | \fB\-m\fR\ \fIX\fR ]
|
|
.RB [ \-\-falsepositive | \-F ]
|
|
.br
|
|
.RB [ \-\-neverignore | \-n ]
|
|
.br
|
|
[\fB\-\-regex=\fR\fIPATTERN\fR | \fB\-e\fR \fIPATTERN\fR]
|
|
.br
|
|
.\" Selecting Output Format:
|
|
.RB [ \-\-context | \-c ]
|
|
.RB [ \-\-columns | \-C ]
|
|
.RB [ \-\-csv ]
|
|
.RB [ \-\-dataonly | \-D ]
|
|
.RB [ \-\-html | \-H ]
|
|
.RB [ \-\-immediate | -i ]
|
|
.RB [ \-\-singleline | \-S ]
|
|
.RB [ \-\-omittime ]
|
|
.RB [ \-\-quiet | \-Q ]
|
|
.RB [ \-\-error-level=\fRLEVEL\fR ]
|
|
.br
|
|
.\" Managing hit list.
|
|
[\fB\-\-loadhitlist=\fR\fIF\fR]
|
|
[\fB\-\-savehitlist=\fR\fIF\fR]
|
|
[\fB\-\-diffhitlist=\fR\fIF\fR]
|
|
.br
|
|
.RB [ \-\- ]
|
|
.I [ source code file or source root directory ]+
|
|
.SH DESCRIPTION
|
|
.PP
|
|
Flawfinder searches through C/C++ source code looking for
|
|
potential security flaws.
|
|
To run flawfinder, simply give flawfinder a list of directories or files.
|
|
For each directory given, all files that have C/C++ filename extensions
|
|
in that directory (and its subdirectories, recursively) will be examined.
|
|
Thus, for most projects, simply give flawfinder the name of the source
|
|
code's topmost directory (use ``.'' for the current directory),
|
|
and flawfinder will examine all of the project's C/C++ source code.
|
|
Flawfinder does \fInot\fR require that you be able to build your software,
|
|
so it can be used even with incomplete source code.
|
|
If you only want to have \fIchanges\fR reviewed, save a unified diff
|
|
of those changes (created by GNU "diff -u" or "svn diff" or "git diff")
|
|
in a patch file and use the \-\-patch (\-P) option.
|
|
.PP
|
|
Flawfinder will produce a list of ``hits'' (potential
|
|
security flaws, also called findings),
|
|
sorted by risk; the riskiest hits are shown first.
|
|
The risk level is shown inside square brackets and
|
|
varies from 0, very little risk, to 5, great risk.
|
|
This risk level depends not only on the function, but on the values of the
|
|
parameters of the function.
|
|
For example, constant strings are often less risky than fully variable
|
|
strings in many contexts, and in those contexts the hit will have a
|
|
lower risk level.
|
|
Flawfinder knows about gettext (a common library for internationalized
|
|
programs) and will treat constant strings
|
|
passed through gettext as though they were constant strings; this reduces
|
|
the number of false hits in internationalized programs.
|
|
Flawfinder will do the same sort of thing with _T() and _TEXT(),
|
|
common Microsoft macros for handling internationalized programs.
|
|
.\" For more info, see: http://www.rpi.edu/~pudeyo/articles/unicode.html
|
|
Flawfinder correctly ignores text inside comments and strings.
|
|
Normally flawfinder shows all hits with a risk level of at least 1,
|
|
but you can use the \-\-minlevel option
|
|
to show only hits with higher risk levels if you wish.
|
|
Hit descriptions also note the relevant
|
|
Common Weakness Enumeration (CWE) identifier(s) in parentheses,
|
|
as discussed below.
|
|
Flawfinder is officially CWE-Compatible.
|
|
Hit descriptions with "[MS-banned]" indicate functions that are in the
|
|
banned list of functions released by Microsoft; see
|
|
http://msdn.microsoft.com/en-us/library/bb288454.aspx
|
|
for more information about banned functions.
|
|
.PP
|
|
Not every hit (aka finding) is actually a security vulnerability,
|
|
and not every security vulnerability is necessarily found.
|
|
Nevertheless, flawfinder can be an aid in finding and removing
|
|
security vulnerabilities.
|
|
A common way to use flawfinder is to first
|
|
apply flawfinder to a set of source code and examine the
|
|
highest-risk items.
|
|
Then, use \-\-inputs to examine the input locations, and check to
|
|
make sure that only legal and safe input values are
|
|
accepted from untrusted users.
|
|
.PP
|
|
Once you've audited a program, you can mark source code lines that
|
|
are actually fine but cause spurious warnings so that flawfinder will
|
|
stop complaining about them.
|
|
To mark a line so that these warnings are suppressed,
|
|
put a specially-formatted comment either on the same
|
|
line (after the source code) or all by itself in the previous line.
|
|
The comment must have one of the two following formats:
|
|
.IP \(bu
|
|
// Flawfinder: ignore
|
|
.IP \(bu
|
|
/* Flawfinder: ignore */
|
|
.PP
|
|
For compatibility's sake, you can replace "Flawfinder:" with
|
|
"ITS4:" or "RATS:" in these specially-formatted comments.
|
|
Since it's possible that such lines are wrong, you can use
|
|
the \-\-neverignore option, which causes flawfinder to never ignore any line
|
|
no matter what the comment directives say
|
|
(more confusingly, \-\-neverignore ignores the ignores).
|
|
.PP
|
|
Flawfinder uses an internal database called the ``ruleset'';
|
|
the ruleset identifies functions that are common causes of security flaws.
|
|
The standard ruleset includes a large number of different potential
|
|
problems, including both general issues that can impact any
|
|
C/C++ program, as well as a number of specific Unix-like and Windows
|
|
functions that are especially problematic.
|
|
The \-\-listrules option reports the list of current rules and their
|
|
default risk levels.
|
|
As noted above, every potential security flaw found in a given source code file
|
|
(matching an entry in the ruleset)
|
|
is called a ``hit,'' and the set of hits found during any particular
|
|
run of the program is called the ``hitlist.''
|
|
Hitlists can be saved (using \-\-savehitlist), reloaded back for redisplay
|
|
(using \-\-loadhitlist), and you can show only the hits that are different
|
|
from another run (using \-\-diffhitlist).
|
|
.PP
|
|
Flawfinder is a simple tool, leading to some fundamental pros and cons.
|
|
Flawfinder works by doing simple lexical tokenization
|
|
(skipping comments and correctly tokenizing strings),
|
|
looking for token matches to the database
|
|
(particularly to find function calls).
|
|
Flawfinder is thus similar to RATS and ITS4, which also
|
|
use simple lexical tokenization.
|
|
Flawfinder then examines the
|
|
text of the function parameters to estimate risk.
|
|
Unlike tools such as splint, gcc's warning flags,
|
|
and clang, flawfinder does \fInot\fR use or have access to
|
|
information about control flow, data flow, or data types when
|
|
searching for potential vulnerabilities or estimating the level of risk.
|
|
Thus, flawfinder will necessarily
|
|
produce many false positives for vulnerabilities
|
|
and fail to report many vulnerabilities.
|
|
On the other hand, flawfinder can find vulnerabilities in programs that
|
|
cannot be built or cannot be linked.
|
|
It can often work with programs that cannot even be compiled
|
|
(at least by the reviewer's tools).
|
|
Flawfinder also doesn't get as confused by macro definitions
|
|
and other oddities that more sophisticated tools have trouble with.
|
|
Flawfinder can also be useful as a simple
|
|
introduction to static analysis tools in general,
|
|
since it is easy to start using and easy to understand.
|
|
.PP
|
|
Any filename given on the command line will be examined (even if
|
|
it doesn't have a usual C/C++ filename extension); thus you can force
|
|
flawfinder to examine any specific files you desire.
|
|
While searching directories recursively, flawfinder only opens and
|
|
examines regular files that have C/C++ filename extensions.
|
|
Flawfinder presumes that files are C/C++ files if they have the extensions
|
|
".c", ".h", ".ec", ".ecp", ".pgc", ".C", ".cpp",
|
|
".CPP", ".cxx", ".c++", ".cc", ".CC", ".pcc", ".hpp", or ".H".
|
|
The filename ``\-'' means the standard input.
|
|
To prevent security problems,
|
|
special files (such as device special files and named pipes) are
|
|
always skipped, and by default symbolic links are skipped
|
|
(the \-\-allowlink option follows symbolic links).
|
|
.PP
|
|
After the list of hits is a brief summary of the results
|
|
(use -D to remove this information).
|
|
It will show the number of hits, lines analyzed (as reported by wc \-l),
|
|
and the physical source lines of code (SLOC) analyzed.
|
|
A physical SLOC is a non-blank, non-comment line.
|
|
It will then show the number of hits at each level; note that there will
|
|
never be a hit at a level lower than minlevel (1 by default).
|
|
Thus, "[0] 0 [1] 9" means that at level 0 there were 0 hits reported,
|
|
and at level 1 there were 9 hits reported.
|
|
It will next show the number of hits at a given level or larger
|
|
(so level 3+ has the sum of the number of hits at level 3, 4, and 5).
|
|
Thus, an entry of "[0+] 37" shows that at level 0 or higher there were
|
|
37 hits (the 0+ entry will always be the same as the "hits" number above).
|
|
Hits per KSLOC is next shown; this is each of the "level or higher"
|
|
values multiplied by 1000 and divided by the physical SLOC.
|
|
If symlinks were skipped, the count of those is reported.
|
|
If hits were suppressed (using the "ignore" directive
|
|
in source code comments as described above), the number suppressed is reported.
|
|
The minimum risk level to be included in the report
|
|
is displayed; by default this is 1 (use \-\-minlevel to change this).
|
|
The summary ends with important reminders:
|
|
Not every hit is necessarily a security vulnerability, and
|
|
there may be other security vulnerabilities not reported by the tool.
|
|
.PP
|
|
Flawfinder can easily integrate into a continuous integration system.
|
|
You might want to check out the \-\-error\-level option to help do that.
|
|
.PP
|
|
Flawfinder is released under the GNU GPL license version 2 or later (GPLv2+).
|
|
.PP
|
|
Flawfinder works similarly to another program, ITS4, which is not
|
|
fully open source software (as defined in the Open Source Definition)
|
|
nor free software (as defined by the Free Software Foundation).
|
|
The author of Flawfinder has never seen ITS4's source code.
|
|
Flawfinder is similar in many ways to RATS, if you are familiar with RATS.
|
|
|
|
.SH "BRIEF TUTORIAL"
|
|
|
|
Here's a brief example of how flawfinder might be used.
|
|
Imagine that you have the C/C++ source code for some program named xyzzy
|
|
(which you may or may not have written), and you're
|
|
searching for security vulnerabilities (so you can fix them before
|
|
customers encounter the vulnerabilities).
|
|
For this tutorial, I'll assume that you're using a Unix-like system,
|
|
such as Linux, OpenBSD, or MacOS X.
|
|
.PP
|
|
If the source code is in a subdirectory named xyzzy, you would probably
|
|
start by opening a text window and using flawfinder's default settings, to
|
|
analyze the program and report a prioritized list of potential
|
|
security vulnerabilities (the ``less'' just makes sure the results
|
|
stay on the screen):
|
|
.RS
|
|
flawfinder xyzzy | less
|
|
.RE
|
|
|
|
.PP
|
|
At this point, you will see a large number of entries.
|
|
Each entry has a filename, a colon, a line number, a
|
|
risk level in brackets (where 5 is the most risky), a category,
|
|
the name of the function, and
|
|
a description of why flawfinder thinks the line is a vulnerability.
|
|
Flawfinder normally sorts by risk level, showing the riskiest items
|
|
first; if you have limited time, it's probably best to start working on
|
|
the riskiest items and continue until you run out of time.
|
|
If you want to limit the display to risks with only
|
|
a certain risk level or higher, use
|
|
the \-\-minlevel option.
|
|
If you're getting an extraordinary number of false positives because
|
|
variable names look like dangerous function names, use the \-F option
|
|
to remove reports about them.
|
|
If you don't understand the error message, please see documents such as the
|
|
.UR "https://dwheeler.com/secure-programs"
|
|
.I "Secure Programming HOWTO"
|
|
.UE
|
|
at
|
|
https://dwheeler.com/secure-programs
|
|
which provides more information on writing secure programs.
|
|
.PP
|
|
Once you identify the problem and understand it, you can fix it.
|
|
Occasionally you may want to re-do the analysis, both because the
|
|
line numbers will change \fIand\fP to make sure that the new code
|
|
doesn't introduce yet a different vulnerability.
|
|
.PP
|
|
If you've determined that some line isn't really a problem, and
|
|
you're sure of it, you can insert just before or on the offending
|
|
line a comment like
|
|
.RS
|
|
/* Flawfinder: ignore */
|
|
.RE
|
|
to keep them from showing up in the output.
|
|
.PP
|
|
Once you've done that, you should go back and search for the
|
|
program's inputs, to make sure that the program strongly filters
|
|
any of its untrusted inputs.
|
|
Flawfinder can identify many program inputs by using the \-\-inputs
|
|
option, like this:
|
|
.RS
|
|
flawfinder \-\-inputs xyzzy
|
|
.RE
|
|
.PP
|
|
Flawfinder can integrate well with text editors and
|
|
integrated development environments; see the examples for
|
|
more information.
|
|
.PP
|
|
Flawfinder includes many other options, including ones to
|
|
create HTML versions of the output (useful for prettier displays).
|
|
The next section describes those options in more detail.
|
|
|
|
.SH OPTIONS
|
|
|
|
Flawfinder has a number of options, which can be grouped into options that
|
|
control its own documentation,
|
|
select input data,
|
|
select which hits to display,
|
|
select the output format,
|
|
and perform hitlist management.
|
|
The commonly-used flawfinder options
|
|
support the standard option syntax defined in the
|
|
POSIX (Issue 7, 2013 Edition) section ``Utility Conventions''.
|
|
Flawfinder also supports the GNU long options
|
|
(double-dash options of form \-\-\fIoption\fR)
|
|
as defined in the \fIGNU C Library Reference Manual\fR
|
|
``Program Argument Syntax Conventions''
|
|
and \fIGNU Coding Standards\fR ``Standards for Command Line Interfaces''.
|
|
Long option arguments can be provided as ``--name=value'' or ``-name value''.
|
|
All options can be accessed using the more
|
|
readable GNU long option conventions;
|
|
some less commonly used options can \fIonly\fR be accessed
|
|
using long option conventions.
|
|
|
|
.SS "Documentation"
|
|
|
|
.TP 12
|
|
.BI \-\-help
|
|
.TP
|
|
.BI \-h
|
|
.\" Leave -? undocumented... it also invokes help.
|
|
Show usage (help) information.
|
|
|
|
.TP
|
|
.BI \-\-version
|
|
Shows (just) the version number and exits.
|
|
|
|
.TP 12
|
|
.BI \-\-listrules
|
|
List the terms (tokens)
|
|
that trigger further examination, their default risk level,
|
|
and the default warning (including the CWE identifier(s), if applicable),
|
|
all tab-separated.
|
|
The terms are primarily names of potentially-dangerous functions.
|
|
Note that the reported risk level and warning
|
|
for some specific code may be different than the default,
|
|
depending on how the term is used.
|
|
Combine with \-D if you do not want the usual header.
|
|
Flawfinder version 1.29 changed the separator from spaces to tabs, and
|
|
added the default warning field.
|
|
|
|
.SS "Selecting Input Data"
|
|
|
|
.TP 12
|
|
.BI \-\-allowlink
|
|
Allow the use of symbolic links; normally symbolic links are skipped.
|
|
Don't use this option if you're analyzing code by others;
|
|
attackers could do many things to cause problems for an analysis
|
|
with this option enabled.
|
|
For example, an attacker
|
|
could insert symbolic links to files such as /etc/passwd
|
|
(leaking information about the file) or create a circular loop,
|
|
which would cause flawfinder to run ``forever''.
|
|
Another problem with enabling this option is that
|
|
if the same file is referenced multiple times using symbolic links,
|
|
it will be analyzed multiple times (and thus reported multiple times).
|
|
Note that flawfinder already includes some protection against symbolic links
|
|
to special file types such as device file types (e.g., /dev/zero or
|
|
C:\\mystuff\\com1).
|
|
Note that for flawfinder version 1.01 and before, this was the default.
|
|
|
|
.TP
|
|
.BI \-\-followdotdir
|
|
Enter directories whose names begin with ".".
|
|
Normally such directories are ignored, since they normally
|
|
include version control private data (such as .git/ or .svn/),
|
|
build metadata (such as .makepp),
|
|
configuration information, and so on.
|
|
|
|
.TP
|
|
.BI \-\-nolink
|
|
Ignored.
|
|
Historically this disabled following symbolic links;
|
|
this behavior is now the default.
|
|
|
|
.TP 12
|
|
\fB\-\-patch=\fR\fIpatchfile\fR
|
|
.TP
|
|
\fB\-P\fR \fIpatchfile\fR
|
|
Examine the selected files or directories, but only report hits in lines
|
|
that are added or modified as described in the given patch file.
|
|
The patch file must be in a recognized unified diff format
|
|
(e.g., the output of GNU "diff -u old new", "svn diff", or "git diff [commit]").
|
|
Flawfinder assumes that the patch has already been applied to the files.
|
|
The patch file can also include changes to irrelevant files
|
|
(they will simply be ignored).
|
|
The line numbers given in the patch file are used to determine which
|
|
lines were changed, so if you have modified the files since the
|
|
patch file was created, regenerate the patch file first.
|
|
Beware that the file names of the new files
|
|
given in the patch file must match exactly,
|
|
including upper/lower case, path prefix, and directory
|
|
separator (\\ vs. /).
|
|
Only unified diff format is accepted (GNU diff, svn diff, and
|
|
git diff output is okay);
|
|
if you have a different format, again regenerate it first.
|
|
Only hits that occur on resultant changed lines, or immediately
|
|
above and below them, are reported.
|
|
This option implies \-\-neverignore.
|
|
\fBWarning\fR: Do \fInot\fR pass a patch file without the
|
|
\fB\-P\fR, because flawfinder will then try to treat the file as a
|
|
source file.
|
|
This will often work, but the line numbers will be relative
|
|
to the beginning of the patch file, not the positions in the
|
|
source code.
|
|
Note that you \fBmust\fR also provide the actual files to analyze,
|
|
and not just the patch file; when using \fB\-P\fR files are only reported
|
|
if they are both listed in the patch and also listed (directly or indirectly)
|
|
in the list of files to analyze.
|
|
|
|
|
|
.SS "Selecting Hits to Display"
|
|
|
|
.TP
|
|
.BI "\-\-inputs"
|
|
.TP
|
|
.BI \-I
|
|
Show only functions that obtain data from outside the program;
|
|
this also sets minlevel to 0.
|
|
|
|
.TP
|
|
\fB\-\-minlevel=\fIX\fR
|
|
.TP
|
|
.BI -m " X"
|
|
Set minimum risk level to X for inclusion in hitlist.
|
|
This can be from 0 (``no risk'') to 5 (``maximum risk'');
|
|
the default is 1.
|
|
|
|
.TP
|
|
.BI "\-\-falsepositive"
|
|
.TP
|
|
.BI \-F
|
|
Do not include hits that are likely to be false positives.
|
|
Currently, this means that function names are ignored if they're
|
|
not followed by "(", and that declarations of character arrays aren't
|
|
noted.
|
|
Thus, if you have use a variable named "access" everywhere, this will
|
|
eliminate references to this ordinary variable.
|
|
This isn't the default, because this also increases the likelihood
|
|
of missing important hits; in particular, function names in #define
|
|
clauses and calls through function pointers will be missed.
|
|
|
|
.TP
|
|
.BI \-\-neverignore
|
|
.TP
|
|
.BI -n
|
|
Never ignore security issues, even if they have an ``ignore'' directive
|
|
in a comment.
|
|
|
|
.TP
|
|
\fB\-\-regexp=\fR\fIPATTERN\fR
|
|
.TP
|
|
\fB-e\fR \fIPATTERN\fR
|
|
Only report hits with text that matches the regular expression pattern PATTERN.
|
|
For example, to only report hits containing the text "CWE-120",
|
|
use ``\-\-regex CWE-120''.
|
|
These option flag names are the same as grep.
|
|
|
|
|
|
.SS "Selecting Output Format"
|
|
|
|
.TP 12
|
|
.BI \-\-columns
|
|
.TP
|
|
.BI \-C
|
|
Show the column number (as well as the file name and line number)
|
|
of each hit; this is shown after the line number by adding a colon
|
|
and the column number in the line (the first character in a line is
|
|
column number 1).
|
|
This is useful for editors that can jump to specific columns, or
|
|
for integrating with other tools (such as those to further filter out
|
|
false positives).
|
|
|
|
.TP
|
|
.BI \-\-context
|
|
.TP
|
|
.BI \-c
|
|
Show context, i.e., the line having the "hit"/potential flaw.
|
|
By default the line is shown immediately after the warning.
|
|
|
|
.TP
|
|
.BI \-\-csv
|
|
Generate output in comma-separated-value (CSV) format.
|
|
This is the recommended format for sending to other tools for processing.
|
|
It will always generate a header row, followed by 0 or more data rows
|
|
(one data row for each hit).
|
|
Selecting this option automatically enables \-\-quiet and
|
|
\-\-dataonly.
|
|
The headers are mostly self-explanatory.
|
|
"File" is the filename, "Line" is the line number,
|
|
"Column" is the column (starting from 1),
|
|
"Level" is the risk level (0-5, 5 is riskiest),
|
|
"Category" is the general flawfinder category,
|
|
"Name" is the name of the triggering rule,
|
|
"Warning" is text explaining why it is a hit (finding),
|
|
"Suggestion" is text suggesting how it might be fixed,
|
|
"Note" is other explanatory notes,
|
|
"CWEs" is the list of one or more CWEs,
|
|
"Context" is the source code line triggering the hit,
|
|
and "Fingerprint" is the SHA-256 hash of the context once
|
|
its leading and trailing whitespace have been removed
|
|
(the fingerprint may help detect and eliminate later duplications).
|
|
If you use Python3, the hash is of the context when encoded as UTF-8.
|
|
|
|
.TP
|
|
.BI "\-\-dataonly"
|
|
.TP
|
|
.BI \-D
|
|
Don't display the header and footer.
|
|
Use this along with \-\-quiet to see just the data itself.
|
|
|
|
.TP
|
|
.BI \-\-html
|
|
.TP
|
|
.BI \-H
|
|
Format the output as HTML instead of as simple text.
|
|
|
|
.TP
|
|
.BI "\-\-immediate"
|
|
.TP
|
|
.BI -i
|
|
Immediately display hits (don't just wait until the end).
|
|
|
|
.TP
|
|
.BI "\-\-singleline"
|
|
.TP
|
|
.BI -S
|
|
Display as single line of text output for each hit.
|
|
Useful for interacting with compilation tools.
|
|
|
|
.TP
|
|
.BI "\-\-omittime"
|
|
Omit timing information.
|
|
This is useful for regression tests of flawfinder itself, so that
|
|
the output doesn't vary depending on how long the analysis takes.
|
|
|
|
.TP
|
|
.BI "\-\-quiet"
|
|
.TP
|
|
.BI \-Q
|
|
Don't display status information (i.e., which files are being examined)
|
|
while the analysis is going on.
|
|
|
|
.TP
|
|
.BI "\-\-error-level=LEVEL"
|
|
Return a nonzero (false) error code if there is at least one
|
|
hit of LEVEL or higher. If a diffhitlist is provided,
|
|
hits noted in it are ignored.
|
|
This option can be useful within a continuous integration script,
|
|
especially if you mark known-okay lines as "flawfinder: ignore".
|
|
Usually you want level to be fairly high, such as 4 or 5.
|
|
By default, flawfinder returns 0 (true) on a successful run.
|
|
|
|
.SS "Hitlist Management"
|
|
|
|
.\" This isn't sorted as usual, because logically saving comes
|
|
.\" before loading and differencing.
|
|
.TP 12
|
|
\fB\-\-savehitlist=\fR\fIF\fR
|
|
Save all resulting hits (the "hitlist") to F.
|
|
|
|
.TP
|
|
\fB\-\-loadhitlist=\fR\fIF\fR
|
|
Load the hitlist from F instead of analyzing source programs.
|
|
Warning: Do \fInot\fR load hitlists from untrusted sources
|
|
(for security reasons).
|
|
These are internally implemented using Python's "pickle" facility,
|
|
which trusts the input.
|
|
Note that stored hitlists often cannot be read when using an older version
|
|
of Python, in particular, if savehitlist was used but
|
|
flawfinder was run using Python 3,
|
|
the hitlist can't be loaded by running flawfinder with Python 2.
|
|
|
|
.TP
|
|
\fB\-\-diffhitlist=\fR\fIF\fR
|
|
Show only hits (loaded or analyzed) not in F.
|
|
F was presumably created previously using \-\-savehitlist.
|
|
Warning: Do \fInot\fR diff hitlists from untrusted sources
|
|
(for security reasons).
|
|
If the \-\-loadhitlist option is not provided, this will show the hits in
|
|
the analyzed source code files that were not previously stored in F.
|
|
If used along with \-\-loadhitlist, this will show the hits in the
|
|
loaded hitlist not in F.
|
|
The difference algorithm is conservative;
|
|
hits are only considered the ``same'' if they have the same
|
|
filename, line number, column position, function name, and risk level.
|
|
|
|
.SS "Character Encoding Errors"
|
|
|
|
Flawfinder uses the character encoding rules set by Python.
|
|
Sometimes source code does not perfectly follow some encoding rules.
|
|
If you run flawfinder with Python 2
|
|
these non-conformities often do not impact processing in practice.
|
|
|
|
However, if you run flawfinder with Python 3, this can be a problem.
|
|
Python 3 developers wants the world to always use encodings perfectly correctly,
|
|
everywhere, and in general wants everyone to only use UTF-8.
|
|
UTF-8 is a great encoding, and it is very popular, but
|
|
the world often doesn't care what the Python 3 developers want.
|
|
|
|
When running flawfinder using Python 3, the program will crash hard if
|
|
\fIany\fR source file has \fIany\fR non-conforming text.
|
|
It will do this even if the non-conforming text is in comments or strings
|
|
(where it often doesn't matter).
|
|
Python 3 fails to provide useful built-ins to deal with
|
|
the messiness of the real world, so it's
|
|
non-trivial to deal with this problem without depending on external
|
|
libraries (which we're trying to avoid).
|
|
|
|
A symptom of this problem
|
|
is if you run flawfinder and you see an error message like this:
|
|
|
|
\fIError: encoding error in ,1.c\fR
|
|
|
|
\fI'utf-8' codec can't decode byte 0xff in position 45: invalid start byte\fR
|
|
|
|
What you are seeing is the result of an internal UnicodeDecodeError.
|
|
|
|
If this happens to you, there are several options:
|
|
|
|
Option #1 (special case):
|
|
if your system normally uses an encoding other than UTF-8,
|
|
is properly set up to use that encoding (using LC_ALL and maybe LC_CTYPE),
|
|
and the input files are in that non-UTF-8 encoding,
|
|
it may be that Python3 is (incorrectly) ignoring your configuration.
|
|
In that case, simply tell Python3 to use your
|
|
configuration by setting the environment variable PYTHONUTF8=0, e.g.,
|
|
run flawfinder as:
|
|
"PYTHONUTF8=0 python3 flawfinder ...".
|
|
|
|
Option #2 (special case): If you know what the encoding of the files is,
|
|
you can force use of that encoding. E.g., if the encoding
|
|
is BLAH, run flawfinder as:
|
|
"PYTHONUTF8=0 LC_ALL=C.BLAH python3 flawfinder ...".
|
|
You can replace "C" after LC_ALL= with your real language locale
|
|
(e.g., "en_US").
|
|
|
|
Option #3: If you don't know what the encoding is, or the encoding is
|
|
inconsistent (e.g., the common case of UTF-8 files with some
|
|
characters encoded using Windows-1252 instead),
|
|
then you can force the system to use the
|
|
ISO-8859-1 (Latin-1) encoding in which all bytes are allowed.
|
|
If the inconsistencies are only in comments and strings, and the
|
|
underlying character set is "close enough" to ASCII, this can get you
|
|
going in a hurry.
|
|
You can do this by running:
|
|
"PYTHONUTF8=0 LC_ALL=C.ISO-8859-1 python3 flawfinder ...".
|
|
In some cases you may not need the "PYTHONUTF8=0".
|
|
You may be able to replace "C" after LC_ALL= with your real language locale
|
|
(e.g., "en_US").
|
|
|
|
Option #4: Convert the encoding of the files to be analyzed so that it's
|
|
a single encoding - it's highly recommended to convert to UTF-8.
|
|
For example, the program "iconv" can be used to convert encodings.
|
|
This works well if some files have one encoding, and some have another,
|
|
but they are consistent within a single file.
|
|
If the files have encoding errors, you'll have to fix them.
|
|
|
|
Option #5: Run flawfinder using Python 2 instead of Python 3.
|
|
E.g., "python2 flawfinder ...".
|
|
|
|
To be clear:
|
|
I strongly recommend using the UTF-8 encoding for all source code,
|
|
and use continuous integration tests to ensure that the source code
|
|
is always valid UTF-8.
|
|
If you do that, many problems disappear.
|
|
But in the real world this is not always the situation.
|
|
Hopefully
|
|
this information will help you deal with real-world encoding problems.
|
|
|
|
.SH EXAMPLES
|
|
|
|
Here are various examples of how to invoke flawfinder.
|
|
The first examples show various simple command-line options.
|
|
Flawfinder is designed to work well with text editors and
|
|
integrated development environments, so the next sections
|
|
show how to integrate flawfinder into vim and emacs.
|
|
|
|
.SS "Simple command-line options"
|
|
|
|
.TP 12
|
|
.B "flawfinder /usr/src/linux-3.16"
|
|
Examine all the C/C++ files in the directory
|
|
/usr/src/linux-3.16 and all its subdirectories (recursively),
|
|
reporting on all hits found.
|
|
By default flawfinder will skip symbolic links and
|
|
directories with names that start with a period.
|
|
|
|
.TP
|
|
.B "flawfinder \-\-minlevel=4 ."
|
|
Examine all the C/C++ files in the current directory
|
|
and its subdirectories (recursively);
|
|
only report vulnerabilities level 4 and up (the two highest risk levels).
|
|
|
|
.TP
|
|
.B "flawfinder \-\-inputs mydir"
|
|
Examine all the C/C++ files in mydir
|
|
and its subdirectories (recursively), and report functions
|
|
that take inputs (so that you can ensure that they filter the
|
|
inputs appropriately).
|
|
|
|
.TP
|
|
.B "flawfinder \-\-neverignore mydir"
|
|
Examine all the C/C++ files in the directory mydir and its subdirectories,
|
|
including even the hits marked for ignoring in the code comments.
|
|
|
|
.TP
|
|
.B "flawfinder \-\-csv ."
|
|
Examine the current directory down (recursively), and report all
|
|
hits in CSV format.
|
|
This is the recommended form if you want to further process
|
|
flawfinder output using other tools
|
|
(such as data correlation tools).
|
|
|
|
.TP
|
|
.B "flawfinder \-QD mydir"
|
|
Examine mydir and report only the actual results
|
|
(removing the header and footer of the output).
|
|
This form may be useful
|
|
if the output will be piped into other tools for further analysis,
|
|
though CSV format is probably the better choice in that case.
|
|
The \-C (\-\-columns) and \-S (\-\-singleline)
|
|
options can also be useful if you're piping the data
|
|
into other tools.
|
|
|
|
.TP
|
|
.B "flawfinder \-QDSC mydir"
|
|
Examine mydir, reporting only the actual results (no header or footer).
|
|
Each hit is reported on one line, and column numbers are reported.
|
|
This can be a useful command if you are feeding
|
|
flawfinder output to other tools.
|
|
|
|
.TP
|
|
.B "flawfinder \-\-quiet \-\-html \-\-context mydir > results.html"
|
|
Examine all the C/C++ files in the directory mydir and its subdirectories,
|
|
and produce an HTML formatted version of the results.
|
|
Source code management systems (such as SourceForge and Savannah)
|
|
might use a command like this.
|
|
|
|
.TP
|
|
.B "flawfinder \-\-quiet \-\-savehitlist saved.hits *.[ch]"
|
|
Examine all .c and .h files in the current directory.
|
|
Don't report on the status of processing, and save the resulting hitlist
|
|
(the set of all hits) in the file saved.hits.
|
|
|
|
.TP
|
|
.B "flawfinder \-\-diffhitlist saved.hits *.[ch]"
|
|
Examine all .c and .h files in the current directory, and show any
|
|
hits that weren't already in the file saved.hits.
|
|
This can be used to show only the ``new'' vulnerabilities in a
|
|
modified program, if saved.hits was created from the
|
|
older version of the program being analyzed.
|
|
|
|
.TP 12
|
|
.B "flawfinder \-\-patch recent.patch ."
|
|
Examine the current directory recursively, but only report lines
|
|
that were changed or added in the already-applied patchfile named
|
|
\fIrecent.patch\fR.
|
|
|
|
.TP
|
|
\fBflawfinder \-\-regex "CWE-120|CWE-126" src/\fR
|
|
Examine directory \fIsrc\fR recursively, but only report hits
|
|
where CWE-120 or CWE-126 apply.
|
|
|
|
.SS "Invoking from vim"
|
|
|
|
.PP
|
|
The text editor
|
|
vim includes a "quickfix" mechanism that works well with flawfinder,
|
|
so that you can easily view the warning messages and jump to
|
|
the relevant source code.
|
|
.PP
|
|
First, you need to invoke flawfinder to create a list of hits, and
|
|
there are two ways to do this.
|
|
The first way is to start flawfinder first, and then (using its output)
|
|
invoke vim.
|
|
The second way is to start (or continue to run) vim, and then invoke
|
|
flawfinder (typically from inside vim).
|
|
.PP
|
|
For the first way, run flawfinder and store its output in some
|
|
FLAWFILE (say "flawfile"),
|
|
then invoke vim using its -q option, like this: "vim -q flawfile".
|
|
The second way (starting flawfinder after starting vim) can be done
|
|
a legion of ways.
|
|
One is to invoke flawfinder using a shell command,
|
|
":!flawfinder-command > FLAWFILE", then follow that with the command
|
|
":cf FLAWFILE".
|
|
Another way is to store the flawfinder command in your makefile
|
|
(as, say, a pseudocommand like "flaw"), and then run
|
|
":make flaw".
|
|
.PP
|
|
In all these cases you need a command for flawfinder to run.
|
|
A plausible command, which places each hit in its own line (-S) and
|
|
removes headers and footers that would confuse it, is:
|
|
.PP
|
|
.B "flawfinder \-SQD ."
|
|
|
|
.PP
|
|
You can now use various editing commands to view the results.
|
|
The command ":cn" displays the next hit; ":cN" displays the
|
|
previous hit, and ":cr" rewinds back to the first hit.
|
|
":copen" will open a window to show the current list of hits, called
|
|
the "quickfix window"; ":cclose" will close the quickfix window.
|
|
If the buffer in the used window has changed, and the error is in
|
|
another file, jumping to the error will fail.
|
|
You have to make sure the window contains a buffer which can be abandoned
|
|
before trying to jump to a new file, say by saving the file;
|
|
this prevents accidental data loss.
|
|
|
|
.SS "Invoking from emacs"
|
|
The text editor / operating system
|
|
emacs includes "grep mode" and "compile mode" mechanisms
|
|
that work well with flawfinder, making it easy to
|
|
view warning messages, jump to the relevant source code, and fix
|
|
any problems you find.
|
|
.PP
|
|
First, you need to invoke flawfinder to create a list of warning messages.
|
|
You can use "grep mode" or "compile mode" to create this list.
|
|
Often "grep mode" is more convenient;
|
|
it leaves compile mode untouched so you can easily recompile
|
|
once you've changed something.
|
|
However, if you want to jump to the exact column position of a hit,
|
|
compile mode may be more convenient because emacs can use
|
|
the column output of flawfinder to directly jump to the right location
|
|
without any special configuration.
|
|
.PP
|
|
To use grep mode,
|
|
enter the command "M-x grep"
|
|
and then enter the needed flawfinder command.
|
|
To use compile mode, enter the command
|
|
"M-x compile" and enter the needed flawfinder command.
|
|
This is a meta-key command, so you'll need to use the meta key for your
|
|
keyboard (this is usually the ESC key).
|
|
As with all emacs commands, you'll need to press RETURN after
|
|
typing "grep" or "compile".
|
|
So on many systems, the grep mode is invoked by typing
|
|
ESC x g r e p RETURN.
|
|
.PP
|
|
You then need to enter a command, removing whatever was there before if
|
|
necessary.
|
|
A plausible command is:
|
|
.PP
|
|
.B "flawfinder \-SQDC ."
|
|
.PP
|
|
This command makes every hit report a single line,
|
|
which is much easier for tools to handle.
|
|
The quiet and dataonly options remove the other status information not needed
|
|
for use inside emacs.
|
|
The trailing period means that the current directory and all descendents
|
|
are searched for C/C++ code, and analyzed for flaws.
|
|
.PP
|
|
Once you've invoked flawfinder, you can use emacs to jump around
|
|
in its results.
|
|
The command C-x \`
|
|
(Control-x backtick)
|
|
visits the source code location for the next warning message.
|
|
C-u C-x \` (control-u control-x backtick)
|
|
restarts from the beginning.
|
|
You can visit the source for any particular error message by moving
|
|
to that hit message in the *compilation* buffer or *grep* buffer
|
|
and typing the return key.
|
|
(Technical note: in the compilation buffer, this invokes
|
|
compile-goto-error.)
|
|
You can also click the Mouse-2 button on the error message
|
|
(you don't need to switch to the *compilation* buffer first).
|
|
.PP
|
|
If you want to use grep mode to jump to specific columns of a hit,
|
|
you'll need to specially configure emacs to do this.
|
|
To do this, modify the emacs variable "grep-regexp-alist".
|
|
This variable tells Emacs how to
|
|
parse output of a "grep" command, similar to the
|
|
variable "compilation-error-regexp-alist" which lists various formats
|
|
of compilation error messages.
|
|
|
|
.SS "Invoking from Integrated Development Environments (IDEs)"
|
|
.PP
|
|
For (other) IDEs, consult your IDE's set of plug-ins.
|
|
|
|
.SH COMMON WEAKNESS ENUMERATION (CWE)
|
|
.PP
|
|
The Common Weakness Enumeration (CWE)
|
|
is ``a formal list or dictionary of common software weaknesses
|
|
that can occur in software's architecture, design, code or implementation
|
|
that can lead to exploitable security vulnerabilities...
|
|
created to serve as a common language for
|
|
describing software security weaknesses''
|
|
(https://cwe.mitre.org/about/faq.html).
|
|
For more information on CWEs, see https://cwe.mitre.org.
|
|
.PP
|
|
Flawfinder supports the CWE and is officially CWE-Compatible.
|
|
Hit descriptions typically include a relevant
|
|
Common Weakness Enumeration (CWE) identifier in parentheses
|
|
where there is known to be a relevant CWE.
|
|
For example, many of the buffer-related hits mention
|
|
CWE-120, the CWE identifier for
|
|
``buffer copy without checking size of input''
|
|
(aka ``Classic Buffer Overflow'').
|
|
In a few cases more than one CWE identifier may be listed.
|
|
The HTML report also includes hypertext links to the CWE definitions
|
|
hosted at MITRE.
|
|
In this way, flawfinder is designed to meet the CWE-Output requirement.
|
|
.PP
|
|
In some cases there are CWE mapping and usage challenges; here is how
|
|
flawfinder handles them.
|
|
If the same entry maps to multiple CWEs simultaneously,
|
|
all the CWE mappings are listed as separated by commas.
|
|
This often occurs with CWE-20, Improper Input Validation;
|
|
thus the report "CWE-676, CWE-120" maps to two CWEs.
|
|
In addition, flawfinder provides additional information for those who are
|
|
are interested in the CWE/SANS top 25 list 2011 (https://cwe.mitre.org/top25/)
|
|
when mappings are not directly to them.
|
|
Many people will want to search for specific CWEs in this top 25 list,
|
|
such as CWE-120 (classic buffer overflow).
|
|
The challenge is that some flawfinder hits map
|
|
to a more general CWE that would include a top 25 item, while in some
|
|
other cases hits map to a more specific vulnerability that is
|
|
only a subset of a top 25 item.
|
|
To resolve this, in some cases flawfinder will list a sequence of CWEs
|
|
in the format "more-general/more-specific", where the CWE actually
|
|
being mapped is followed by a "!".
|
|
This is always done whenever a flaw is not mapped directly to
|
|
a top 25 CWE, but the mapping is related to such a CWE.
|
|
So "CWE-119!/CWE-120" means that the vulnerability is mapped
|
|
to CWE-119 and that CWE-120 is a subset of CWE-119.
|
|
In contrast, "CWE-362/CWE-367!" means that the hit is mapped to
|
|
CWE-367, a subset of CWE-362.
|
|
Note that this is a subtle syntax change from flawfinder version 1.31;
|
|
in flawfinder version 1.31,
|
|
the form "more-general:more-specific" meant what is now listed as
|
|
"more-general!/more-specific", while
|
|
"more-general/more-specific" meant "more-general/more-specific!".
|
|
Tools can handle both the version 1.31 and the current format,
|
|
if they wish, by noting that the older format did not use "!" at all
|
|
(and thus this is easy to distinguish).
|
|
These mapping mechanisms simplify searching for certain CWEs.
|
|
.PP
|
|
CWE version 2.7 (released June 23, 2014) was used for the mapping.
|
|
The current CWE mappings select the most specific CWE the tool can determine.
|
|
In theory, most CWE security elements (signatures/patterns that the
|
|
tool searches for) could theoretically be mapped to
|
|
CWE-676 (Use of Potentially Dangerous Function), but such a mapping would
|
|
not be useful.
|
|
Thus, more specific mappings were preferred where one could be found.
|
|
Flawfinder is a lexical analysis tool; as a result, it is impractical
|
|
for it to be more specific than the mappings currently implemented.
|
|
This also means that it is unlikely to need much
|
|
updating for map currency; it simply doesn't have enough information to
|
|
refine to a detailed CWE level that CWE changes would typically affect.
|
|
The list of CWE identifiers was generated automatically using "make show-cwes",
|
|
so there is confidence that this list is correct.
|
|
Please report CWE mapping problems as bugs if you find any.
|
|
.PP
|
|
Flawfinder may fail to find a vulnerability, even if flawfinder covers
|
|
one of these CWE weaknesses.
|
|
That said, flawfinder does find vulnerabilities listed by the CWEs it covers,
|
|
and it will not report lines without those vulnerabilities in many cases.
|
|
Thus, as required for any tool intending to be CWE compatible,
|
|
flawfinder has a rate of false positives less than 100%
|
|
and a rate of false negatives less than 100%.
|
|
Flawfinder almost always reports whenever it finds a match to a
|
|
CWE security element (a signature/pattern as defined in its database),
|
|
though certain obscure constructs can cause it to fail (see BUGS below).
|
|
.PP
|
|
Flawfinder can report on the following CWEs
|
|
(these are the CWEs that flawfinder covers; ``*'' marks those in the
|
|
CWE/SANS top 25 list):
|
|
.IP \(bu 2
|
|
CWE-20: Improper Input Validation
|
|
.IP \(bu 2
|
|
CWE-22: Improper Limitation of a Pathname to a Restricted Directory (``Path Traversal'')
|
|
.IP \(bu
|
|
CWE-78: Improper Neutralization of Special Elements used in an OS Command (``OS Command Injection'')*
|
|
.IP \(bu
|
|
CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer
|
|
(a parent of CWE-120*, so this is shown as CWE-119!/CWE-120)
|
|
.IP \(bu
|
|
CWE-120: Buffer Copy without Checking Size of Input (``Classic Buffer Overflow'')*
|
|
.IP \(bu
|
|
CWE-126: Buffer Over-read
|
|
.IP \(bu
|
|
CWE-134: Uncontrolled Format String*
|
|
.IP \(bu
|
|
CWE-190: Integer Overflow or Wraparound*
|
|
.IP \(bu
|
|
CWE-250: Execution with Unnecessary Privileges
|
|
.IP \(bu
|
|
CWE-327: Use of a Broken or Risky Cryptographic Algorithm*
|
|
.IP \(bu
|
|
CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization (``Race Condition'')
|
|
.IP \(bu
|
|
CWE-377: Insecure Temporary File
|
|
.IP \(bu
|
|
CWE-676: Use of Potentially Dangerous Function*
|
|
.IP \(bu
|
|
CWE-732: Incorrect Permission Assignment for Critical Resource*
|
|
.IP \(bu
|
|
CWE-785: Use of Path Manipulation Function without Maximum-sized Buffer
|
|
(child of CWE-120*, so this is shown as CWE-120/CWE-785)
|
|
.IP \(bu
|
|
CWE-807: Reliance on Untrusted Inputs in a Security Decision*
|
|
.IP \(bu
|
|
CWE-829: Inclusion of Functionality from Untrusted Control Sphere*
|
|
.PP
|
|
You can select a specific subset of CWEs to report by using
|
|
the ``\-\-regex'' (-e) option.
|
|
This option accepts a regular expression, so you can select multiple CWEs,
|
|
e.g., ``\-\-regex "CWE-120|CWE-126"''.
|
|
If you select multiple CWEs with ``|'' on a command line
|
|
you will typically need to quote the parameters (since an
|
|
unquoted ``|'' is the pipe symbol).
|
|
Flawfinder is designed to meet the CWE-Searchable requirement.
|
|
.PP
|
|
If your goal is to report a subset of CWEs that are listed in a file,
|
|
that can be achieved on a Unix-like system using the ``\-\-regex'' aka
|
|
``\-e'' option.
|
|
The file must be in regular expression format.
|
|
For example,
|
|
``flawfinder -e $(cat file1)'' would report only hits that matched
|
|
the pattern in ``file1''.
|
|
If file1 contained ``CWE-120|CWE-126'' it
|
|
would only report hits matching those CWEs.
|
|
.PP
|
|
A list of all CWE security elements
|
|
(the signatures/patterns that flawfinder looks for)
|
|
can be found by using the ``\-\-listrules'' option.
|
|
Each line lists the signature token (typically a function name)
|
|
that may lead to a hit, the default risk level, and
|
|
the default warning (which includes the default CWE identifier).
|
|
For most purposes this is also enough if you want to see what
|
|
CWE security elements map to which CWEs, or the reverse.
|
|
For example, to see the most of the signatures (function names)
|
|
that map to CWE-327,
|
|
without seeing the default risk level or detailed warning text,
|
|
run ``flawfinder \-\-listrules | grep CWE-327 | cut -f1''.
|
|
You can also see the tokens without a CWE mapping this way by running
|
|
``flawfinder -D --listrules | grep -v CWE-''.
|
|
However, while \-\-listrules lists all CWE security elements,
|
|
it only lists the default mappings
|
|
from CWE security elements to CWE identifiers.
|
|
It does not include the refinements
|
|
that flawfinder applies (e.g., by examining function parameters).
|
|
.PP
|
|
If you want a detailed and exact mapping between the CWE security elements
|
|
and CWE identifiers, the flawfinder source code (included in the distribution)
|
|
is the best place for that information.
|
|
This detailed information is primarily of interest to those few
|
|
people who are trying to refine the CWE mappings of flawfinder
|
|
or refine CWE in general.
|
|
The source code documents the mapping between the security elements
|
|
to the respective CWE identifiers, and is a single Python file.
|
|
The ``c_rules'' dataset defines most rules, with reference to a
|
|
function that may make further refinements.
|
|
You can search the dataset for
|
|
function names to see what CWE it generates by default;
|
|
if first parameter is not ``normal'' then that is the name of
|
|
a refining Python method that may select different CWEs
|
|
(depending on additional information).
|
|
Conversely, you can search for ``CWE-number'' and find what security
|
|
elements (signatures or patterns) refer to that CWE identifier.
|
|
For most people, this is much more than they need; most people just want to
|
|
scan their source code to quickly find problems.
|
|
|
|
|
|
.SH SECURITY
|
|
.PP
|
|
The whole point of this tool is to help find vulnerabilities so they
|
|
can be fixed.
|
|
However, developers and reviewers must
|
|
know how to develop secure software to use this tool, because otherwise,
|
|
\fIa fool with a tool is still a fool\fR.
|
|
My book at https://dwheeler.com/secure-programs may help.
|
|
.PP
|
|
This tool should be, at most, a small part of a larger software
|
|
development process designed
|
|
to eliminate or reduce the impact of vulnerabilities.
|
|
Developers and reviewers need know how to develop secure software,
|
|
and they need to apply this knowledge to reduce the
|
|
risks of vulnerabilities in the first place.
|
|
.PP
|
|
Different vulnerability-finding tools tend to find different vulnerabilities.
|
|
Thus, you are best off using human review and a variety of tools.
|
|
This tool can help find some vulnerabilities, but by no means all.
|
|
.PP
|
|
You should always analyze a \fIcopy\fP of the source program being analyzed,
|
|
not a directory that can be modified by a developer while flawfinder
|
|
is performing the analysis.
|
|
This is \fIespecially\fP true if you don't necessily trust a
|
|
developer of the program being analyzed.
|
|
If an attacker has control over the files while you're analyzing them,
|
|
the attacker could move files around or change their contents to
|
|
prevent the exposure of a security problem (or create the impression
|
|
of a problem where there is none).
|
|
If you're worried about malicious programmers you should do this anyway,
|
|
because after analysis you'll need to verify that the code eventually run
|
|
is the code you analyzed.
|
|
Also, do not use the \-\-allowlink option in such cases;
|
|
attackers could create malicious symbolic links to files outside of their
|
|
source code area (such as /etc/passwd).
|
|
.PP
|
|
Source code management systems (like GitHub, SourceForge, and Savannah)
|
|
definitely fall into this category; if you're maintaining one of those
|
|
systems, first copy or extract the files into a separate directory
|
|
(that can't be controlled by attackers)
|
|
before running flawfinder or any other code analysis tool.
|
|
.PP
|
|
Note that flawfinder only opens regular files, directories, and
|
|
(if requested) symbolic links; it will never open other kinds of files,
|
|
even if a symbolic link is made to them.
|
|
This counters attackers who insert unusual file types into the
|
|
source code.
|
|
However, this only works if the filesystem being analyzed can't
|
|
be modified by an attacker during the analysis, as recommended above.
|
|
This protection also doesn't work on Cygwin platforms, unfortunately.
|
|
.PP
|
|
Cygwin systems (Unix emulation on top of Windows)
|
|
have an additional problem if flawfinder is used to analyze
|
|
programs that the analyst cannot trust.
|
|
The problem is due to a design flaw in Windows (that it inherits from MS-DOS).
|
|
On Windows and MS-DOS, certain filenames (e.g., ``com1'') are
|
|
automatically treated by the operating system as the names of peripherals,
|
|
and this is true even when a full pathname is given.
|
|
Yes, Windows and MS-DOS really are designed this badly.
|
|
Flawfinder deals with this by checking what a filesystem object is,
|
|
and then only opening directories and regular files
|
|
(and symlinks if enabled).
|
|
Unfortunately, this doesn't work on Cygwin; on at least some versions
|
|
of Cygwin on some versions of Windows,
|
|
merely trying to determine if a file is a device type
|
|
can cause the program to hang.
|
|
A workaround is to delete or rename any filenames that are interpreted
|
|
as device names before performing the analysis.
|
|
These so-called ``reserved names'' are CON, PRN, AUX, CLOCK$, NUL,
|
|
COM1-COM9, and LPT1-LPT9, optionally followed by an extension
|
|
(e.g., ``com1.txt''), in any directory, and in any case
|
|
(Windows is case-insensitive).
|
|
.\" See 'Writing Secure Code' by Howard and LeBlanc, pg. 223
|
|
.PP
|
|
Do \fInot\fR load or diff hitlists from untrusted sources.
|
|
They are implemented using the Python pickle module, and the pickle
|
|
module is not intended to be secure against
|
|
erroneous or maliciously constructed data.
|
|
Stored hitlists are intended for later use by the same user who created
|
|
the hitlist; in that context this restriction is not a problem.
|
|
|
|
.SH BUGS
|
|
.PP
|
|
Flawfinder is based on simple text pattern matching, which is
|
|
part of its fundamental design and not easily changed.
|
|
This design approach leads to a number of fundamental limitations, e.g.,
|
|
a higher false positive rate, and is the underlying cause of
|
|
most of the bugs listed here.
|
|
On the positive side, flawfinder doesn't get confused by many
|
|
complicated preprocessor sequences that other tools sometimes choke on;
|
|
flawfinder can often handle code that cannot link, and sometimes
|
|
cannot even compile or build.
|
|
.PP
|
|
Flawfinder is currently limited to C/C++.
|
|
In addition, when analyzing C++ it focuses primarily on the C subset of C++.
|
|
For example, flawfinder does not report on expressions like cin >> charbuf,
|
|
where charbuf is a char array.
|
|
That is because flawfinder doesn't have type information,
|
|
and ">>" is safe with many other types; reporting on all ">>"
|
|
would lead to too many false positives.
|
|
That said,
|
|
it's designed so that adding support for other languages should be easy
|
|
where its text-based approach can usefully apply.
|
|
.PP
|
|
Flawfinder can be fooled by user-defined functions or method names that
|
|
happen to be the same as those defined as ``hits'' in its database,
|
|
and will often trigger on definitions (as well as uses) of functions
|
|
with the same name.
|
|
This is typically not a problem for C code.
|
|
In C code, a function with the same name as a common library routine name
|
|
often indicates that the developer is simply rewriting a
|
|
common library routine with the same interface, say for portability's sake.
|
|
C programs tend to avoid reusing the same name for a different purpose
|
|
(since in C function names are global by default).
|
|
There are reasonable odds that
|
|
these rewritten routines will be vulnerable to the same kinds of misuse,
|
|
and thus, reusing these rules is a reasonable approach.
|
|
However, this can be a much more serious problem in C++
|
|
code which heavily uses classes and namespaces, since the
|
|
same method name may have many different meanings.
|
|
The \-\-falsepositive option can help somewhat in this case.
|
|
If this is a serious problem, feel free to modify the program, or process
|
|
the flawfinder output through other tools to remove the false positives.
|
|
.PP
|
|
Preprocessor commands embedded in the middle of a parameter list
|
|
of a call can cause problems in parsing, in particular, if a string
|
|
is opened and then closed multiple times using an #ifdef .. #else
|
|
construct, flawfinder gets confused.
|
|
Such constructs are bad style, and will confuse many other tools too.
|
|
If you must analyze such files, rewrite those lines.
|
|
Thankfully, these are quite rare.
|
|
.PP
|
|
Flawfinder reports vulnerabilities regardless of the parameters of
|
|
"#if" or "#ifdef".
|
|
A construct "#if VALUE" will often have VALUE of 0 in some cases, and
|
|
non-zero in others.
|
|
Similarly, "#ifdef VALUE" will have VALUE defined in some cases, and
|
|
not defined in others.
|
|
Flawfinder reports in all cases, which
|
|
means that flawfinder has a chance of reporting vulnerabilities in
|
|
all alternatives.
|
|
This is not a bug, this is intended behavior.
|
|
.PP
|
|
Flawfinder will report hits even if they are between
|
|
a literal "#if 0" and "#endif".
|
|
It would be possible to change this particular situation, but directly
|
|
using "#if 0" to comment-out code (other than during debugging) is itself
|
|
that the removal is very temporary (in which case we should report it) or
|
|
an indicator of a problem with poor code practices.
|
|
If you want to permanently get rid of code, then
|
|
delete it instead of using "#if 0", since you can always see what it was
|
|
using your version control software.
|
|
If you don't use version control software, then that's the bug
|
|
you need to fix right now.
|
|
.PP
|
|
Some complex or unusual constructs can mislead flawfinder.
|
|
In particular, if a parameter begins with gettext(" and ends with ),
|
|
flawfinder will presume that the parameter of gettext is a constant.
|
|
This means it will get confused by patterns like
|
|
gettext("hi") + function("bye").
|
|
In practice, this doesn't seem to be a problem; gettext() is usually
|
|
wrapped around the entire parameter.
|
|
.PP
|
|
The routine to detect statically defined character arrays uses
|
|
simple text matching; some complicated expressions can cause it to
|
|
trigger or not trigger unexpectedly.
|
|
.PP
|
|
Flawfinder looks for specific patterns known to be common mistakes.
|
|
Flawfinder (or any tool like it) is not a good tool for finding intentionally
|
|
malicious code (e.g., Trojan horses); malicious programmers can easily
|
|
insert code that would not be detected by this kind of tool.
|
|
.PP
|
|
Flawfinder looks for specific patterns known to be common mistakes
|
|
in application code.
|
|
Thus, it is likely to be less effective
|
|
analyzing programs that aren't application-layer code
|
|
(e.g., kernel code or self-hosting code).
|
|
The techniques may still be useful; feel free to replace the database
|
|
if your situation is significantly different from normal.
|
|
.PP
|
|
Flawfinder's default output format (filename:linenumber, followed optionally
|
|
by a :columnnumber) can be misunderstood if any source files have
|
|
very weird filenames.
|
|
Filenames embedding a newline/linefeed character will cause odd breaks,
|
|
and filenames including colon (:) are likely to be misunderstood.
|
|
This is especially important if flawfinder's output is being used
|
|
by other tools, such as filters or text editors.
|
|
If you are using flawfinder's output in other tools, consider using its
|
|
CSV format instead (which can handle this).
|
|
If you're looking at new code, examine the files for such characters.
|
|
It's incredibly unwise to have such filenames anyway;
|
|
many tools can't handle such filenames at all.
|
|
Newline and linefeed are often used as internal data delimeters.
|
|
The colon is often used as special characters in filesystems:
|
|
MacOS uses it as a directory separator, Windows/MS-DOS uses it
|
|
to identify drive letters, Windows/MS-DOS inconsistently uses it
|
|
to identify special devices like CON:, and applications on many platforms
|
|
use the colon to identify URIs/URLs.
|
|
Filenames including spaces and/or tabs don't cause problems for flawfinder,
|
|
though note that other tools might have problems with them.
|
|
.PP
|
|
Flawfinder is not internationalized, so it currently
|
|
does not support localization.
|
|
.PP
|
|
In general, flawfinder attempts to err on the side of caution; it tends
|
|
to report hits, so that they can be examined further, instead of silently
|
|
ignoring them.
|
|
Thus, flawfinder prefers to have false positives (reports that
|
|
turn out to not be problems) rather than false negatives
|
|
(failures to report security vulnerabilities).
|
|
But this is a generality; flawfinder uses simplistic heuristics and
|
|
simply can't get everything "right".
|
|
.PP
|
|
Security vulnerabilities might not be identified as such by flawfinder,
|
|
and conversely, some hits aren't really security vulnerabilities.
|
|
This is true for all static security scanners, and is especially true
|
|
for tools like flawfinder that use a simple lexical analysis and
|
|
pattern analysis to identify potential vulnerabilities.
|
|
Still, it can serve as a useful aid for humans, helping to identify
|
|
useful places to examine further, and that's the point of this simple tool.
|
|
|
|
.SH "SEE ALSO"
|
|
See the flawfinder website at https://dwheeler.com/flawfinder.
|
|
You should also see the
|
|
.I "Secure Programming HOWTO"
|
|
at
|
|
.IR "https://dwheeler.com/secure-programs" .
|
|
|
|
.SH AUTHOR
|
|
David A. Wheeler (dwheeler@dwheeler.com).
|