Skip to content

Commit

Permalink
Users can now specify /dev/null for output files
Browse files Browse the repository at this point in the history
  • Loading branch information
andresriancho committed Mar 28, 2019
1 parent 97c019d commit 7ad600d
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 18 deletions.
11 changes: 11 additions & 0 deletions w3af/core/data/options/output_file_option.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
from w3af.core.data.options.option_types import OUTPUT_FILE
from w3af.core.data.fuzzer.utils import rand_alpha

DEV_NULL = '/dev/null'


class OutputFileOption(BaseOption):

Expand All @@ -45,6 +47,15 @@ def validate(self, value):

expanded_path = os.path.expanduser(value)

# In some scenarios we want to allow the end-user to choose an output
# file that doesn't actually write to disk
#
# For example, in output.text_file the user might want to log to the
# text log, but doesn't care about the HTTP requests and responses. In
# that case the user specifies /dev/null as the output
if expanded_path == '/dev/null':
return value

# This is useful for testing, the user specifies a script with $rnd$ in the
# output file name, w3af will replace that string with 5 random chars.
#
Expand Down
57 changes: 39 additions & 18 deletions w3af/plugins/output/text_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from w3af.core.controllers.exceptions import BaseFrameworkException
from w3af.core.data.options.opt_factory import opt_factory
from w3af.core.data.options.option_types import OUTPUT_FILE
from w3af.core.data.options.output_file_option import DEV_NULL
from w3af.core.data.options.option_list import OptionList


Expand Down Expand Up @@ -58,7 +59,7 @@ def __init__(self):
self._initialized = False

# File handlers
self._file = None
self._log = None
self._http = None

# XXX Only set '_show_caller' to True for debugging purposes. It
Expand All @@ -74,7 +75,7 @@ def _init(self):
self._http_file_name = os.path.expanduser(self._http_file_name)

try:
self._file = open(self._output_file_name, 'w')
self._log = open(self._output_file_name, 'w')
except IOError, io:
msg = 'Can\'t open report file "%s" for writing, error: %s.'
args = (os.path.abspath(self._output_file_name), io.strerror)
Expand All @@ -84,6 +85,10 @@ def _init(self):
args = (os.path.abspath(self._output_file_name), e)
raise BaseFrameworkException(msg % args)

if self._http_file_name == DEV_NULL:
# The user wants to ignore output to this file
return

try:
# Images aren't ascii, so this file that logs every request/response,
# will be binary.
Expand All @@ -103,22 +108,22 @@ def _write_to_file(self, msg, flush=False):
:param msg: The text to write.
"""
if self._file is None:
if self._log is None:
return

try:
self._file.write(msg)
self._log.write(msg)
except Exception, e:
self._file = None
self._log = None
msg = ('An exception was raised while trying to write to the output'
' file "%s", error: "%s". Disabling output to this file.')
om.out.error(msg % (self._output_file_name, e),
ignore_plugins={self.get_name()})

if flush and self._file is not None:
self._file.flush()
if flush and self._log is not None:
self._log.flush()

def _write_to_HTTP_log(self, msg):
def _write_to_http_log(self, msg):
"""
Write to the HTTP log file.
Expand All @@ -142,8 +147,8 @@ def flush(self):
flush() the cache disk
:return: None
"""
if self._file is not None:
self._file.flush()
if self._log is not None:
self._log.flush()

if self._http is not None:
self._http.flush()
Expand Down Expand Up @@ -263,8 +268,8 @@ def end(self):
if self._http is not None:
self._http.close()

if self._file is not None:
self._file.close()
if self._log is not None:
self._log.close()

def set_options(self, option_list):
"""
Expand Down Expand Up @@ -309,18 +314,31 @@ def log_http(self, request, response):
:param request: A fuzzable request object
:param response: A HTTPResponse object
"""
if self._http_file_name == DEV_NULL:
# We could open() /dev/null, write to that file, and leave the code
# as-is (without this if statement).
#
# But that would require w3af to dump() request and response,
# serialize all that into strings, and write them to /dev/null
#
# After all the CPU effort, that data will be discarded... a complete
# waste of time!
#
# So we just check if the output is /dev/null and return
return

now = time.localtime(time.time())
the_time = time.strftime("%c", now)

request_hdr = REQUEST_HEADER_FMT % (response.id, the_time)
self._write_to_HTTP_log(request_hdr)
self._write_to_HTTP_log(request.dump())
self._write_to_http_log(request_hdr)
self._write_to_http_log(request.dump())

response_hdr = RESPONSE_HEADER_FMT % (response.id, the_time)
self._write_to_HTTP_log(response_hdr)
self._write_to_HTTP_log(response.dump())
self._write_to_http_log(response_hdr)
self._write_to_http_log(response.dump())

self._write_to_HTTP_log('\n' + '=' * (len(request_hdr) - 1) + '\n')
self._write_to_http_log('\n' + '=' * (len(request_hdr) - 1) + '\n')

def get_long_desc(self):
"""
Expand All @@ -329,8 +347,11 @@ def get_long_desc(self):
return """
This plugin writes the framework messages to a text file.
Four configurable parameters exist:
Three configurable parameters exist:
- output_file
- http_output_file
- verbose
Use `dev/null` as the value for any of the output file options to
disable writing to that log.
"""

0 comments on commit 7ad600d

Please sign in to comment.