fix(apply): reject reserved module names in validate_bundle (parity)
The interactive create path rejects a module whose name shadows a built-in SDK namespace (`kv`, `secrets`, …) so `import "kv"` can't resolve to a user module, but `pic apply`'s `validate_bundle` skipped the check — a parity gap that let a manifest create what the dashboard forbids. Gate it on `ScriptKind::Module` and share the same `RESERVED_MODULE_NAMES` const (now `pub(crate)`); endpoints remain unrestricted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -260,7 +260,7 @@ async fn create_script<R: ScriptRepository, L: ExecutionLogRepository>(
|
|||||||
/// real KV bridge — defense against author confusion, not a security
|
/// real KV bridge — defense against author confusion, not a security
|
||||||
/// boundary (stdlib namespaces and module imports already live in
|
/// boundary (stdlib namespaces and module imports already live in
|
||||||
/// disjoint Rhai scopes).
|
/// disjoint Rhai scopes).
|
||||||
const RESERVED_MODULE_NAMES: &[&str] = &[
|
pub(crate) const RESERVED_MODULE_NAMES: &[&str] = &[
|
||||||
"log",
|
"log",
|
||||||
"regex",
|
"regex",
|
||||||
"random",
|
"random",
|
||||||
|
|||||||
@@ -886,6 +886,15 @@ impl ApplyService {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
let res = if s.kind == ScriptKind::Module {
|
let res = if s.kind == ScriptKind::Module {
|
||||||
|
// Parity with the interactive create path (`api.rs`): a module
|
||||||
|
// may not shadow a built-in SDK namespace, or `import "kv"`
|
||||||
|
// could resolve to a user module instead of the real bridge.
|
||||||
|
if crate::api::RESERVED_MODULE_NAMES.contains(&s.name.as_str()) {
|
||||||
|
return Err(ApplyError::Invalid(format!(
|
||||||
|
"script `{}`: reserved module name (shadows a built-in SDK namespace)",
|
||||||
|
s.name
|
||||||
|
)));
|
||||||
|
}
|
||||||
self.validator.validate_module(&s.source)
|
self.validator.validate_module(&s.source)
|
||||||
} else {
|
} else {
|
||||||
self.validator.validate(&s.source)
|
self.validator.validate(&s.source)
|
||||||
|
|||||||
Reference in New Issue
Block a user