dinou 4.0.9 → 4.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dinou/core/server.js +16 -5
- package/dinou/package.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [4.0.11]
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Security: Fix server functions endpoint vulnerability and add improvements.
|
|
13
|
+
|
|
14
|
+
## [4.0.10]
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Server Functions endpoint vulnerability.
|
|
19
|
+
|
|
8
20
|
## [4.0.9]
|
|
9
21
|
|
|
10
22
|
### Changed
|
package/dinou/core/server.js
CHANGED
|
@@ -752,7 +752,7 @@ function isOriginAllowed(req) {
|
|
|
752
752
|
try {
|
|
753
753
|
// Parse to ignore protocol (http/https) and port if they differ subtly
|
|
754
754
|
const originHost = new URL(origin).host;
|
|
755
|
-
const serverHost = req.headers.host;
|
|
755
|
+
const serverHost = req.headers["x-forwarded-host"] || req.headers.host;
|
|
756
756
|
|
|
757
757
|
// Compare host (domain:port)
|
|
758
758
|
return originHost === serverHost;
|
|
@@ -782,7 +782,7 @@ app.post("/____server_function____", async (req, res) => {
|
|
|
782
782
|
|
|
783
783
|
// 1. Check Origin (Prevent calls from other domains)
|
|
784
784
|
const origin = req.headers.origin;
|
|
785
|
-
const host = req.headers.host;
|
|
785
|
+
const host = req.headers["x-forwarded-host"] || req.headers.host;
|
|
786
786
|
|
|
787
787
|
// Note: Locally sometimes origin is undefined or null, allow in dev if necessary
|
|
788
788
|
if (!isDevelopment && origin && !origin.includes(host)) {
|
|
@@ -851,10 +851,15 @@ app.post("/____server_function____", async (req, res) => {
|
|
|
851
851
|
|
|
852
852
|
// Extract relativePath and normalize (remove 'file://' and potential '/')
|
|
853
853
|
let relativePath = fileUrl.replace(/^file:\/\/\/?/, "").trim();
|
|
854
|
-
|
|
854
|
+
const normalizedRelative = relativePath.replace(/\\/g, "/");
|
|
855
|
+
if (
|
|
856
|
+
normalizedRelative.startsWith("/") ||
|
|
857
|
+
normalizedRelative.includes("..") ||
|
|
858
|
+
normalizedRelative.includes(":")
|
|
859
|
+
) {
|
|
855
860
|
return res
|
|
856
861
|
.status(400)
|
|
857
|
-
.json({ error: "Invalid path: no absolute or
|
|
862
|
+
.json({ error: "Invalid path: no absolute, traversal, or drive letter allowed" });
|
|
858
863
|
}
|
|
859
864
|
// console.log("relPath", relativePath);
|
|
860
865
|
// Restrict to 'src/' folder: prepend 'src/' if missing, and resolve absolutePath
|
|
@@ -881,6 +886,11 @@ app.post("/____server_function____", async (req, res) => {
|
|
|
881
886
|
// Prod: use manifest (relativePath is already normalized)
|
|
882
887
|
allowedExports = serverFunctionsManifest[relativePath];
|
|
883
888
|
} else {
|
|
889
|
+
if (!isDevelopment) {
|
|
890
|
+
return res
|
|
891
|
+
.status(403)
|
|
892
|
+
.json({ error: "Access denied: Manifest missing in production" });
|
|
893
|
+
}
|
|
884
894
|
const fileContent = readFileSync(absolutePath, "utf8"); // Reads only once
|
|
885
895
|
if (!useServerRegex.test(fileContent)) {
|
|
886
896
|
return res
|
|
@@ -895,7 +905,8 @@ app.post("/____server_function____", async (req, res) => {
|
|
|
895
905
|
// Validate exportName against allowedExports
|
|
896
906
|
if (
|
|
897
907
|
!exportName ||
|
|
898
|
-
|
|
908
|
+
!allowedExports ||
|
|
909
|
+
!allowedExports.has(exportName)
|
|
899
910
|
) {
|
|
900
911
|
return res.status(400).json({ error: "Invalid export name" });
|
|
901
912
|
}
|
package/dinou/package.json
CHANGED