NestJS Risk Assessment & Management 4 — Questions and Answers
Question 1: What risk does not sanitizing user-supplied values before passing them to a TypeORM QueryBuilder introduce?
- SQL injection, allowing attackers to manipulate or exfiltrate database data (Correct answer)
- Circular dependency errors in the NestJS module graph
- Over-fetching data due to missing SELECT projections
- Memory leaks in the connection pool
Correct answer: SQL injection, allowing attackers to manipulate or exfiltrate database data
Concatenating unsanitized user input into raw SQL expressions enables injection attacks that can read, modify, or delete arbitrary data.
Question 2: Which NestJS approach reduces the risk of privilege escalation by ensuring a user can only access their own resources?
- Implementing resource-level authorization in guards using the requesting user's ID from the JWT payload (Correct answer)
- Using role-based access control at the controller level only
- Disabling all public endpoints
- Storing resource ownership in cookies
Correct answer: Implementing resource-level authorization in guards using the requesting user's ID from the JWT payload
Comparing the JWT subject claim to the resource owner ID inside a guard prevents users from accessing other users' data even with valid tokens.
Question 3: In a NestJS GraphQL API, what security risk do deeply nested queries pose?
- They can cause denial-of-service by triggering exponentially expensive resolver chains (Correct answer)
- They break Apollo schema introspection
- They prevent field-level authorization guards from running
- They disable DataLoader batching automatically
Correct answer: They can cause denial-of-service by triggering exponentially expensive resolver chains
Deeply nested GraphQL queries can cause N+1 resolver explosions and overwhelm the server, a risk mitigated by query depth and complexity limits.
Question 4: When deploying a NestJS application in a Docker container, which practice reduces the attack surface at the infrastructure level?
- Running the Node.js process as a non-root user inside the container (Correct answer)
- Exposing all ports to simplify service discovery
- Installing development dependencies in the production image
- Using the latest tag for the base image
Correct answer: Running the Node.js process as a non-root user inside the container
Running as a non-root user limits the damage an attacker can do if they gain code execution inside the container.
Question 5: A NestJS service caches sensitive user data in Redis without an expiry. What risk does this create?
- Stale sensitive data persists indefinitely, increasing exposure if the cache is breached (Correct answer)
- Redis automatically evicts data using LRU, causing cache misses
- NestJS CacheModule cannot connect without a TTL
- JWT tokens stored in Redis become invalid after a restart
Correct answer: Stale sensitive data persists indefinitely, increasing exposure if the cache is breached
Without a TTL, sensitive records remain in the cache long after they are no longer needed, enlarging the window for unauthorized access.
Question 6: What risk does logging full request bodies in a NestJS middleware without redaction introduce?
- Passwords, tokens, and PII are written to log storage, violating data-privacy regulations and expanding breach impact (Correct answer)
- Request processing slows down due to serialization overhead
- NestJS Logger throws when bodies exceed 4KB
- Guards no longer receive the original request object
Correct answer: Passwords, tokens, and PII are written to log storage, violating data-privacy regulations and expanding breach impact
Unredacted logs capture credentials and personal data, creating a high-value target for attackers and potential GDPR/CCPA violations.
Question 7: Which NestJS configuration option mitigates the risk of accidentally exposing internal service endpoints to the public internet?
- Binding the HTTP server to localhost (127.0.0.1) and using a reverse proxy for public traffic (Correct answer)
- Disabling HTTPS in favor of HTTP for internal traffic only
- Using @Controller() without a path prefix
- Enabling synchronize: true in TypeORM
Correct answer: Binding the HTTP server to localhost (127.0.0.1) and using a reverse proxy for public traffic
Listening on 127.0.0.1 ensures the NestJS port is not directly reachable from outside the server; all public traffic must pass through the reverse proxy.
What risk does not sanitizing user-supplied values before passing them to a TypeORM QueryBuilder introduce?