GuardAPI Logo
GuardAPI

Fix Shadow API Exposure in LoopBack

Shadow APIs in LoopBack 4 are a silent killer, often born from the 'convention over configuration' trap. When developers use the CLI to scaffold CRUD controllers, they inadvertently expose internal-only methods and sensitive model properties to the public. If you aren't explicitly pruning your endpoints and hardening your models, you're leaking the blueprint of your internal infrastructure to any script kiddie with a fuzzer.

The Vulnerable Pattern

@model()
export class User extends Entity {
  @property({id: true}) id: number;
  @property() email: string;
  @property() passwordHash: string; // EXPOSED
  @property() internalAdminNote: string; // EXPOSED
}

export class UserController { constructor(@repository(UserRepository) public userRepository: UserRepository) {}

@get(‘/users’) async find(): Promise<User[]> { return this.userRepository.find(); // Returns every field in the DB including hashes }

@patch(‘/users/{id}’) async updateById(@param.path.number(‘id’) id: number, @requestBody() user: User): Promise { await this.userRepository.updateById(id, user); // Allows mass assignment/overwriting of admin notes } }

The Secure Implementation

To eliminate Shadow API exposure, you must implement a multi-layered defense. 1. Model Hardening: Use the 'hidden: true' metadata in your Model definition to ensure sensitive fields are stripped during JSON serialization. 2. Field Filtering: In your Controller, never return the raw result of a repository find; use the 'fields' filter to explicitly define an allow-list of public attributes. 3. Schema Pruning: Use 'getModelSchemaRef' with the 'exclude' option in your requestBody decorators to prevent mass-assignment vulnerabilities where attackers overwrite internal flags. 4. Explicit Routing: Delete any scaffolded CRUD methods that aren't strictly required for your business logic to reduce the attack surface.

@model({settings: {strict: true}})
export class User extends Entity {
  @property({id: true}) id: number;
  @property({required: true}) email: string;
  @property({hidden: true}) passwordHash: string; // PROTECTED
  @property({hidden: true}) internalAdminNote: string; // PROTECTED
}

export class UserController { constructor(@repository(UserRepository) public userRepository: UserRepository) {}

@get(‘/users’) @authenticate(‘jwt’) async find(): Promise<Partial[]> { return this.userRepository.find({ fields: {id: true, email: true} // STRICT ALLOW-LIST }); }

@patch(‘/users/{id}’) @authorize({allowedRoles: [‘admin’]}) async updateById(@param.path.number(‘id’) id: number, @requestBody({content: {‘application/json’: {schema: getModelSchemaRef(User, {partial: true, exclude: [‘id’, ‘internalAdminNote’]})}}}) user: User): Promise { await this.userRepository.updateById(id, user); } }

System Alert • ID: 6844
Target: LoopBack API
Potential Vulnerability

Your LoopBack API might be exposed to Shadow API Exposure

74% of LoopBack apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

Free Tier • No Credit Card • Instant Report

Verified by Ghost Labs Security Team

This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.