Alex's Notes

CM3035 Topic 08: User Authentication and Security

:ID: a9098ba6-4ddb-4768-b8bb-1bc64652b09a

Main Info

Description

Auth and stuff.

Key Reading

Attacks

Protection

HTTPS

Vulnerability Diagnostics

Authentication

Lecture Summaries

8.1 Attacks

Cross Site Scripting (XSS)

XSS is a code injection attack. The attacker wants to run malicious JS on a target’s machine. To do this, they add it to a benign/trusted site, that unwittingly hosts the code.

There are stored and reflected variations of XSS.

Stored XSS attacks

here js is stored remotely, on the benign website. For example if the site is a forum, or includes comments, the user can post a piece of malicious js as a comment, and it will then be stored in the server.

When a second client comes to fetch the comments, they do so trusting the site, but if the site is badly set up that script might then execute on page render.

Reflected XSS attacks

Here the attack is via a non-direct route. generally there would be a link from a non-direct source - for example in an email, or link on a malicious website, the link contains code to execute and it sent to a legitimate site.

The legitimate site raises a response (error) which contains the data/script.

Client sees response is from a legitimate site and executes the code.

IE the attack vector here is that the response comes from a legit site, but includes the original bad script/data from the malicious site. this might then execute.

To prevent, we just have to sanitize input. In a stored case, we sanitize all input before storing to the db. In a reflected case, we must ensure all responses do not contain code.

8.104 CORS

Cross-Origin Resource Sharing (or CORS) is a means to work around browser default policies around resource origins.

Browsers typically enforce a Same Origin Policy. When I load a page from one domain, the returned resources (html, js) are only allowed to fetch resources from the same domain.

CORS settings allow us to set things up such that web applications are allowed to share resources to circumvent this restriction. EG they let us host our files, images etc on different servers to our html and js.

It allows our clients to make API requests to resources that are not on the API source domain.

CORS attacks are possible when we misconfigure the settings.

We can end up exposing resources that are not meant to be shared, like APIs, fonts, images.

there are two settings that we can misconfigure to expose ourselves to this:

Access-Control-Allow-Origin

  • we should whitelist domains

  • do not wildcard

  • do not set as null

Access-Control-Allow-Credentials

  • do not set as null

  • prevents use of wildcards in Allow-Origin for credentialled requests.

8.107 Denial of Service

DoS or DDoS (distributed version) is an attempt to take a resource/site offline.

Commonly the pattern is to flood the server with requests, which eventually blocks access for legitimate users.

You might have the site allocate too many resources - if you saturate the system threads it can’t run more, or you could overload its memory.

Or you force the server not to release resources - keep connections open.

or you might try to upload loads of data to force it to run out of storage space.

To remediate these we might increase resources - bigger disks/dbs, more servers, CDN.

8.110 Buffer Overflow

Common attack for many types of software, including servers.

An attempt to crash a running process, or use the process to execute malicious code.

One means is by sending too much data to some input, if the input length is not checked the data might write over memory when it should not be. This might cause a crash or insert code into memory which is then executed.

Mitigation: We ensure buffers are sufficient length, we sanitise inputs, check lengths of input data.

8.113 SQL Injection

An attempt to submit data via a service from an untrusted source.

Data will cause malicious SQL to run in the application.

Read, dump or send database contents, or destroy a datastore

Execute commands with higher privileges or even unix terminal access

Common attack on PHP and ASP

Remediation: sanitise all inputs. Construct SQL programmatically (eg use ORM), never execute user inputs. Ensure database runs with a low privileged user.

8.118 Cross Site Request Forgery (CSRF)

Attempt to trick a user into sending a malicious request

User is authenticated legitimately

User follows a link provided by an illegitimate source that will send malicious data into our application.

Solutions: Set CORS policies correctly.

Forms have a per-request form-key that identifies the form is legitimately from our website.

Users ensure they are logged out of sites when they finish. Expiry time for auto-logout.

8.119 Clickjacking

This is the UI redress attack.

An attempt by the attacker to insert a ‘layer’ between the user and legitimate site.

The attacker can use the layer to capture user events (eg keystrokes, mouse actions)

The attacker passes it through to the website so the attack is invisible.

Typically uses an HTML frame to load a transparent layer.

To defend against it we can set the servers’ Content Security Policy frame ancestors directive to not allow framing. Ensure UI is sitting at the top level, not nested in frames.

8.2 Making Sites Secure

8.201 Web app built in security

Most modern web frameworks provide built in security features:

xss protection - we can use Django templating here, which will escape where possible.

Templating won’t always help though, let’s say we have a <div class='{{var}}'>. Then the user manages to set var to 'class1 onclick=javascript:malicious_function()' then the result will be <div class=class1 onlclick=javascript:malicious_function().

So you need to check user input.

csrf protection - enable csrf middleware, ensure {%csrf_token()%} is included in all forms, this ensures all form submissions have a unique token.

sql injection protection - model querysets are safe from incoming SQL, minimize use of raw, custom sql. Sanitise any user inputs of raw, custom sql.

clickjacking protection - enable x-frame-options middleware, ensure sites can not be rendered inside third-party site.

HTTPS

HTTPS is the cryptographically secure extension of HTTP. All HTTP messages are encrypted, making use of TLS (Transport Layer Security) that requires a third party certificate authority.

