Repository navigation
feat(common): dual-server db validation for byod config #371
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
Merged
Merged
Changes from 3 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
c5a8b4e
feat(common): dual-server db validation for byod config
yash-pouranik e7c95aa
fix: address CodeRabbit feedback for DB validation
yash-pouranik f7a5d9c
fix(security): Address CodeRabbit PR feedback for SSRF, Auth, and Err…
yash-pouranik d285219
feat(security): implement DNS Rebinding protection & MongoDB connecti…
yash-pouranik 13d2ed3
fix(public-api): restore mocked middlewares in internal.test.js to fi…
yash-pouranik 9556e9c
fix(public-api): fix REDIS_URL missing in internal tests and address …
yash-pouranik 435ed7a
fix(common): update isRestrictedIPv6 to parse IPv4-mapped addresses c…
yash-pouranik 5e02005
test(public-api): add successful connection verification test for /ap…
yash-pouranik 347cce2
test(dashboard-api): add missing verification test cases for project.…
yash-pouranik 293cf33
test(dashboard-api): fix byod test expectations for error handling an…
yash-pouranik f73cabe
test: refine byod and internal route test expectations
yash-pouranik File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| const express = require('express'); | ||
| const mongoose = require('mongoose'); | ||
| const crypto = require('crypto'); | ||
| const { getPublicIp, isSafeUri } = require('@urbackend/common'); | ||
| const router = express.Router(); | ||
|
|
||
| // Middleware to protect internal routes | ||
| const internalAuth = (req, res, next) => { | ||
| const secret = process.env.INTERNAL_SECRET; | ||
| if (!secret) { | ||
| console.error("INTERNAL_SECRET is not configured on Public API"); | ||
| return res.status(500).json({ success: false, data: {}, message: "Server misconfiguration" }); | ||
| } | ||
|
|
||
| const header = req.headers['x-internal-secret']; | ||
| const providedSecret = Array.isArray(header) ? header[0] : (header || ''); | ||
|
|
||
| // Convert both to buffers of the same length to use timingSafeEqual | ||
| const secretBuffer = Buffer.from(String(secret), 'utf8'); | ||
| const providedBuffer = Buffer.from(String(providedSecret), 'utf8'); | ||
|
|
||
| if (secretBuffer.length !== providedBuffer.length || !crypto.timingSafeEqual(secretBuffer, providedBuffer)) { | ||
| return res.status(403).json({ success: false, data: {}, message: "Forbidden: Invalid internal secret" }); | ||
| } | ||
|
|
||
| next(); | ||
| }; | ||
|
|
||
| router.post('/test-db', internalAuth, async (req, res) => { | ||
| const { dbUri } = req.body; | ||
| if (!dbUri) { | ||
| return res.status(400).json({ success: false, data: {}, message: "dbUri is required" }); | ||
| } | ||
|
|
||
| if (!(await isSafeUri(dbUri))) { | ||
| return res.status(400).json({ | ||
| success: false, | ||
| data: {}, | ||
| message: "DB URI is pointing to a restricted host, internal network, or unsupported URI format.", | ||
| }); | ||
| } | ||
|
|
||
|
yash-pouranik marked this conversation as resolved.
|
||
| console.log("[Internal] Verifying connection for external DB..."); | ||
| let tempConn = null; | ||
| try { | ||
| tempConn = mongoose.createConnection(dbUri, { | ||
| serverSelectionTimeoutMS: 5000, | ||
| }); | ||
| await tempConn.asPromise(); | ||
| return res.status(200).json({ success: true, data: {}, message: "Connection verified" }); | ||
| } catch (connErr) { | ||
| console.error("[Internal] Verification Connection Failed:", connErr.message); | ||
| let errorMsg = "Could not connect to the provided MongoDB URI."; | ||
| let serverIp = null; | ||
|
|
||
| if ( | ||
| connErr.message.includes("Server selection timed out") || | ||
| connErr.message.includes("Could not connect") | ||
| ) { | ||
| try { | ||
| serverIp = await getPublicIp(); | ||
| errorMsg = `Access Denied: Please whitelist Server IP [${serverIp}] in MongoDB Atlas.`; | ||
| } catch (ipErr) { | ||
| console.error("Failed to fetch Public API IP:", ipErr.message); | ||
| } | ||
| } | ||
|
|
||
| return res.status(400).json({ success: false, data: { serverIp }, message: errorMsg }); | ||
| } finally { | ||
| if (tempConn) { | ||
| await tempConn.close(); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| module.exports = router; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.