diff --git a/package-lock.json b/package-lock.json
index 9dacb2ad0331d92cfe2d4ea26e506e7b449e50cd..6e263e935453408f57369118cc2079e3205ed7cf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2700,6 +2700,11 @@
         }
       }
     },
+    "express-rate-limit": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-4.0.4.tgz",
+      "integrity": "sha512-DLRj2vMO7Xgai8qWKU9O6ZztF2bdDmfFNFi9k3G9BPzJ+7MG7eWaaBikbe0eBpNGSxU8JziwW0PQKG78aNWa6g=="
+    },
     "extend": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
diff --git a/package.json b/package.json
index 7cf5c17ae94593863f5030b3183c73ba3ff891f3..2dd162d5d2e4d1bb28b0351c7afa69dbeefd74f0 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,7 @@
     "bcryptjs": "^2.4.3",
     "class-transformer": "^0.2.3",
     "class-validator": "^0.9.1",
+    "express-rate-limit": "^4.0.4",
     "jsonwebtoken": "^8.5.1",
     "pg": "^7.11.0",
     "reflect-metadata": "^0.1.12",
diff --git a/src/main.ts b/src/main.ts
index 1c70cb25c549b76c47fc0e078b05adaba2219ebc..3c7cc4607bac085ff529775a441ef81e4e089a6a 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,11 +1,22 @@
 import { NestFactory } from '@nestjs/core';
+import * as rateLimit from 'express-rate-limit';
 
 import { AppModule } from './app.module';
 
+// due to a bug with newest release of express-rate-limit, call for rateLimit is broken
+// (rateLimit as any) works as a workaround for now
+// see https://github.com/nfriedly/express-rate-limit/issues/138
+const limiter = (rateLimit as any)({
+  windowMs: 60 * 1000, // one minute
+  max: 100 // limit each IP to 100 requests per windowMs
+});
+
 async function bootstrap() {
   const app = await NestFactory.create(AppModule);
   // Cors is needed for application/json POST
   app.enableCors();
+  //  apply limiter to all routes
+  app.use(limiter);
   await app.listen(5000);
 }
 bootstrap();
diff --git a/src/user/user.controller.ts b/src/user/user.controller.ts
index c10ef159a2a6f877164ebc4bd73f740aac19a277..363e894a9e7fd0cb34df6dbd8a81b496f623bdea 100644
--- a/src/user/user.controller.ts
+++ b/src/user/user.controller.ts
@@ -1,8 +1,9 @@
-import { Controller, Post, Body, UsePipes, ValidationPipe, Get, UseGuards, Req } from '@nestjs/common';
+import { Controller, Post, Body, UsePipes, Get, UseGuards } from '@nestjs/common';
 
 import { UserService } from './user.service';
 import { UserDTO } from './user.dto';
 import { AuthGuard } from 'src/shared/auth.guard';
+import { ValidationPipe } from 'src/shared/validation.pipe';
 
 @Controller('user')
 export class UserController {
diff --git a/src/user/user.dto.ts b/src/user/user.dto.ts
index 4d806ad44c69002ca802b62918cfc5338f5a8924..c5bfa70cc3551645e1773e9aa7c4fb898b3f9887 100644
--- a/src/user/user.dto.ts
+++ b/src/user/user.dto.ts
@@ -1,8 +1,10 @@
-import { IsString } from 'class-validator';
+import { IsString, IsNotEmpty, Length } from 'class-validator';
 
 export class UserDTO {
-    @IsString()
+    // uses class-validator built in validations
+    // see https://github.com/typestack/class-validator
+    @IsString() @IsNotEmpty() @Length(3, 31)
     name: string;
-    @IsString()
+    @IsString() @IsNotEmpty() @Length(3, 255)
     password: string;
 }
\ No newline at end of file