Add ability to search in warnings (e.g., for CWEs), and document that

This commit is contained in:
David A. Wheeler 2014-07-13 13:19:50 -04:00
parent 620a6df894
commit bd3bd7dae5
2 changed files with 64 additions and 8 deletions

View File

@ -65,6 +65,8 @@ showheading = 1 # --dataonly turns this off
output_format = 0 # 0 = normal, 1 = html. output_format = 0 # 0 = normal, 1 = html.
single_line = 0 # 1 = singleline (can 't be 0 if html) single_line = 0 # 1 = singleline (can 't be 0 if html)
omit_time = 0 # 1 = omit time-to-run (needed for testing) omit_time = 0 # 1 = omit time-to-run (needed for testing)
required_regex = None # If non-None, regex that must be met to report
required_regex_compiled = None
displayed_header = 0 # Have we displayed the header yet? displayed_header = 0 # Have we displayed the header yet?
num_ignored_hits = 0 # Number of ignored hits (used if never_ignore==0) num_ignored_hits = 0 # Number of ignored hits (used if never_ignore==0)
@ -393,6 +395,8 @@ hitlist = []
def add_warning(hit): def add_warning(hit):
global hitlist, num_ignored_hits global hitlist, num_ignored_hits
if show_inputs and not hit.input: return if show_inputs and not hit.input: return
if required_regex and (required_regex_compiled.search(hit.warning) is None):
return
if hit.level >= minimum_level: if hit.level >= minimum_level:
if linenumber == ignoreline: if linenumber == ignoreline:
num_ignored_hits = num_ignored_hits + 1 num_ignored_hits = num_ignored_hits + 1
@ -1612,6 +1616,8 @@ flawfinder [--help | -h] [--listrules] [--version]
--neverignore | -n --neverignore | -n
Never ignore security issues, even if they have an ``ignore'' Never ignore security issues, even if they have an ``ignore''
directive in a comment. directive in a comment.
--regex PATTERN | -e PATTERN
Only report hits that match the regular expression PATTERN.
Selecting Output Format: Selecting Output Format:
--columns Show the column number (as well as the file name and --columns Show the column number (as well as the file name and
@ -1649,18 +1655,20 @@ flawfinder [--help | -h] [--listrules] [--version]
def process_options(): def process_options():
global show_context, show_inputs, allowlink, skipdotdir, omit_time global show_context, show_inputs, allowlink, skipdotdir, omit_time
global output_format, minimum_level, show_immediately, single_line global output_format, minimum_level, show_immediately, single_line
global required_regex, required_regex_compiled
global falsepositive global falsepositive
global show_columns, never_ignore, quiet, showheading, list_rules global show_columns, never_ignore, quiet, showheading, list_rules
global loadhitlist, savehitlist, diffhitlist global loadhitlist, savehitlist, diffhitlist
global patch_file global patch_file
try: try:
# Note - as a side-effect, this sets sys.argv[]. # Note - as a side-effect, this sets sys.argv[].
optlist, args = getopt.getopt(sys.argv[1:], "cm:nih?CSDQIFP:", optlist, args = getopt.getopt(sys.argv[1:], "ce:m:nih?CSDQIFP:",
["context", "minlevel=", "immediate", "inputs", "input", ["context", "minlevel=", "immediate", "inputs", "input",
"nolink", "falsepositive", "falsepositives", "nolink", "falsepositive", "falsepositives",
"columns", "listrules", "omittime", "allowlink", "patch=", "columns", "listrules", "omittime", "allowlink", "patch=",
"followdotdir", "followdotdir",
"neverignore", "quiet", "dataonly", "html", "singleline", "neverignore", "regex=",
"quiet", "dataonly", "html", "singleline",
"loadhitlist=", "savehitlist=", "diffhitlist=", "loadhitlist=", "savehitlist=", "diffhitlist=",
"version", "help" ]) "version", "help" ])
for (opt,value) in optlist: for (opt,value) in optlist:
@ -1698,6 +1706,10 @@ def process_options():
show_immediately = 1 show_immediately = 1
elif opt == "-n" or opt == "--neverignore": elif opt == "-n" or opt == "--neverignore":
never_ignore = 1 never_ignore = 1
elif opt == "-e" or opt == "--regex":
required_regex = value
# This will raise an exception if it can't be compiled as a regex:
required_regex_compiled = re.compile(required_regex)
elif opt == "-P" or opt == "--patch": elif opt == "-P" or opt == "--patch":
# Note: This is -P, so that a future -p1 option can strip away # Note: This is -P, so that a future -p1 option can strip away
# pathname prefixes (with the same option name as "patch"). # pathname prefixes (with the same option name as "patch").
@ -1825,6 +1837,8 @@ def show_final_results():
# By computing time here, we also include the time for # By computing time here, we also include the time for
# producing the list of hits, which is reasonable. # producing the list of hits, which is reasonable.
time_analyzing = time.time() - starttime time_analyzing = time.time() - starttime
if required_regex:
print "Hits limited to regular expression " + required_regex
print "Lines analyzed = %d" % sumlines, print "Lines analyzed = %d" % sumlines,
if time_analyzing > 0 and not omit_time: # Avoid divide-by-zero. if time_analyzing > 0 and not omit_time: # Avoid divide-by-zero.
print "in approximately %.2f seconds (%.0f lines/second)" % ( print "in approximately %.2f seconds (%.0f lines/second)" % (

View File

@ -40,6 +40,7 @@ flawfinder \- find potential security flaws ("hits") in source code
[ \fB\-\-minlevel \fR\fIX\fR | \fB\-m\fR\ \fIX\fR ] [ \fB\-\-minlevel \fR\fIX\fR | \fB\-m\fR\ \fIX\fR ]
.RB [ \-\-falsepositive | \-F ] .RB [ \-\-falsepositive | \-F ]
.RB [ \-\-neverignore | \-n ] .RB [ \-\-neverignore | \-n ]
.RB [ \-\-regex | \-e ]
.br .br
.\" Selecting Output Format: .\" Selecting Output Format:
.RB [ \-\-context | \-c ] .RB [ \-\-context | \-c ]
@ -412,6 +413,16 @@ clauses and calls through function pointers will be missed.
Never ignore security issues, even if they have an ``ignore'' directive Never ignore security issues, even if they have an ``ignore'' directive
in a comment. in a comment.
.TP
.BI \-\-regexp PATTERN
.TP
.BI -e PATTERN
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" .SS "Selecting Output Format"
.TP 12 .TP 12
@ -682,18 +693,34 @@ of compilation error messages.
.SH COMMON WEAKNESS ENUMERATION (CWE) .SH COMMON WEAKNESS ENUMERATION (CWE)
.PP .PP
Hit descriptions typically include a relevant The Common Weakness Enumeration (CWE)
Common Weakness Enumeration (CWE) identifier in parentheses. 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 [that]
was 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 CWE.
Hit descriptions typically 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 For example, many of the buffer-related hits mention
CWE-120, the CWE identifier for CWE-120, the CWE identifier for
``buffer copy without checking size of input'' ``buffer copy without checking size of input''
(aka ``Classic Buffer Overflow''). (aka ``Classic Buffer Overflow'').
CWE version 2.7 (released June 23, 2014) was used. Flawfinder is designed to meet the CWE-Output requirement.
CWE version 2.7 (released June 23, 2014) was used for the mapping.
Note that many of these CWEs are identified in the CWE/SANS top 25 list Note that many of these CWEs are identified in the CWE/SANS top 25 list
(http://cwe.mitre.org/top25/). (http://cwe.mitre.org/top25/).
.PP .PP
Flawfinder can report the following CWEs:
.PP
Flawfinder can report on the following CWEs
(these are the CWEs that flawfinder covers):
CWE-22 CWE-22
CWE-78 CWE-78
CWE-119 CWE-119
@ -711,10 +738,25 @@ CWE-829.
.PP .PP
Flawfinder may fail to find a Flawfinder may fail to find a
vulnerability, even if it is covered by one of these weaknesses. vulnerability, even if the vulnerability
is covered by 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, flawfinder has a rate of false positives less than 100%,
and a rate of false negatives less than 100%, as required for
any tool intending to be CWE compatible.
.PP .PP
For more information on CWEs, see http://cwe.mitre.org. 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-119|CWE-120"''.
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.
.SH SECURITY .SH SECURITY