portal_review/notes.md
2020-02-29 15:53:46 +05:30

5.5 KiB

I divide the security points that I think are important into 3 classes: 1) Critical and 2) Other based on their importance and django recommendations.

Critical points

  1. DB Password in codebase

  2. SECRET_KEY in codebase and same in development and production

  3. Object level access control permission missing

  • I see the UserPermission class and I am assuming it is for managing object level permission but I am not sure how it is being used for object level permissions. By object permissions, I mean granting add/delete/change/view permissions on an object to a particular user or a group.
  • In Django we generally use the django-guardian module to accomplish this. https://django-guardian.readthedocs.io/en/stable/
  • Each object can be assigned permission specifically to a user or a group

For eg. the following (taken from https://django-guardian.readthedocs.io/en/stable/userguide/assign.html#assign-obj-perms)

    >>> from django.contrib.auth.models import User
    >>> boss = User.objects.create(username='Big Boss')
    >>> joe = User.objects.create(username='joe')
    >>> task = Task.objects.create(summary='Some job', content='', reported_by=boss)
    >>> joe.has_perm('assign_task', task)
    False

    >>> from guardian.shortcuts import assign_perm
    >>> assign_perm('assign_task', joe, task)
    >>> joe.has_perm('assign_task', task)
    True

The following code taken from payroll/views.py file lines 1119-1137

@login_required
def attachment_delete(request, pk):
    """
    Attachment löschen
    """
    # Attachment auswählen
    instance = Attachment.objects.get(id=pk)
    # Dateipfad ermitteln
    file_path = str(instance.attachment)
    # Physische Datei löschen
    try:
        os.remove(os.path.join(MEDIA_ROOT, file_path))
    except:
        pass
    # Instanz löschen
    instance.delete()

    # zurück zur Ursprungsseite
    return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))

Anyone who can login to the system, could potentially delete an attachment belonging to some other user, which may be disastrous. We could easily overcome this like the example from django-guardian above.

  1. I am not sure what exact Django version the app is designed for. I am assuming some version of Django 2.x.x. based on my attempt to run the project. It would be nice to check all vulnerabilities for this specific version of Django.

Standard Django app deployment checks

  • Check issues in manage.py check --deploy
(venv) [pcoder@archlinux portal]$ ./manage.py check --deploy
System check identified some issues:

WARNINGS:
?: (security.W004) You have not set a value for the SECURE_HSTS_SECONDS setting. If your entire site is served only over SSL, you may want to consider setting a value and enabling HTTP Strict Transport Security. Be sure to read the documentation first; enabling HSTS carelessly can cause serious, irreversible problems.
?: (security.W006) Your SECURE_CONTENT_TYPE_NOSNIFF setting is not set to True, so your pages will not be served with an 'x-content-type-options: nosniff' header. You should consider enabling this header to prevent the browser from identifying content types incorrectly.
?: (security.W007) Your SECURE_BROWSER_XSS_FILTER setting is not set to True, so your pages will not be served with an 'x-xss-protection: 1; mode=block' header. You should consider enabling this header to activate the browser's XSS filtering and help prevent XSS attacks.
?: (security.W008) Your SECURE_SSL_REDIRECT setting is not set to True. Unless your site should be available over both SSL and non-SSL connections, you may want to either set this setting True or configure a load balancer or reverse-proxy server to redirect all connections to HTTPS.
?: (security.W012) SESSION_COOKIE_SECURE is not set to True. Using a secure-only session cookie makes it more difficult for network traffic sniffers to hijack user sessions.
?: (security.W016) You have 'django.middleware.csrf.CsrfViewMiddleware' in your MIDDLEWARE, but you have not set CSRF_COOKIE_SECURE to True. Using a secure-only CSRF cookie makes it more difficult for network traffic sniffers to steal the CSRF token.
?: (security.W019) You have 'django.middleware.clickjacking.XFrameOptionsMiddleware' in your MIDDLEWARE, but X_FRAME_OPTIONS is not set to 'DENY'. The default is 'SAMEORIGIN', but unless there is a good reason for your site to serve other parts of itself in a frame, you should change it to 'DENY'.

Actions to take for the warnings above and as per the recommendations in the settings page https://django-secure.readthedocs.io/en/latest/settings.html

  1. Django's way to protect the project against XSS is to enable the following values
# For Xss filter See https://scotthelme.co.uk/x-xss-protection-1-mode-block-demo/
SECURE_BROWSER_XSS_FILTER = True
# See https://docs.djangoproject.com/en/dev/ref/middleware/#x-content-type-options-nosniff
SECURE_CONTENT_TYPE_NOSNIFF = True
  1. SSL and HSTS

Force/exempt ssl urls

# set to any regex of urls that need to be served over plain http
# https://django-secure.readthedocs.io/en/latest/settings.html#secure-ssl-redirect
SECURE_REDIRECT_EXEMPT = []
SECURE_SSL_HOST = None
SECURE_SSL_REDIRECT = False

Enable HSTS

# Make the production server to respond to https always or set the strict https settings iff for a single domain
SECURE_HSTS_INCLUDE_SUBDOMAINS=True
# 30 seconds or above based on whether increasing this value breaks something
SECURE_HSTS_SECONDS=30 seconds and above based on tests
SECURE_HSTS_PRELOAD = True