Statistics
| Branch: | Tag: | Revision:

root / snf-webproject / synnefo / webproject / exception_filter.py @ a868c831

History | View | Annotate | Download (4.4 kB)

1 0fa71fcc Christos Stavrakakis
# Copyright 2013 GRNET S.A. All rights reserved.
2 0fa71fcc Christos Stavrakakis
#
3 0fa71fcc Christos Stavrakakis
# Redistribution and use in source and binary forms, with or
4 0fa71fcc Christos Stavrakakis
# without modification, are permitted provided that the following
5 0fa71fcc Christos Stavrakakis
# conditions are met:
6 0fa71fcc Christos Stavrakakis
#
7 0fa71fcc Christos Stavrakakis
#   1. Redistributions of source code must retain the above
8 0fa71fcc Christos Stavrakakis
#      copyright notice, this list of conditions and the following
9 0fa71fcc Christos Stavrakakis
#      disclaimer.
10 0fa71fcc Christos Stavrakakis
#
11 0fa71fcc Christos Stavrakakis
#   2. Redistributions in binary form must reproduce the above
12 0fa71fcc Christos Stavrakakis
#      copyright notice, this list of conditions and the following
13 0fa71fcc Christos Stavrakakis
#      disclaimer in the documentation and/or other materials
14 0fa71fcc Christos Stavrakakis
#      provided with the distribution.
15 0fa71fcc Christos Stavrakakis
#
16 0fa71fcc Christos Stavrakakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 0fa71fcc Christos Stavrakakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 0fa71fcc Christos Stavrakakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 0fa71fcc Christos Stavrakakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 0fa71fcc Christos Stavrakakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 0fa71fcc Christos Stavrakakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 0fa71fcc Christos Stavrakakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 0fa71fcc Christos Stavrakakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 0fa71fcc Christos Stavrakakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 0fa71fcc Christos Stavrakakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 0fa71fcc Christos Stavrakakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 0fa71fcc Christos Stavrakakis
# POSSIBILITY OF SUCH DAMAGE.
28 0fa71fcc Christos Stavrakakis
#
29 0fa71fcc Christos Stavrakakis
# The views and conclusions contained in the software and
30 0fa71fcc Christos Stavrakakis
# documentation are those of the authors and should not be
31 0fa71fcc Christos Stavrakakis
# interpreted as representing official policies, either expressed
32 0fa71fcc Christos Stavrakakis
# or implied, of GRNET S.A.
33 0fa71fcc Christos Stavrakakis
34 0fa71fcc Christos Stavrakakis
from django.conf import settings
35 0fa71fcc Christos Stavrakakis
from django.views.debug import SafeExceptionReporterFilter
36 0fa71fcc Christos Stavrakakis
from django.http import HttpRequest, build_request_repr
37 0fa71fcc Christos Stavrakakis
38 0fa71fcc Christos Stavrakakis
HIDDEN_ALL = settings.HIDDEN_COOKIES + settings.HIDDEN_HEADERS
39 0fa71fcc Christos Stavrakakis
CLEANSED_SUBSTITUTE = u'********************'
40 0fa71fcc Christos Stavrakakis
41 0fa71fcc Christos Stavrakakis
42 0fa71fcc Christos Stavrakakis
class SynnefoExceptionReporterFilter(SafeExceptionReporterFilter):
43 0fa71fcc Christos Stavrakakis
    def is_active(self, request):
44 0fa71fcc Christos Stavrakakis
        # Ignore DEBUG setting. Always active filtering!
45 0fa71fcc Christos Stavrakakis
        return True
46 0fa71fcc Christos Stavrakakis
47 0fa71fcc Christos Stavrakakis
    def get_traceback_frame_variables(self, request, tb_frame):
48 0fa71fcc Christos Stavrakakis
        sensitive_variables = HIDDEN_ALL
49 0fa71fcc Christos Stavrakakis
        cleansed = []
50 0fa71fcc Christos Stavrakakis
        if self.is_active(request) and sensitive_variables:
51 0fa71fcc Christos Stavrakakis
            if sensitive_variables == '__ALL__':
52 0fa71fcc Christos Stavrakakis
                # Cleanse all variables
53 0fa71fcc Christos Stavrakakis
                for name, value in tb_frame.f_locals.items():
