BETA Shoulder is in beta — Findings may sometimes be wrong. Your feedback shapes what we fix next. Share feedback
🛡️

Improper Authorization

🛡️ 3 rules detect this

Improper Authorization

The product does not perform or incorrectly performs an authorization check when an actor attempts to access a resource or perform an action.

Assuming a user with a given identity, authorization is the process of determining whether that user can access a given resource, based on the user's privileges and any permissions or other access-control specifications that apply to the resource.

Prevalence
High
Frequently exploited
Impact
Critical
3 critical-severity rules
Prevention
Documented
3 fix examples
2 Prevention
2 Prevention

How to fix this vulnerability

Prevention strategies for Improper Authorization based on 3 Shoulder detection rules.

Angular Missing Route Guard CRITICAL

Add canActivate guards to all sensitive routes to prevent unauthorized access

+18 -8 javascript
- import { Routes } from '@angular/router';
- import { AdminComponent } from './admin/admin.component';
- import { SettingsComponent } from './settings/settings.component';
- 
- const routes: Routes = [
-   { path: 'admin', component: AdminComponent },
-   { path: 'settings', component: SettingsComponent },
-   { path: 'profile/:id', component: ProfileComponent },
+ import { Injectable } from '@angular/core';
+ import { CanActivate, Router, Routes } from '@angular/router';
+ import { AuthService } from './auth.service';
+ 
+ @Injectable({ providedIn: 'root' })
+ export class AuthGuard implements CanActivate {
+   constructor(private auth: AuthService, private router: Router) {}
+   canActivate(): boolean {
+     if (this.auth.isAuthenticated()) return true;
+     this.router.navigate(['/login']);
+     return false;
+   }
+ }
+ 
+ const routes: Routes = [
+   { path: 'admin', component: AdminComponent, canActivate: [AuthGuard, AdminGuard] },
+   { path: 'settings', component: SettingsComponent, canActivate: [AuthGuard] },
+   { path: 'profile/:id', component: ProfileComponent, canActivate: [AuthGuard] },
  ];
  
NestJS Sensitive Route Missing Guard CRITICAL

Add @UseGuards with authentication and authorization guards to all sensitive NestJS endpoints

+8 -3 javascript
- import { Controller, Delete, Post, Body, Param } from '@nestjs/common';
- 
- @Controller('admin')
+ import { Controller, Delete, Post, Body, Param, UseGuards } from '@nestjs/common';
+ import { AuthGuard } from '@nestjs/passport';
+ import { RolesGuard } from '../auth/roles.guard';
+ import { Roles } from '../auth/roles.decorator';
+ 
+ @Controller('admin')
+ @UseGuards(AuthGuard('jwt'), RolesGuard)
+ @Roles('admin')
  export class AdminController {
    @Delete('users/:id')
    deleteUser(@Param('id') id: string) {
      return this.adminService.deleteUser(id);
    }
  
    @Post('users')
    createUser(@Body() dto: CreateUserDto) {
      return this.adminService.createUser(dto);
    }
  }
  
tRPC Protected Procedure Missing Authentication CRITICAL

Use protectedProcedure with authentication middleware for all sensitive mutations and user-specific queries

+26 -20 javascript
- import { router, publicProcedure } from './trpc';
- import { z } from 'zod';
- 
- export const userRouter = router({
-   updateProfile: publicProcedure
-     .input(z.object({
-       userId: z.number(),
-       bio: z.string(),
-     }))
-     .mutation(async ({ input }) => {
-       return await db.user.update({
-         where: { id: input.userId },
-         data: { bio: input.bio },
-       });
-     }),
- 
-   deleteAccount: publicProcedure
-     .input(z.object({ userId: z.number() }))
-     .mutation(async ({ input }) => {
-       return await db.user.delete({ where: { id: input.userId } });
+ import { router, protectedProcedure } from './trpc';
+ import { z } from 'zod';
+ import { TRPCError } from '@trpc/server';
+ 
+ const isAuthed = t.middleware(async ({ ctx, next }) => {
+   if (!ctx.session?.user) {
+     throw new TRPCError({ code: 'UNAUTHORIZED' });
+   }
+   return next({ ctx: { user: ctx.session.user } });
+ });
+ 
+ const protectedProcedure = t.procedure.use(isAuthed);
+ 
+ export const userRouter = router({
+   updateProfile: protectedProcedure
+     .input(z.object({ bio: z.string() }))
+     .mutation(async ({ ctx, input }) => {
+       return await db.user.update({
+         where: { id: ctx.user.id },
+         data: { bio: input.bio },
+       });
+     }),
+ 
+   deleteAccount: protectedProcedure
+     .mutation(async ({ ctx }) => {
+       return await db.user.delete({ where: { id: ctx.user.id } });
      }),
  });
  
4 Warning Signs
4 Warning Signs

What to watch for in code reviews

These patterns indicate potential Improper Authorization vulnerabilities. Look for these during code reviews and security audits.

🔴
Route '...' handles sensitive operations but lacks canActivate or other route guards. angular-missing-route-guard
🔴
Controller method '...' performs sensitive operation '...' without @UseGuards decorator. This endpoint is publicly acces nestjs-missing-route-guard
🔴
Procedure '...' handles sensitive data but uses publicProcedure. Use protected procedure with authentication middleware. trpc-missing-auth-middleware
🔍

Scan your codebase for Improper Authorization

Shoulder CLI finds vulnerable patterns across your entire codebase.