示例#1
0
    def _generic_send_error_handler(self, req, exception, grep, original_url):
        if not req.error_handling:
            msg = u'Raising HTTP error "%s" "%s". Reason: "%s". Error' \
                  u' handling was disabled for this request.'
            om.out.debug(msg % (req.get_method(), original_url, exception))
            error_str = get_exception_reason(exception) or str(exception)
            raise HTTPRequestException(error_str, request=req)

        # Log the error
        msg = u'Failed to HTTP "%s" "%s". Reason: "%s", going to retry.'
        om.out.debug(msg % (req.get_method(), original_url, exception))

        # Don't make a lot of noise on URLTimeoutError which is pretty common
        # and properly handled by this library
        if not isinstance(exception, URLTimeoutError):
            msg = 'Traceback for this error: %s'
            om.out.debug(msg % traceback.format_exc())

        with self._count_lock:
            self._log_failed_response(exception, req)

            should_stop_scan = self._should_stop_scan(req)
            if should_stop_scan:
                self._handle_error_count_exceeded(exception)

        # Then retry!
        req._Request__original = original_url
        return self._retry(req, grep, exception)
示例#2
0
    def _handle_error_count_exceeded(self, error):
        """
        Handle the case where we exceeded MAX_ERROR_COUNT
        """
        # Create a detailed exception message
        msg = ('w3af found too many consecutive errors while performing'
               ' HTTP requests. In most cases this means that the remote web'
               ' server is not reachable anymore, the network is down, or'
               ' a WAF is blocking our tests. The last exception message'
               ' was "%s" (%s.%s).')

        reason_msg = get_exception_reason(error)
        args = (error, error.__class__.__module__, error.__class__.__name__)

        # If I got a reason, it means that it is a known exception.
        if reason_msg is not None:
            # Stop using ExtendedUrllib instance
            e = ScanMustStopByKnownReasonExc(msg % args, reason=reason_msg)

        else:
            last_errors = []
            last_n_responses = list(self._last_responses)[-MAX_ERROR_COUNT:]

            for response_meta in last_n_responses:
                last_errors.append(response_meta.message)

            e = ScanMustStopByUnknownReasonExc(msg % args, errs=last_errors)

        self._stop_exception = e
        # pylint: disable=E0702
        raise self._stop_exception
示例#3
0
    def _generic_send_error_handler(self, req, exception, grep, original_url):
        if not req.error_handling:
            msg = u'Raising HTTP error "%s" "%s". Reason: "%s". Error' \
                  u' handling was disabled for this request.'
            om.out.debug(msg % (req.get_method(), original_url, exception))
            error_str = get_exception_reason(exception) or str(exception)
            raise HTTPRequestException(error_str, request=req)

        # Log the error
        msg = u'Failed to HTTP "%s" "%s". Reason: "%s", going to retry.'
        om.out.debug(msg % (req.get_method(), original_url, exception))

        # Don't make a lot of noise on URLTimeoutError which is pretty common
        # and properly handled by this library
        if not isinstance(exception, URLTimeoutError):
            msg = 'Traceback for this error: %s'
            om.out.debug(msg % traceback.format_exc())

        with self._count_lock:
            self._log_failed_response(exception, req)

            should_stop_scan = self._should_stop_scan(req)
            if should_stop_scan:
                self._handle_error_count_exceeded(exception)

        # Then retry!
        req._Request__original = original_url
        return self._retry(req, grep, exception)
示例#4
0
    def _handle_error_count_exceeded(self, error):
        """
        Handle the case where we exceeded MAX_ERROR_COUNT
        """
        # Create a detailed exception message
        msg = ('w3af found too many consecutive errors while performing'
               ' HTTP requests. In most cases this means that the remote web'
               ' server is not reachable anymore, the network is down, or'
               ' a WAF is blocking our tests. The last exception message'
               ' was "%s" (%s.%s).')

        reason_msg = get_exception_reason(error)
        args = (error,
                error.__class__.__module__,
                error.__class__.__name__)

        # If I got a reason, it means that it is a known exception.
        if reason_msg is not None:
            # Stop using ExtendedUrllib instance
            e = ScanMustStopByKnownReasonExc(msg % args, reason=reason_msg)

        else:
            last_errors = []
            last_n_responses = list(self._last_responses)[-MAX_ERROR_COUNT:]

            for response_meta in last_n_responses:
                last_errors.append(response_meta.message)

            e = ScanMustStopByUnknownReasonExc(msg % args, errs=last_errors)

        self._stop_exception = e
        # pylint: disable=E0702
        raise self._stop_exception
示例#5
0
    def _log_failed_response(self, error, request):
        """
        Add the failed response to the self._last_responses log, and if we got a
        lot of failures raise a "ScanMustStopException" subtype.

        :param error: Exception object.
        """
        reason = get_exception_reason(error)
        reason = reason or str(error)
        self._last_responses.append(
            ResponseMeta(False, reason, host=request.get_host()))

        self._log_error_rate()
示例#6
0
    def _log_failed_response(self, error, request):
        """
        Add the failed response to the self._last_responses log, and if we got a
        lot of failures raise a "ScanMustStopException" subtype.

        :param error: Exception object.
        """
        reason = get_exception_reason(error)
        reason = reason or str(error)
        self._last_responses.append(ResponseMeta(False, reason,
                                                 host=request.get_host()))

        self._log_error_rate()
示例#7
0
    def _retry(self, req, grep, url_error):
        """
        Try to send the request again while doing some error handling.
        """
        req.retries_left -= 1

        if req.retries_left > 0:
            msg = 'Re-sending request "%s" after initial exception: "%s"'
            om.out.debug(msg % (req, url_error))
            return self.send(req, grep=grep)

        else:
            # Please note that I'm raising HTTPRequestException and not a
            # ScanMustStopException (or subclasses) since I don't want the
            # scan to stop because of a single HTTP request failing.
            #
            # Actually we get here if one request fails three times to be sent
            # but that might be because of the http request itself and not a
            # fault of the framework/server/network.
            error_str = get_exception_reason(url_error) or str(url_error)
            raise HTTPRequestException(error_str, request=req)
示例#8
0
    def _retry(self, req, grep, url_error):
        """
        Try to send the request again while doing some error handling.
        """
        req.retries_left -= 1

        if req.retries_left > 0:
            msg = 'Re-sending request "%s" after initial exception: "%s"'
            om.out.debug(msg % (req, url_error))
            return self.send(req, grep=grep)
        
        else:
            # Please note that I'm raising HTTPRequestException and not a
            # ScanMustStopException (or subclasses) since I don't want the
            # scan to stop because of a single HTTP request failing.
            #
            # Actually we get here if one request fails three times to be sent
            # but that might be because of the http request itself and not a
            # fault of the framework/server/network.
            error_str = get_exception_reason(url_error) or str(url_error)
            raise HTTPRequestException(error_str, request=req)