54 0fa71fcc Christos Stavrakakis
                    cleansed.append((name, CLEANSED_SUBSTITUTE))
55 0fa71fcc Christos Stavrakakis
                return cleansed
56 0fa71fcc Christos Stavrakakis
            else:
57 0fa71fcc Christos Stavrakakis
                # Cleanse specified variables
58 0fa71fcc Christos Stavrakakis
                for name, value in tb_frame.f_locals.items():
59 0fa71fcc Christos Stavrakakis
                    if name in sensitive_variables:
60 0fa71fcc Christos Stavrakakis
                        value = CLEANSED_SUBSTITUTE
61 0fa71fcc Christos Stavrakakis
                    elif isinstance(value, HttpRequest):
62 0fa71fcc Christos Stavrakakis
                        # Cleanse the request's POST parameters.
63 0fa71fcc Christos Stavrakakis
                        value = self.get_request_repr(value)
64 0fa71fcc Christos Stavrakakis
                    cleansed.append((name, value))
65 0fa71fcc Christos Stavrakakis
                return cleansed
66 0fa71fcc Christos Stavrakakis
        else:
67 0fa71fcc Christos Stavrakakis
            # Potentially cleanse only the request if it's one of the frame
68 0fa71fcc Christos Stavrakakis
            # variables.
69 0fa71fcc Christos Stavrakakis
            for name, value in tb_frame.f_locals.items():
70 0fa71fcc Christos Stavrakakis
                if isinstance(value, HttpRequest):
71 0fa71fcc Christos Stavrakakis
                    # Cleanse the request's POST parameters.
72 0fa71fcc Christos Stavrakakis
                    value = self.get_request_repr(value)
73 0fa71fcc Christos Stavrakakis
                cleansed.append((name, value))
74 0fa71fcc Christos Stavrakakis
            return cleansed
75 0fa71fcc Christos Stavrakakis
76 0fa71fcc Christos Stavrakakis
    def get_request_repr(self, request):
77 0fa71fcc Christos Stavrakakis
        if request is None:
78 0fa71fcc Christos Stavrakakis
            return repr(None)
79 0fa71fcc Christos Stavrakakis
        else:
80 0fa71fcc Christos Stavrakakis
            # Use custom method method to build the request representation
81 0fa71fcc Christos Stavrakakis
            # where all sensitive values will be cleansed
82 0fa71fcc Christos Stavrakakis
            _repr = self.build_request_repr(request)
83 0fa71fcc Christos Stavrakakis
            # Respect max mail size
84 0fa71fcc Christos Stavrakakis
            if len(_repr) > settings.MAIL_MAX_LEN:
85 0fa71fcc Christos Stavrakakis
                _repr += "Mail size over limit (truncated)\n\n" + _repr
86 0fa71fcc Christos Stavrakakis
            return _repr[:settings.MAIL_MAX_LEN]
87 0fa71fcc Christos Stavrakakis
88 0fa71fcc Christos Stavrakakis
    def build_request_repr(self, request):
89 0fa71fcc Christos Stavrakakis
        cleansed = {}
90 0fa71fcc Christos Stavrakakis
        for fields in ["GET", "POST", "COOKIES", "META"]:
91 0fa71fcc Christos Stavrakakis
            _cleansed = getattr(request, fields).copy()
92 0fa71fcc Christos Stavrakakis
            for key in _cleansed.keys():
93 0fa71fcc Christos Stavrakakis
                for hidden in HIDDEN_ALL:
94 0fa71fcc Christos Stavrakakis
                    if hidden in key:
95 0fa71fcc Christos Stavrakakis
                        _cleansed[key] = CLEANSED_SUBSTITUTE
96 0fa71fcc Christos Stavrakakis
            cleansed[fields] = _cleansed
97 0fa71fcc Christos Stavrakakis
        return build_request_repr(request,
98 0fa71fcc Christos Stavrakakis
                                  GET_override=cleansed["GET"],
99 0fa71fcc Christos Stavrakakis
                                  POST_override=cleansed["POST"],
100 0fa71fcc Christos Stavrakakis
                                  COOKIES_override=cleansed["COOKIES"],
101 0fa71fcc Christos Stavrakakis
                                  META_override=cleansed["META"])