Secure Coding
Security is a fundamental aspect of modern software development. As a fullstack team working with NestJS, Vue.js, GraphQL, and TypeScript, we adhere to best practices to protect our applications and users.
1. Never Expose Secrets
- Do not commit secrets (API keys, database credentials, JWT secrets) to version control.
- Use environment variables for configuration and inject them at runtime:
// In NestJS
@Module({imports: ConfigModule.forRoot()})
export class AppModule {}
- Example:
Store secrets in.env
files and add.env
to your.gitignore
.
2. Input Validation and Sanitization
- Validate all user input on both client and server to prevent injection attacks:
// In NestJS (with class-validator)
class CreateUserDto {
@IsEmail()
email: string;
@MinLength(8)
password: string;
}
3. Authentication and Authorization
- Use strong, modern authentication (OAuth, JWT with secure storage, or session-based authentication).
- Example:
In NestJS, use@nestjs/passport
andpassport-jwt
for JWT authentication. - Example:
In Vue.js, store tokens securely (preferably in HTTP-only, Secure, SameSite cookies).
4. Secure API Design
- Always use HTTPS to encrypt data in transit.
- Implement rate limiting to protect against brute force and abuse.
- Example:
In NestJS, use guards and rate-limiting middleware:
@UseGuards(RateLimitGuard)
@Get('profile')getProfile() { … }
5. Avoid Hardcoded Credentials
- Never hardcode usernames, passwords, or API keys in your code.
- Example:
Use environment variables or a secrets management service (e.g., AWS Secrets Manager, GCP Secret Manager).
6. Keep Dependencies Updated
- Regularly update your Node.js, Vue.js, NestJS, and other dependencies to patch security vulnerabilities.
- Example:
Usenpm audit
or Dependabot to monitor for vulnerabilities.
7. Error Handling and Logging
- Do not expose stack traces or sensitive information in error messages to clients.
- Example:
In NestJS, use custom exception filters:
@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
// Return a generic error message to the client}
}
}
8. Secure GraphQL Endpoints
- Validate all queries and mutations to prevent malicious or overly complex requests.
- Example:
Use query complexity analysis and depth limiting in your GraphQL server.
By following these practices, we ensure our applications are robust, reliable, and secure for our users.