Software Engineer Playbook

Software Engineer Playbook

Share this post

Software Engineer Playbook
Software Engineer Playbook
Secure Coding for Authorization

Secure Coding for Authorization

Part 2 of Secure Coding for Software Engineers series.

James Ma's avatar
James Ma
Oct 02, 2023
∙ Paid

Share this post

Software Engineer Playbook
Software Engineer Playbook
Secure Coding for Authorization
Share

black smartphone
Photo by Lukenn Sabellano on Unsplash

Authorization involves granting permission to an entity, whether it’s an individual or a group, enabling them to access data or execute specific functions within your application. Authentication and authorization often complement each other. Authentication verifies the identity of a user, ensuring that they are who they claim to be. Following authentication, authorization determines what actions and data that authenticated user is allowed to interact with.

Web applications should possess the capability to verify the user responsible for a particular task and the range of actions permitted for that user. However, in certain scenarios, web application developers might choose to forgo authorization altogether. This decision implies that any type of user can freely access or utilize the resource exempt from authorization checks.

When authorization is integrated with authentication, web applications can effectively manage the activities permitted for different users. This integration frequently grants authenticated users expanded access, as the application can grant authorized access to resources and functionalities essential for that user, entity, or group.

Here are some suggestions for enhancing the security of your web application’s authorization mechanism:

1. Always embrace the principle of Least Privilege

When it comes to access control and authority, it’s crucial to begin by granting users the minimal level of privilege necessary. This entails ensuring that your application provides the most basic access required, tailored to the specific requirements of the user.

This can be effectively implemented through the use of a policy file. When a user interacts with your web server, your web controller will assess the authorization attributes of the user against the permission grants outlined within a policy file.

2. Use role-based access control (RBAC) for programmatic authorization

Programmatic authorization enforces security within the application itself, focusing on safeguarding each action granted to a specific target directly from the code. This approach proves valuable when either a single action string requires protection or when multiple action strings need safeguarding, possibly in conjunction with resources that don’t require authorization.

Role-based access control ensures that the web application or resource is accessed or acted upon in accordance with the user’s role during code execution. To implement this approach effectively, it’s essential to align functions with individual users and user groups.

Although role-based access control has these two benefits, and is easy to use, it also has its share of challenges. Implementing role-based access control requires stringent management of roles and associated accesses. Furthermore, it is not compatible with data-based access control, which revolves around data and who should have access to it, irrespective of their role.

One limitation of programmatic authorization is its requirement for user login. If web application developers opt not to enforce a login procedure, they may need to combine programmatic authorization with declarative authorization.

Caution must be exercised regarding role spillover, where a user is associated with multiple role groups. For instance, consider John, who holds ‘RoleHR,’ granting him read permission to the HR folder, and ‘RoleForum,’ which permits him to write to the company internal forum. These combined roles could potentially allow John to display all employee bonus amounts on the company forum.

Therefore, it’s crucial to carefully evaluate roles and their assignments. Whenever a role change occurs, it is essential to revoke authorizations or accesses granted in the previous role

Here’s a simple example in Golang that demonstrates programmatic authorization for a web application using middleware and a basic role-based access control (RBAC) approach. This code assumes you have a user authentication system in place.

package main

import (
    "fmt"
    "net/http"
)

// User represents a user in the system.
type User struct {
    ID    int
    Username string
    Role  string
}

// Simulated user database.
var users = []User{
    {ID: 1, Username: "alice", Role: "admin"},
    {ID: 2, Username: "bob", Role: "user"},
}

func main() {
    http.HandleFunc("/admin", adminHandler)
    http.HandleFunc("/profile", profileHandler)
    http.ListenAndServe(":8080", nil)
}

func adminHandler(w http.ResponseWriter, r *http.Request) {
    user := getUserFromSession(r) // Simulated user authentication

    // Check if the user is authorized to access the admin page
    if user != nil && user.Role == "admin" {
     fmt.Fprintf(w, "Welcome, %s! You have admin access.", user.Username)
    } else {
     http.Error(w, "Unauthorized", http.StatusUnauthorized)
    }
}

func profileHandler(w http.ResponseWriter, r *http.Request) {
    user := getUserFromSession(r) // Simulated user authentication

    // Display user profile
    if user != nil {
     fmt.Fprintf(w, "Welcome, %s! This is your profile page.", user.Username)
    } else {
     http.Error(w, "Unauthorized", http.StatusUnauthorized)
    }
}

func getUserFromSession(r *http.Request) *User {
    // Simulated user authentication (replace with actual authentication logic)
    username := "alice" // For demonstration purposes, assume Alice is authenticated

    // Find the user by username
    for _, u := range users {
     if u.Username == username {
      return &u
     }
    }

    return nil // User not found
}

In this example:

  • We have a basic web server with two routes: /admin and /profile.

  • We define a User struct to represent users with an ID, Username, and Role.

  • The getUserFromSession function simulates user authentication by returning a user based on the username. Implement your actual authentication logic there.

  • In the adminHandler, we check if the user is authenticated and has the “admin” role to access the admin page.

  • In the profileHandler, we check if the user is authenticated to access their profile page.

Please note that this is a simplified example for demonstration purposes. In a real-world scenario, you should implement a more robust authentication and authorization system, possibly using middleware, and handle user sessions securely.

3. Use policy-based authorization for declarative authorization

Declarative authorization is an approach to access control and security in software applications where the authorization rules and policies are declared and managed separately from the application’s core logic, typically through configuration files, annotations, or settings, rather than embedding them directly into the application code.

This means you can update user access privileges without modifying the application code.

Below is an illustrative example of a policy file read by an application to enforce policy-based authorization:

{
    "policies": [
        {
            "resource": "document",
            "action": "read",
            "permission": "allow"
        },
        {
            "resource": "document",
            "action": "write",
            "permission": "deny"
        },
        {
            "resource": "user",
            "action": "delete",
            "permission": "allow"
        },
        {
            "resource": "admin",
            "action": "access_dashboard",
            "permission": "allow"
        }
    ]
}

4. Use discretionary access control (DAC) for refined access to resources

Discretionary access control (DAC) empowers resource owners to grant or revoke access to individual users or user groups at their discretion. It puts the decision-making power in the hands of the resource owner, allowing them to specify who can access their resources and the level of access granted. This approach offers developers a high degree of control over the access management framework.

Keep reading with a 7-day free trial

Subscribe to Software Engineer Playbook to keep reading this post and get 7 days of free access to the full post archives.

Already a paid subscriber? Sign in
© 2025 James Ma
Privacy ∙ Terms ∙ Collection notice
Start writingGet the app
Substack is the home for great culture

Share