NestJS Penetration Testing for Guards, Validation and Resolver Security
NestJS structures a Node.js application around modules, providers and decorators, and hands you guards, pipes and interceptors as the building blocks for authorisation, validation and serialisation. Where those decorators actually get applied, at the controller, the route, the resolver or the microservice handler, is where our testing concentrates, because a guard that protects nine routes and misses a tenth behaves exactly like no guard at all on that tenth route. We test the boundary your team built with NestJS’s toolkit, not the framework runtime underneath it. CREST-certified testers, fixed price from £2,850 for a 2-day single-framework scope, quoted within 24 hours.
- Unlimited retesting
- Unlimited pre-retesting
- No hidden fees
“I would highly recommend EJN Labs to any organisation seeking reliable, detailed, and well-managed penetration testing services, particularly for government or enterprise-level projects.”
“There wasn’t another company we could find that could deliver what we needed in the timeframe we needed. The client loved it, and we got instant ROI from the engagement.”
NestJS lets you bind a guard globally, to a single controller or to one route, and a custom metadata decorator to skip it for chosen endpoints. We test whether every controller and route actually carries the guard your application depends on, and whether every exemption from it is deliberate.
Why NestJS security depends on where you put the decorator
NestJS turns authorisation into a decorator. A guard is a class that implements CanActivate and decides whether a request reaches its handler, and NestJS’s own guards documentation is explicit that a guard can be bound globally with useGlobalGuards or the APP_GUARD provider, scoped to a single controller with @UseGuards, or scoped to one route handler. A route can also carry custom metadata, set with @SetMetadata or a decorator built from Reflector.createDecorator, that a guard reads at runtime and uses to skip itself, the mechanism behind a Public or SkipAuth decorator used to exempt a login endpoint from a global AuthGuard. We test every controller and route against the guard scope your team intended, and every metadata-driven bypass against the list of endpoints that should actually be exempt.
Role and object-level authorisation sit a layer deeper. A RolesGuard built with Reflector compares the roles a route requires against the roles on the authenticated user, and where access depends on the specific record rather than the route, NestJS’s authorisation guide describes a PoliciesGuard built on CASL’s MongoAbility, for condition-based checks against the object itself. We test whether a role check that correctly blocks a route also blocks that same request against another tenant’s or another user’s specific record, the gap a route-level guard alone cannot close.
Input and output follow the same opt-in pattern. ValidationPipe’s documentation confirms that its whitelist option strips any property without a class-validator decorator from an incoming payload, and forbidNonWhitelisted rejects the request outright instead, but only on the DTOs and routes where the pipe is actually bound. The same pattern repeats on the way out and on other transports: a ClassSerializerInterceptor has to be applied per route or globally before an @Exclude decorator does anything, NestJS does not run guards or interceptors on a GraphQL field resolver unless fieldResolverEnhancers is configured, and a global HTTP guard set with useGlobalGuards does not extend to a connected microservice by default. Each of those is a control that looks universal on the main path and quietly stops at a boundary.
SCOPE
What we pen test on a NestJS application
Global Guard Coverage and Binding
A guard runs for every request only once it is bound with useGlobalGuards or registered on the APP_GUARD provider, and a guard added to one module’s providers and never wired into the root module never reaches routes outside it. We test whether the guard your application depends on for authentication actually wraps every controller, not only the ones in the module where it was first added.
Controller and Route-Level Guard Scope
Guards can also be scoped to a single controller or a single route with @UseGuards, which suits an endpoint that needs stricter checks than the rest of the API, but it is also how a route ends up with no guard at all when a global guard was never registered in the first place. We test every controller and route against the guard scope your team intended, rather than the scope a code search for @UseGuards happens to find.
Public-Style Bypass Decorators
NestJS’s own authentication guide shows this exact pattern: a custom decorator, commonly named Public, SkipAuth or AllowAnon, sets metadata that a global AuthGuard reads through Reflector and uses to skip itself for that one route. We test which routes actually carry that metadata against which routes should be exempt, since the mechanism that excuses a login endpoint can just as easily excuse one it was never meant to.
Role-Based Authorisation with Reflector
A RolesGuard reads the roles a route requires from custom metadata, set with @SetMetadata or a decorator built from Reflector.createDecorator, and compares them against the roles on the authenticated user attached to the request. We test whether every state-changing route actually declares the roles it needs, and whether the comparison logic inside the guard enforces the boundary your business intends.
Object-Level and Policy-Based Authorisation
Where access depends on the specific record rather than the route, NestJS’s authorisation documentation describes a PoliciesGuard built on CASL’s MongoAbility, checking conditions against the object itself rather than just the endpoint. We test whether a role or ability check that correctly blocks a route also blocks that same request against another tenant’s or another user’s specific record.
ValidationPipe Whitelisting and Mass Assignment
ValidationPipe’s whitelist option strips any property without a class-validator decorator from an incoming payload, and forbidNonWhitelisted rejects the request outright instead of silently stripping it, but both only apply on the DTOs and routes where the pipe is actually bound. We test every write endpoint for a DTO that still accepts a role, tenant, price or ownership field it was never meant to expose to the client.
DTO Coverage Across the API Surface
class-validator decorators only validate the class they are declared on, so a body handled through a typed DTO can sit next to a query parameter or route parameter taking a raw, unvalidated string, and the transform option that turns a JSON payload into a typed DTO instance has to be enabled for each input surface to matter. We test every endpoint’s body, query and route parameters for the DTO and pipe coverage the rest of the API already has.
REST and GraphQL Resolver Authorisation Parity
NestJS’s GraphQL documentation states that guards and interceptors do not run automatically on @ResolveField methods, only on the top-level @Query and @Mutation handlers, unless fieldResolverEnhancers is explicitly configured to include them. We test whether a field resolver that returns a related, more sensitive object is actually covered by the same authorisation your REST controllers enforce, or bypasses it.
Serialisation and ClassSerializerInterceptor Coverage
ClassSerializerInterceptor applies class-transformer’s instanceToPlain function to a handler’s return value, honouring @Exclude and @Expose on the entity or DTO class, but only on the controllers and routes where the interceptor is actually bound, whether per-route with @UseInterceptors or globally through the APP_INTERCEPTOR token. We test for handlers that return an entity without the interceptor applied, and for fields such as passwords or tokens still reaching the response.
Microservice Transports and Message Handler Guards
NestJS’s own guards documentation notes that in a hybrid application, useGlobalGuards does not set up guards for a connected microservice by default, so message handlers built with @MessagePattern or @EventPattern over TCP, Redis, NATS, Kafka or gRPC can end up without the protection the HTTP side has. We test every transporter and message handler in scope against the guard, pipe and serialisation coverage it actually has, not the coverage the HTTP layer implies.
OUR PROCESS
NestJS Penetration Testing: From Scope to Attestation
Scope and Guard Mapping
We agree the environments, controllers, resolvers and message handlers in scope, and map every guard, pipe and interceptor binding, global, controller and route-level, before testing begins.
Decorator and Metadata Review
We review the custom metadata behind every role, policy and bypass decorator in scope against the access it is meant to grant or exempt, including any Public-style decorator used to skip a global guard.
Manual Exploitation
A CREST-certified tester manually tests guard coverage, object-level authorisation, DTO validation and serialisation boundaries, chaining findings across REST, GraphQL and microservice handlers where they compound.
Attestation and Retest
You get a technical report with CVSS scores and reproduction steps, a walkthrough call, a free retest once fixes are deployed, and an attestation letter for auditors.
CREDENTIALS
Verified Accreditations Auditors Accept
Every credential below is independently verifiable. UK procurement teams, FCA supervisors, ISO 27001 / SOC 2 auditors, and cyber insurance underwriters all recognise these standards.
GET YOUR QUOTE
Get a CREST NestJS pen test quote in 24 hours
A fixed-price quote back in one business day, from a named CREST assessor. No sales pipeline, no chasing.
- CREST and IASME accredited. Testing your auditors and clients already recognise.
- Fast-track testing within 24 hours where required. Free retest of every fix included.
- Live findings via your client portal, not a four-week PDF.
- Fixed price from £3,500 for a single-role, single-app scope, agreed up front. Most engagements run £5,000 and up. No day-rate surprises.
Under NDA Further named references available on a scoping call.
- We reply within one business day with a fixed-price quote from a named CREST assessor.
- You approve the scope and we book a start date, usually within 24 hours.
- Live findings land in your client portal as we test, with a free retest of every fix.
Get your fixed pen test quote in 24 hours
Quote request received
We will reply within one business day with your fixed-price quote from a named CREST assessor.
Your data stays with us. No newsletter signup.
or book a 20-min scoping call first
We reply within one business day. Your data stays with us. No newsletter signup.
COMPLIANCE READY
Reports Mapped to Every Framework
Findings are written so your team can reference the report against each framework without translation work.
ISO 27001:2022
Annex A.8.8 management of technical vulnerabilities plus A.5.15-5.18 and A.8.2-8.5 access control validation.
SOC 2 Type I & II
CC6 logical access, CC7 system operations, CC8 change management evidence.
PCI DSS
Requirement 11.4 application penetration testing across cardholder data environments, including ecommerce penetration testing for online retail platforms.
FCA SYSC
SYSC 4.1.1R, 6.1.1R, 13 mapped to each finding for FCA-regulated firms.
UK GDPR
Article 32 effectiveness testing, customer-data security controls, ICO-acceptable evidence.
Cyber Essentials Plus
Direct certification through our IASME body status, single-vendor delivery.
PRICING
Transparent NestJS Penetration Testing Pricing
Pricing depends on the number of roles, integrations and environments in scope. See our pricing page for how we quote.
2 to 3 testing days
Single user role, basic CRUD application, marketing website with auth. Around 5 working days from kickoff to report.
Get a fixed quote3 to 5 testing days
Multi-role SaaS, business application with payment integration. Around 8 to 12 working days from kickoff to report.
Get a fixed quote5 to 8 testing days
Multi-tenant platform, complex authorisation matrix, integration-heavy applications. Around 15 to 20 working days from kickoff to report.
Get a fixed quoteSECTORS
Sectors We Test NestJS For
Sector-specific scoping for regulated UK organisations.
Fintech & FCA-Regulated
FCA SYSC, Open Banking FAPI 1.0, PSD2 SCA, payment-flow scrutiny, KYC/AML testing.
Fintech sector pageSaaS Companies
SOC 2 Type I & II evidence, multi-tenant boundaries, role escalation, customer-tenant isolation.
SaaS sector pageLaw Firms
SRA Cyber Standard, privileged data, conveyancing fraud defence, partner-tier procurement.
Law firm sector pageHealthcare
NHS DTAC, DSP Toolkit v6, UK GDPR Article 32, EHR systems, telehealth platforms.
Healthcare sector pageInsurance
FCA / PRA Operational Resilience, cyber underwriting, claims data, broker portals.
Insurance sector pagePublic Sector
CCS / G-Cloud framework, NCSC-aligned, citizen-facing services, PSN-compliance scrutiny.
Public sector pageWHY EJN LABS
What You Get From NestJS Penetration Testing
Six concrete differentiators competitors don’t all match.
CREST-Certified Testers, Verifiable
Every test by a CREST-certified pen tester (CRT, CCT APP, CCT INF where applicable). Verify our company status at crest-approved.org.
24-Hour Startup, Where Required
From signed scope to active testing in a single business day for incident response, audit deadlines, or regulator-driven timelines.
Live Findings, Not 4-Week PDFs
Critical issues reported during testing through your client portal. Your team remediates while testing continues.
Audit-Ready Reports
Executive summary plus full technical report with CVSS scores and explicit framework mappings (ISO 27001, SOC 2, PCI DSS, FCA SYSC).
Free Retests, Standard
Verify remediation of every finding before close-out. Letter of attestation for audit submission included. Most competitors charge £1,500-£3,000 per retest.
UK-Based CREST Testers
Every engagement performed by vetted, UK-based CREST-certified testers, matched to your needs, security clearance, and compliance scope.
FAQ
Frequently Asked
What access do you need to test our NestJS application?
We need at least one authenticated account for every distinct role or permission level the API exposes, plus a valid token or session for each guard and role combination your application defines. Where the application includes a GraphQL API, sight of the schema, whether introspection is enabled or a schema file is provided, speeds up mapping every query, mutation and field resolver in scope.
Will testing touch our live data?
We test whichever environment you give us access to. If that is production, we agree exclusions upfront, such as bulk deletes and any outbound messages your microservice handlers would normally emit, and we do not run destructive tests against real customer records without that agreement in writing.
How long does a NestJS penetration test take?
A single NestJS application sits in our 2-day single-framework scope, with a report typically landing around 5 working days after kickoff. An application with a GraphQL API alongside REST, several microservice transports or a wider role and tenant matrix moves into a larger scope with more testing days.
Do you test microservice message handlers as well as the HTTP API?
Yes, where they are in scope. Handlers built with @MessagePattern and @EventPattern over transports such as TCP, Redis, NATS, Kafka or gRPC are tested for the same guard, pipe and serialisation coverage as the HTTP controllers, since a global HTTP guard does not automatically extend to a connected microservice in a hybrid application.
Is our GraphQL API covered in the same test?
Yes. Resolvers, mutations and field resolvers are tested for authorisation the same way REST controllers are, including the specific NestJS behaviour where guards and interceptors do not run on field resolvers unless the application has explicitly configured them to.
What is out of scope for a single-framework NestJS test?
Infrastructure-level issues in the underlying server, container platform or cloud configuration are out of scope for this test and covered by our cloud penetration testing service instead. A separate frontend application consuming the API, such as a decoupled React or Angular app, is also scoped and quoted separately.
Do you need our source code?
No. Testing is black-box against the running application by default. A grey-box option, where we review the relevant guards, DTOs, interceptors and resolver code alongside testing, is available if you want faster or deeper coverage of specific findings.
Does NestJS have a customer penetration-testing policy we need to follow?
No. NestJS is framework code you deploy and control yourself rather than a shared multi-tenant service, so there is no vendor notification process to follow before testing it. If your NestJS application runs on a shared cloud platform or managed hosting provider, that provider’s own penetration-testing policy still applies, and we confirm its current terms with you during scoping.
20+ CREST-accredited testing services in one place
Web, mobile, API, cloud, AI, infrastructure, red team. Pick the test that fits your environment.
Get a fixed price for your NestJS application
NestJS structures a Node.js application around modules, providers and decorators, and hands you guards, pipes and interceptors as the building blocks for authorisation, validation and serialisation. Where those decorators actually get applied, at the controller, the route, the resolver or the microservice handler, is where our testing concentrates, because a guard that protects nine routes and misses a tenth behaves exactly like no guard at all on that tenth route. We test the boundary your team built with NestJS’s toolkit, not the framework runtime underneath it. CREST-certified testers, fixed price from £2,850 for a 2-day single-framework scope, quoted within 24 hours.



