-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PS-703 : Added CORS and helmet to middle ware for security #16
base: main
Are you sure you want to change the base?
Conversation
📝 Walkthrough📝 WalkthroughWalkthroughThe pull request introduces updates to the Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Server
participant CORS Middleware
participant Helmet Middleware
Client->>Server: Request with Origin
Server->>CORS Middleware: Check Origin
CORS Middleware->>Server: Validate Origin
Server->>Helmet Middleware: Apply Security Headers
Helmet Middleware->>Server: Secure Response
Server->>Client: Response with CORS and Security Headers
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Outside diff range and nitpick comments (2)
package.json (1)
2-2
: Overall assessment: Changes improve security as intendedThe modifications to
package.json
align well with the PR objectives. The project name correction and the addition ofcors
andhelmet
dependencies enhance the project's configuration and security capabilities. These changes lay the groundwork for implementing CORS handling and security headers in the application.Remember to properly configure and use these new dependencies in your application code, particularly in your main application file or middleware setup.
Also applies to: 37-37, 39-39
src/main.ts (1)
58-58
: Configurehelmet
middleware for optimal security.Including
helmet()
enhances security by setting various HTTP headers. Ensure that it's correctly configured for your application's needs, especially if you have APIs that require specific header settings.You may need to adjust
helmet
settings:app.use( helmet({ contentSecurityPolicy: false, // Adjust as necessary }), );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
- package.json (2 hunks)
- src/main.ts (2 hunks)
🔇 Additional comments (4)
package.json (3)
2-2
: LGTM: Project name correctedThe project name has been correctly updated from "middleware_micorservice" to "middleware_microservice", fixing the typo. This change improves consistency and clarity in the project configuration.
37-37
: LGTM: CORS dependency addedThe addition of the
cors
package (version ^2.8.5) aligns with the PR objectives for enhancing security. This middleware will help in managing Cross-Origin Resource Sharing (CORS) headers.To ensure we're using the latest stable version compatible with our project, please run the following command:
39-39
: LGTM: Helmet dependency addedThe addition of the
helmet
package (version ^8.0.0) aligns well with the PR objectives for enhancing security. Helmet will help in securing the application by setting various HTTP headers.To ensure we're using the latest stable version compatible with our project, please run the following command:
✅ Verification successful
Verified: Helmet dependency is up to date
The
helmet
package is already using the latest version (8.0.0
). No action is required.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check the latest version of helmet and compare with the current version latest_version=$(npm show helmet version) current_version=$(jq -r '.dependencies.helmet' package.json | tr -d '^') echo "Current helmet version: $current_version" echo "Latest helmet version: $latest_version" if [ "$current_version" != "$latest_version" ]; then echo "Consider updating helmet to the latest version" fiLength of output: 448
Script:
#!/bin/bash # Fetch the latest version of helmet from the npm registry latest_version=$(curl -s https://registry.npmjs.org/helmet | jq -r '.["dist-tags"].latest') current_version=$(jq -r '.dependencies.helmet' package.json | tr -d '^') echo "Current helmet version: $current_version" echo "Latest helmet version: $latest_version" if [ "$latest_version" != "" ] && [ "$(printf '%s\n' "$latest_version" "$current_version" | sort -V | head -n1)" != "$current_version" ]; then echo "Consider updating helmet to the latest version ($latest_version)" fiLength of output: 419
src/main.ts (1)
2-2
: Importinghelmet
for security enhancements.The import statement for
helmet
is correctly added.
src/main.ts
Outdated
app.use((req, res, next) => { | ||
const origin = req.headers.origin; | ||
|
||
if (corsOriginList.includes(origin) || corsOriginList[0] === '*') { | ||
res.setHeader('Access-Control-Allow-Origin', origin); | ||
} else { | ||
throw new InternalServerErrorException('Invalid CORS_ORIGIN'); | ||
} | ||
res.setHeader('Access-Control-Allow-Credentials', 'true'); | ||
res.header( | ||
'Access-Control-Allow-Methods', | ||
'GET,HEAD,PUT,PATCH,POST,DELETE', | ||
); | ||
next(); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant and conflicting CORS middleware.
You have manually implemented a middleware to handle CORS, but you also enable CORS using app.enableCors(corsOptions);
at line 57. This redundancy can cause conflicts and unexpected behaviors.
Consider removing the custom middleware and rely on app.enableCors(corsOptions);
for CORS handling.
Apply this diff to remove the custom middleware:
- app.use((req, res, next) => {
- const origin = req.headers.origin;
-
- if (corsOriginList.includes(origin) || corsOriginList[0] === '*') {
- res.setHeader('Access-Control-Allow-Origin', origin);
- } else {
- throw new InternalServerErrorException('Invalid CORS_ORIGIN');
- }
- res.setHeader('Access-Control-Allow-Credentials', 'true');
- res.header(
- 'Access-Control-Allow-Methods',
- 'GET,HEAD,PUT,PATCH,POST,DELETE',
- );
- next();
- });
If you need custom logic, you can adjust the corsOptions
passed to app.enableCors()
.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
app.use((req, res, next) => { | |
const origin = req.headers.origin; | |
if (corsOriginList.includes(origin) || corsOriginList[0] === '*') { | |
res.setHeader('Access-Control-Allow-Origin', origin); | |
} else { | |
throw new InternalServerErrorException('Invalid CORS_ORIGIN'); | |
} | |
res.setHeader('Access-Control-Allow-Credentials', 'true'); | |
res.header( | |
'Access-Control-Allow-Methods', | |
'GET,HEAD,PUT,PATCH,POST,DELETE', | |
); | |
next(); | |
}); |
src/main.ts
Outdated
|
||
async function bootstrap() { | ||
dotenv.config(); // Load environment variables from .env file | ||
const app = await NestFactory.create(AppModule); | ||
const app = await NestFactory.create(AppModule, { cors: true }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant CORS configuration detected.
You have enabled CORS by setting { cors: true }
in NestFactory.create
, and later you enable CORS again using app.enableCors(corsOptions);
. This redundancy might cause unexpected behavior.
Consider removing the { cors: true }
option when creating the app, since you are configuring CORS with custom options later.
Apply this diff:
- const app = await NestFactory.create(AppModule, { cors: true });
+ const app = await NestFactory.create(AppModule);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const app = await NestFactory.create(AppModule, { cors: true }); | |
const app = await NestFactory.create(AppModule); |
if (corsOriginList[0] !== '*' && !validateCorsOriginList(corsOriginList)) { | ||
throw new Error('Invalid CORS_ORIGIN_LIST'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential issue with empty corsOriginList
.
If CORS_ORIGIN_LIST
is undefined or empty, accessing corsOriginList[0]
could lead to an error.
Add a check to handle cases where corsOriginList
is undefined or empty.
Apply this diff:
+ if (!corsOriginList || corsOriginList.length === 0) {
+ throw new Error('CORS_ORIGIN_LIST is not defined or empty');
+ }
if (corsOriginList[0] !== '*' && !validateCorsOriginList(corsOriginList)) {
throw new Error('Invalid CORS_ORIGIN_LIST');
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (corsOriginList[0] !== '*' && !validateCorsOriginList(corsOriginList)) { | |
throw new Error('Invalid CORS_ORIGIN_LIST'); | |
} | |
if (!corsOriginList || corsOriginList.length === 0) { | |
throw new Error('CORS_ORIGIN_LIST is not defined or empty'); | |
} | |
if (corsOriginList[0] !== '*' && !validateCorsOriginList(corsOriginList)) { | |
throw new Error('Invalid CORS_ORIGIN_LIST'); | |
} |
src/main.ts
Outdated
function validateCorsOriginList(corsOriginList: string[]): boolean { | ||
return corsOriginList.every((origin) => { | ||
return origin.includes('http://') || origin.includes('https://'); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve CORS origin validation.
The current validation only checks if the origins include http://
or https://
, which might not sufficiently validate the URLs.
Consider using the URL
constructor to validate each origin.
Apply this diff:
function validateCorsOriginList(corsOriginList: string[]): boolean {
- return corsOriginList.every((origin) => {
- return origin.includes('http://') || origin.includes('https://');
- });
+ return corsOriginList.every((origin) => {
+ try {
+ new URL(origin);
+ return true;
+ } catch (error) {
+ return false;
+ }
+ });
}
This approach ensures that each origin is a valid URL.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
function validateCorsOriginList(corsOriginList: string[]): boolean { | |
return corsOriginList.every((origin) => { | |
return origin.includes('http://') || origin.includes('https://'); | |
}); | |
} | |
function validateCorsOriginList(corsOriginList: string[]): boolean { | |
return corsOriginList.every((origin) => { | |
try { | |
new URL(origin); | |
return true; | |
} catch (error) { | |
return false; | |
} | |
}); | |
} |
src/main.ts
Outdated
if (corsOriginList.includes(origin) || corsOriginList[0] === '*') { | ||
res.setHeader('Access-Control-Allow-Origin', origin); | ||
} else { | ||
throw new InternalServerErrorException('Invalid CORS_ORIGIN'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improper error handling for invalid CORS origins.
Throwing an InternalServerErrorException
when the origin is invalid may not be appropriate and could expose internal details.
Instead of throwing an exception, you can simply not set the Access-Control-Allow-Origin
header, or respond with a 403 Forbidden status.
Apply this diff:
if (corsOriginList.includes(origin) || corsOriginList[0] === '*') {
res.setHeader('Access-Control-Allow-Origin', origin);
} else {
- throw new InternalServerErrorException('Invalid CORS_ORIGIN');
+ res.status(403).send('Forbidden');
+ return;
}
However, removing the custom middleware as suggested earlier would eliminate this issue.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (corsOriginList.includes(origin) || corsOriginList[0] === '*') { | |
res.setHeader('Access-Control-Allow-Origin', origin); | |
} else { | |
throw new InternalServerErrorException('Invalid CORS_ORIGIN'); | |
} | |
if (corsOriginList.includes(origin) || corsOriginList[0] === '*') { | |
res.setHeader('Access-Control-Allow-Origin', origin); | |
} else { | |
res.status(403).send('Forbidden'); | |
return; | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (2)
src/main.ts (2)
13-31
: LGTM: CORS configuration setup is well-implemented.The CORS configuration is properly implemented, addressing the PR objectives. Good practices include:
- Retrieving the CORS origin list from environment variables.
- Validating the CORS origin list.
- Appropriate error handling for empty or invalid CORS_ORIGIN_LIST.
- Correct definition of corsOptions object.
Consider adding a comment explaining the purpose of the
corsOriginList[0] !== '*'
check in the validation condition. This will improve code readability.
69-78
: LGTM: Improved CORS origin validation.The
validateCorsOriginList
function is well-implemented, addressing a past review comment. Using the URL constructor for validation ensures that each origin is a valid URL, which is a robust approach.Consider adding a check for the protocol to ensure only 'http:' and 'https:' URLs are allowed. This can be done by adding a condition after the URL constructor:
function validateCorsOriginList(corsOriginList: string[]): boolean { return corsOriginList.every((origin) => { try { const url = new URL(origin); return url.protocol === 'http:' || url.protocol === 'https:'; } catch (error) { return false; } }); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
- src/main.ts (2 hunks)
🔇 Additional comments (4)
src/main.ts (4)
2-2
: LGTM: Necessary imports added for security enhancements.The new imports for
helmet
,ConfigService
, andForbiddenException
are appropriate for implementing CORS and security headers as mentioned in the PR objectives.Also applies to: 6-7
61-62
: LGTM: Correct application of CORS and Helmet middleware.The application of CORS using
app.enableCors(corsOptions)
and the Helmet middleware aligns with the PR objectives. These additions will enhance the security of the application by properly handling CORS and setting various HTTP security headers.
12-12
: LGTM: Redundant CORS configuration removed.The
{ cors: true }
option inNestFactory.create
has been removed, addressing a past review comment. This change eliminates the potential for conflicting CORS configurations.
Line range hint
1-81
: Overall implementation aligns with PR objectives, but one issue remains.The changes in this file successfully implement CORS and security enhancements using Helmet, addressing the main objectives of the PR. Most past review comments have been addressed, improving the overall quality and security of the code.
However, there is still a redundancy issue with the custom CORS middleware (lines 45-59) that conflicts with the
app.enableCors(corsOptions)
call. As mentioned in a previous comment, this custom middleware should be removed to avoid potential conflicts and unexpected behavior.Once this final issue is resolved, the implementation will be fully aligned with the PR objectives and best practices for CORS and security handling in NestJS applications.
src/main.ts
Outdated
app.use((req, res, next) => { | ||
const origin = req.headers.origin; | ||
|
||
if (corsOriginList.includes(origin) || corsOriginList[0] === '*') { | ||
res.setHeader('Access-Control-Allow-Origin', origin); | ||
} else { | ||
throw new ForbiddenException('Origin not allowed'); | ||
} | ||
res.setHeader('Access-Control-Allow-Credentials', 'true'); | ||
res.header( | ||
'Access-Control-Allow-Methods', | ||
'GET,HEAD,PUT,PATCH,POST,DELETE', | ||
); | ||
next(); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove redundant custom CORS middleware.
The custom CORS middleware implementation conflicts with the app.enableCors(corsOptions)
call on line 61. This redundancy can lead to unexpected behavior and was previously pointed out in a past review comment.
Consider removing the custom middleware and relying solely on app.enableCors(corsOptions)
for CORS handling. If custom logic is needed, it should be incorporated into the corsOptions
object.
Apply this diff to remove the custom middleware:
- app.use((req, res, next) => {
- const origin = req.headers.origin;
-
- if (corsOriginList.includes(origin) || corsOriginList[0] === '*') {
- res.setHeader('Access-Control-Allow-Origin', origin);
- } else {
- throw new ForbiddenException('Origin not allowed');
- }
- res.setHeader('Access-Control-Allow-Credentials', 'true');
- res.header(
- 'Access-Control-Allow-Methods',
- 'GET,HEAD,PUT,PATCH,POST,DELETE',
- );
- next();
- });
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
app.use((req, res, next) => { | |
const origin = req.headers.origin; | |
if (corsOriginList.includes(origin) || corsOriginList[0] === '*') { | |
res.setHeader('Access-Control-Allow-Origin', origin); | |
} else { | |
throw new ForbiddenException('Origin not allowed'); | |
} | |
res.setHeader('Access-Control-Allow-Credentials', 'true'); | |
res.header( | |
'Access-Control-Allow-Methods', | |
'GET,HEAD,PUT,PATCH,POST,DELETE', | |
); | |
next(); | |
}); |
Quality Gate passedIssues Measures |
Summary by CodeRabbit
New Features
helmet
middleware for improved HTTP header management.Bug Fixes
"middleware_micorservice"
to"middleware_microservice"
.Chores
cors
andhelmet
.