TLS is a means of encrypting data that runs over a reliable transport protocol (typically TCP).

The rough outline is:

  1. Client issues a secure connection request

  2. Server agrees and returns a certificate

  3. Client checks certificate validity with Certificate Authority

  4. Session keys exchanged

  5. Communication starts

In HTTPS all components of HTTP can be transmitted over TLS. It’s convenient in that only one party needs to be signed (the server). It’s secure against eavesdropping and man-in-the-middle attacks.

It does not seure IP address or port numbers (in the IP wrapper). Uses port 443 rather than 80.

OWASP

The OWASP foundation is an online developer-led community. In existence since 2001. Founded by Mark Curphey, provides documentation, guidance and research.

There are ‘projects’, which are member-led initiatives on web security. There will be some documentation, code, and tools for some issue in security. Most cities have an OWASP chapter, with hackathons, talks etc.

Best practices

Pathching and updating: most code contains bugs, approx one bug per 100 lines of production code. Some bugs present security holes. This is true of your code, your framework, its language and so on.

Patches keep your code environment up to date, keep your packages/libraries up to date.

We can check the Django docs about security:

https://docs.djangoproject.com/en/dev/internals/security/

https://groups.google.com/forum/#!forum/django-users

//irc.freenode.net/django

https://github.com/django/django

also the equivalents for drf:

https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework

https://github.com/encode/django-rest-framework/security

8.3 Django Authentication and Administration

Authentication is a process by which we can verify the identity of a user.

We shall restrict content/resources access for users according to their identity

The Django authentication system is provided by the django.contrib.auth application.

It requires SessionMiddleware and AuthenticationMiddleware to be enabled in settings (they are by default).

Now we can have differently identified sets of users, resource permission flags, user groups, configurable password hashing, all forms and pages for user registration, log in and log out.

It does not provide password safety checks, no login throttling, no third-party authentication authorities. We need different modules to add these features.

8.4 Django application authentication

Runs through setting up user auth on a django project.

Start by adding a model for your users:

from django.db import models
from django.contrib.auth.models import User

class AppUser(models.Model):
    user = models.oneToOneField(User, on_delete=models.CASCADE)
    organisation = models.CharField(max_length=256, null=True, blank=True)

    def __unicode__(self):
	return self.user.username

Register the model with the admin interface, and add the forms for logging in:

from django.forms import ModelForm
from django.contrib.auth.models import User
from .models import *

class UserForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput())
    class Meta:
	model = User
	fields = ('username', 'email', 'password')

class UserProfileForm(ModelForm):
    class Meta:
	model = AppUser
	fields = ('organisation',)

Then we can implement the view:

def register(request):
    registered = False
    if request.method == 'Post':
	user_form = UserForm(data=request.POST)
	profile_form = UserProfileForm(data=request.POST)
	if user_form.is_valid() and profile_form.is_valid():
	    user = user_form.save()
	    user.set_password(user.password) # don't store in plain text
	    user.save()
	    profile = profile_form.save(commit=False)
	    profile.user = user
	    if 'organisation' in user_form.cleaned_data:
		profile.organisation = request.DATA['organisation']
	    profile.save()
	    registered = True
    else:
	user_form = UserForm()
	profile_form = UserProfileForm()

    return render(request, 'genedata/register.html', {'user_form': user_form,
						      'profile_form': profile_form,
						      'registered': registered,
						      }

Then you can create a template that responds to the registered status:

{% extends "./base.html" %}

{% block content %}
  <h1>Register</h1>
  {% if registered %}
    <strong> Thank you for registering </strong>
  {% else %}
    <strong> Register Here </strong> <br />
    <form id="user_form" method="post", action="/register/"
     enctype="multipart/form-data">
     {% csrf_token %}
     {{ user_form.as_p }}
     {{ profile_form.as_p }}
     <input type="submit" name="submit" value="Register" />
     </form>
  {% endif %}
{% endblock %}

Now we can write a function to handle a login action:

from django.contrib.auth import authenticate, login
from django.http import HttpResponseRedirect

def user_login(request):
    if request.method == 'POST':
	username=request.POST['username']
	password=request.POST['password']
	user = authenticate(username=username, password=password)
	if user:
	    if user.is_active:
		login(request, user) # sends cookie to browser with login creds
		return HttpResponseRedirect('/') # to home page
	    else:
		return HttpResponse('Your account is disabled')
	else:
	    return HttpResponse('Invalid login')
    else:
	return render(request, 'genedata/login.html, {})

8.404 second half shows the login form that corresponds to this.

8.405 shows logging out, which is a simple function provided by the django.contrib.auth module.

8.406 covers access control. Here’s how we can restrict users for some arbitrary view:


def some_view(request):
    if not request.user.is_authenticated():
	return ("You are not logged in")
    else:
	return ("You are logged in")

Or we can control access to entire functions with decorators:

from django.contrib.auth.decorators import login_required

@login_required
def user_logout(request):
    logout(request)
    return HttpResponseRedirect('/')

What about class views?

Here we need to go to the urls instead and control access to the routing via the decorator.

from django.contrib.auth.decorators import login_required

urlpatterns = [
    path('gene/<int:pk>', login_required(login_url='login/')(views.GeneDetail.as_view()), name='gene_datail'),
]