@abi-software/simulationvuer 4.0.3 → 4.0.4
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/package.json +1 -1
- package/vite.config.js +75 -8
package/package.json
CHANGED
package/vite.config.js
CHANGED
|
@@ -82,21 +82,88 @@ export default defineConfig(({ command, mode }) => {
|
|
|
82
82
|
// Serve libopencor files from @opencor/opencor during development so the dynamic import in opencor.es.js
|
|
83
83
|
// resolves same-origin (required for pthread Workers).
|
|
84
84
|
|
|
85
|
+
// Resolve symlinks in libopencorDir once so the per-request guard compares real paths on both sides.
|
|
86
|
+
|
|
87
|
+
let realLibopencorDir;
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
realLibopencorDir = fs.realpathSync(libopencorDir);
|
|
91
|
+
} catch {
|
|
92
|
+
realLibopencorDir = libopencorDir;
|
|
93
|
+
}
|
|
94
|
+
|
|
85
95
|
server.middlewares.use((req, res, next) => {
|
|
86
|
-
|
|
96
|
+
// Parse the URL to strip any query string, and decode it safely (malformed sequences are rejected).
|
|
87
97
|
|
|
88
|
-
|
|
98
|
+
let pathname;
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
pathname = decodeURIComponent(
|
|
102
|
+
new URL(req.url, "http://localhost").pathname,
|
|
103
|
+
);
|
|
104
|
+
} catch {
|
|
89
105
|
next();
|
|
90
106
|
|
|
91
107
|
return;
|
|
92
108
|
}
|
|
93
109
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
110
|
+
if (!pathname.startsWith("/libopencor/")) {
|
|
111
|
+
next();
|
|
112
|
+
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Resolve the requested subpath and verify the result stays within libopencorDir, guarding against
|
|
117
|
+
// directory traversal (e.g., "/libopencor/../../..." or percent-encoded ".." segments) and symlink
|
|
118
|
+
// escapes (a symlink inside libopencorDir pointing outside would pass a purely lexical check).
|
|
119
|
+
// Note: realpathSync() resolves symlinks, so a symlink pointing outside libopencorDir resolves to a path
|
|
120
|
+
// outside it, which the relative check below rejects. It also throws if the path doesn't exist.
|
|
121
|
+
|
|
122
|
+
let filePath;
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
filePath = fs.realpathSync(
|
|
126
|
+
path.resolve(
|
|
127
|
+
libopencorDir,
|
|
128
|
+
pathname.slice("/libopencor/".length),
|
|
129
|
+
),
|
|
130
|
+
);
|
|
131
|
+
} catch {
|
|
132
|
+
next();
|
|
133
|
+
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Reject paths escaping the directory: exactly "..", starting with "../", or absolute (e.g., a
|
|
138
|
+
// different drive on Windows).
|
|
139
|
+
// Note: a plain startsWith("..") check would wrongly reject legitimate files like "..foo.js".
|
|
140
|
+
|
|
141
|
+
const relative = path.relative(realLibopencorDir, filePath);
|
|
142
|
+
|
|
143
|
+
if (
|
|
144
|
+
relative === "" ||
|
|
145
|
+
relative === ".." ||
|
|
146
|
+
relative.startsWith(`..${path.sep}`) ||
|
|
147
|
+
path.isAbsolute(relative)
|
|
148
|
+
) {
|
|
149
|
+
next();
|
|
150
|
+
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Read the file and serve it with the correct headers.
|
|
155
|
+
|
|
156
|
+
let content;
|
|
157
|
+
|
|
158
|
+
try {
|
|
159
|
+
if (!fs.statSync(filePath).isFile()) {
|
|
160
|
+
next();
|
|
161
|
+
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
98
164
|
|
|
99
|
-
|
|
165
|
+
content = fs.readFileSync(filePath);
|
|
166
|
+
} catch {
|
|
100
167
|
next();
|
|
101
168
|
|
|
102
169
|
return;
|
|
@@ -107,7 +174,7 @@ export default defineConfig(({ command, mode }) => {
|
|
|
107
174
|
"Cross-Origin-Embedder-Policy": "require-corp",
|
|
108
175
|
"Cross-Origin-Resource-Policy": "same-origin",
|
|
109
176
|
});
|
|
110
|
-
res.end(
|
|
177
|
+
res.end(content);
|
|
111
178
|
});
|
|
112
179
|
},
|
|
113
180
|
closeBundle() {
|