Secure Software Development

Assignments and code examples.

View on GitHub

Authorization

Introduction

Many tutorials and framework documentation often only describe authorization so far as to allow or deny based on whether a user has authenticated or not. Maybe they do a bit of role-based access control. But that’s where things usually stop.

Simply checking that a user is authenticated is not enough for a real world application.

Following the principle of least privilege we almost always need more fine-grained control.

The aim of this assignment is for you to explorer this field within your tech-stack of choice.

Context

Imagine you are working on the back-end for a news site. The site contains news articles written by journalists. The site have editors which can correct factual mistakes in articles and remove hateful comments.

The business model rely on subscription fees and advertising. Subscribers can, for a small monthly fee access a version of the site without adds. Guests can still read articles published on the site, but will be presented with ads.

(Implementing ads are out-of-scope)

You can use whatever web-framework you like to implement the solution.

Policy

Your task is to implement authorization as a proof-of-concept that enforces the following policy.

Schema

You can use this (SQLite) schema as your starting point.

CREATE TABLE IF NOT EXISTS users (
    user_id INTEGER PRIMARY KEY,
    username TEXT UNIQUE NOT NULL,
    password_hash TEXT NOT NULL,
);

CREATE TABLE IF NOT EXISTS articles (
    article_id INTEGER PRIMARY KEY,
    title TEXT NOT NULL,
    content TEXT NOT NULL,
    author_id INTEGER NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (author_id) REFERENCES users(user_id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS comments (
    comment_id INTEGER PRIMARY KEY,
    content TEXT NOT NULL,
    article_id INTEGER NOT NULL,
    user_id INTEGER NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (article_id) REFERENCES articles(article_id) ON DELETE CASCADE,
    FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE
);

You can also create your own schema instead. You are not required to use a SQL database.

It is also acceptable to use an in-memory data storage like Dictionary (C#), HashMap (Java) and Dict (Python) instead of a database. Though a database is preferred.

Limitations

Implementing an advertising system is out of scope. Focus on CRUD endpoints and authorization policies.

As said, this will be a proof of concept. Focus is on authorization / access control.

I don’t expect you to do anything fancy regarding authentication (that’s for another lesson).

You can use either:

Front-end isn’t required, nor expected. A simple REST API is fine.

Tips

You are allowed to user GenAI (ChatGPT, Claude, Gemini, Copilot etc) to create the endpoints. You might need to take it step-by-step.

  1. Start with the data-access layer.
  2. Then CRUD endpoints for articles.
  3. Last, CRUD endpoints for comments.

Do not prompt it to implement authorization/access-control. The whole point is that you should gain a good understanding on how to implement authorization rules in your preferred framework. Referrer to the documentation for your framework rather than prompting.

If you use .NET for back-end you can take advantage of ASP.NET Core Identity.

Using something like Swagger UI or Scalar to test the API, is a good idea if your framework of choice supports it. Alternatively you could use Postman or write integrations test to validate your authorization polices.

Feedback

If you want feedback on your solution, then you can email me with a link to a GitHub repository with your code. The repository must be public and should contain a README with instructions on how I can run it with GitHub Codespaces.