flawfinder/flawfinder.1

1043 lines
42 KiB
Groff

'\"
.\" (C) Copyright 2001-2014 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 "19 Jul 2014" "Flawfinder" "Flawfinder"
.SH NAME
flawfinder \- lexically find potential security flaws ("hits") in source code
.SH SYNOPSIS
.B flawfinder
.\" Documentation:
.RB [ \-\-help ]
.RB [ \-\-listrules ]
.RB [ \-\-version ]
.br
.\" Selecting Input Data:
.RB [ \-\-allowlink ]
.RB [ \-\-followdotdir ]
.RB [ \-\-nolink ]
.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 ]
.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 [ \-\-dataonly | \-D ]
.RB [ \-\-html ]
.RB [ \-\-immediate | -i ]
.RB [ \-\-singleline | \-S ]
.RB [ \-\-omittime ]
.RB [ \-\-quiet | \-Q ]
.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.
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), 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 most 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.
.PP
Not every hit 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 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 linked, and in some cases, cannot even be compiled.
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.
.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", ".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 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.
.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 "http://www.dwheeler.com/secure-programs"
.I "Writing Secure Programs for Linux and Unix HOWTO"
.UE
at
http://www.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.
Flawfinder supports the standard syntax defined in the
POSIX (Issue 7, 2013 Edition) section ``Utility Conventions''.
It 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''.
Some options can only be accessed using the more
readable GNU long option conventions;
common options are also supported
by the older single-letter option convention.
.SS "Documentation"
.TP 12
.BI \-\-help
.TP
.BI \-h
.\" Leave -? undocumented... it also invokes help.
Show usage (help) information.
.TP 12
.BI \-\-listrules
List the terms that trigger further examination, their default risk level,
and the default warning (including the CWE identifier(s), if applicable),
all tab-separated.
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.
Note that version 1.29 changed the separator from spaces to tabs, and
added the default warning field.
.TP
.BI \-\-version
Shows (just) the version number and exits.
.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, configurations, 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 by 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.
.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 "\-\-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
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.
.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.
Do not load hitlists from untrusted sources.
.TP
\fB\-\-diffhitlist=\fR\fIF\fR
Show only hits (loaded or analyzed) not in F.
F was presumably created previously using \-\-savehitlist.
Do not diff hitlists from untrusted sources.
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.
.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 -QD mydir"
Examine mydir and report only the actual results
(removing the header and footer of the output).
This form is useful
if the output will be piped into other tools for further analysis.
The \-C (\-\-columns) and \-S (\-\-singleline)
options can also be useful if you're piping the data
into 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 recent.patch.
.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''
(http://cwe.mitre.org/about/faq.html).
For more information on CWEs, see http://cwe.mitre.org.
.PP
Flawfinder supports the CWE.
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.
Note that many of these CWEs are identified in the CWE/SANS top 25 list
2011 (http://cwe.mitre.org/top25/).
.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-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
.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-807: Reliance on Untrusted Inputs in a Security Decision*
.IP \(bu
CWE-829: Inclusion of Functionality from Untrusted Control Sphere*
.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 listed above.
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
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''.
However, while this procedure lists all CWE security elements,
this procedure 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 http://www.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 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 not load or diff hitlists from untrusted sources.
They are implemented using the Python pickle module, which is not
intended to be secure against erroneous or maliciously constructed data.
.SH BUGS
Flawfinder is currently limited to C/C++.
In addition, when analyzing C++ it focuses primarily on the C subset of C++.
That said,
it's designed so that adding support for other languages should be easy.
.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 because flawfinder is based on text pattern matching, which is
part of its fundamental design and not easily changed.
This isn't as much of a problem for C code, but it can be more of a problem
for some C++ code which heavily uses classes and namespaces.
On the positive side, flawfinder doesn't get confused by many
complicated preprocessor sequences that other tools sometimes choke on.
Also, having the same name as a common library routine name can
indicate that the developer is simply rewriting a common library routine,
say for portability's sake.
Thus, there are reasonable odds that
these rewritten routines will be vulnerable to the same kinds of misuse.
The \-\-falsepositive option can help somewhat.
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
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 expresions 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 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'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
(failure to report on a security vulnerability).
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 http://www.dwheeler.com/flawfinder.
You should also see the
.I "Secure Programming for Unix and Linux HOWTO"
at
.IR "http://www.dwheeler.com/secure-programs" .
.SH AUTHOR
David A. Wheeler (dwheeler@dwheeler.com).