Skip to content

Commit 730e046

Browse files
committed
feat: single point for security gate
1 parent 3f21fd7 commit 730e046

File tree

2 files changed

+15
-36
lines changed

2 files changed

+15
-36
lines changed

test-app/runtime/src/main/cpp/HMRSupport.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,23 @@ std::string CanonicalizeHttpUrlKey(const std::string& url) {
210210
}
211211

212212
// Minimal HTTP fetch using java.net.* via JNI. Returns true on success (2xx) and non-empty body.
213+
// Security: This is the single point of enforcement for remote module loading.
214+
// In debug mode, all URLs are allowed. In production, checks security.allowRemoteModules
215+
// and security.remoteModuleAllowlist from the app config.
213216
bool HttpFetchText(const std::string& url, std::string& out, std::string& contentType, int& status) {
214217
out.clear();
215218
contentType.clear();
216219
status = 0;
220+
221+
// Security gate: check if remote module loading is allowed before any HTTP fetch.
222+
if (!IsRemoteUrlAllowed(url)) {
223+
status = 403; // Forbidden
224+
if (IsScriptLoadingLogEnabled()) {
225+
DEBUG_WRITE("[http-esm][security][blocked] %s", url.c_str());
226+
}
227+
return false;
228+
}
229+
217230
try {
218231
JEnv env;
219232

test-app/runtime/src/main/cpp/ModuleInternalCallbacks.cpp

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,6 @@ extern std::unordered_map<std::string, v8::Global<v8::Module>> g_moduleRegistry;
2424
// Forward declaration used by logging helper
2525
std::string GetApplicationPath();
2626

27-
// Logging flag now provided via DevFlags for fast cached access
28-
29-
// Security gate
30-
// In debug mode, all URLs are allowed. In production, checks security.allowRemoteModules and security.remoteModuleAllowlist
31-
static inline bool IsHttpUrlAllowedForLoading(const std::string& url) {
32-
return IsRemoteUrlAllowed(url);
33-
}
34-
35-
// Helper to create a security error message for blocked remote modules
36-
static std::string GetRemoteModuleBlockedMessage(const std::string& url) {
37-
if (!IsRemoteModulesAllowed()) {
38-
return "Remote ES modules are not allowed in production. URL: " + url +
39-
". Enable via security.allowRemoteModules in nativescript.config.ts";
40-
}
41-
return "Remote URL not in security.remoteModuleAllowlist: " + url;
42-
}
4327

4428
// Diagnostic helper: emit detailed V8 compile error info for HTTP ESM sources.
4529
static void LogHttpCompileDiagnostics(v8::Isolate* isolate,
@@ -388,17 +372,8 @@ v8::MaybeLocal<v8::Module> ResolveModuleCallback(v8::Local<v8::Context> context,
388372
}
389373

390374
// HTTP(S) ESM support: resolve, fetch and compile from dev server
375+
// Security: HttpFetchText gates remote module access centrally.
391376
if (spec.rfind("http://", 0) == 0 || spec.rfind("https://", 0) == 0) {
392-
// Security gate: check if remote module loading is allowed
393-
if (!IsHttpUrlAllowedForLoading(spec)) {
394-
std::string msg = GetRemoteModuleBlockedMessage(spec);
395-
if (IsScriptLoadingLogEnabled()) {
396-
DEBUG_WRITE("[http-esm][security][blocked] %s", msg.c_str());
397-
}
398-
isolate->ThrowException(v8::Exception::Error(ArgConverter::ConvertToV8String(isolate, msg)));
399-
return v8::MaybeLocal<v8::Module>();
400-
}
401-
402377
std::string canonical = tns::CanonicalizeHttpUrlKey(spec);
403378
if (IsScriptLoadingLogEnabled()) {
404379
DEBUG_WRITE("[http-esm][resolve] spec=%s canonical=%s", spec.c_str(), canonical.c_str());
@@ -893,17 +868,8 @@ v8::MaybeLocal<v8::Promise> ImportModuleDynamicallyCallback(
893868
}
894869

895870
// Handle HTTP(S) dynamic import directly
871+
// Security: HttpFetchText gates remote module access centrally.
896872
if (!spec.empty() && isHttpLike(spec)) {
897-
// Security gate: check if remote module loading is allowed
898-
if (!IsHttpUrlAllowedForLoading(spec)) {
899-
std::string msg = GetRemoteModuleBlockedMessage(spec);
900-
if (IsScriptLoadingLogEnabled()) {
901-
DEBUG_WRITE("[http-esm][dyn][security][blocked] %s", msg.c_str());
902-
}
903-
resolver->Reject(context, v8::Exception::Error(ArgConverter::ConvertToV8String(isolate, msg))).Check();
904-
return scope.Escape(resolver->GetPromise());
905-
}
906-
907873
std::string canonical = tns::CanonicalizeHttpUrlKey(spec);
908874
if (IsScriptLoadingLogEnabled()) {
909875
DEBUG_WRITE("[http-esm][dyn][resolve] spec=%s canonical=%s", spec.c_str(), canonical.c_str());

0 commit comments

Comments
 (0)