@vorionsys/atsf-core 0.2.3 → 0.2.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/dist/api/index.d.ts +1 -1
- package/dist/api/index.js +1 -1
- package/dist/api/server.d.ts +2 -2
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +147 -184
- package/dist/api/server.js.map +1 -1
- package/dist/arbitration/index.d.ts +4 -4
- package/dist/arbitration/index.d.ts.map +1 -1
- package/dist/arbitration/index.js +41 -46
- package/dist/arbitration/index.js.map +1 -1
- package/dist/arbitration/types.d.ts +10 -10
- package/dist/arbitration/types.d.ts.map +1 -1
- package/dist/basis/evaluator.d.ts +1 -1
- package/dist/basis/evaluator.d.ts.map +1 -1
- package/dist/basis/evaluator.js +54 -56
- package/dist/basis/evaluator.js.map +1 -1
- package/dist/basis/index.d.ts +3 -3
- package/dist/basis/index.js +3 -3
- package/dist/basis/parser.d.ts +2 -2
- package/dist/basis/parser.d.ts.map +1 -1
- package/dist/basis/parser.js +25 -32
- package/dist/basis/parser.js.map +1 -1
- package/dist/basis/types.d.ts +2 -2
- package/dist/chain/index.d.ts.map +1 -1
- package/dist/chain/index.js +16 -16
- package/dist/chain/index.js.map +1 -1
- package/dist/cognigate/index.d.ts +1 -1
- package/dist/cognigate/index.d.ts.map +1 -1
- package/dist/cognigate/index.js +33 -44
- package/dist/cognigate/index.js.map +1 -1
- package/dist/common/adapters.d.ts +4 -4
- package/dist/common/adapters.d.ts.map +1 -1
- package/dist/common/adapters.js +52 -62
- package/dist/common/adapters.js.map +1 -1
- package/dist/common/config.d.ts +69 -68
- package/dist/common/config.d.ts.map +1 -1
- package/dist/common/config.js +50 -50
- package/dist/common/config.js.map +1 -1
- package/dist/common/index.d.ts +4 -4
- package/dist/common/index.js +4 -4
- package/dist/common/logger.d.ts +1 -1
- package/dist/common/logger.js +8 -8
- package/dist/common/types.d.ts +5 -5
- package/dist/common/types.js +5 -5
- package/dist/containment/index.d.ts +3 -3
- package/dist/containment/index.d.ts.map +1 -1
- package/dist/containment/index.js +105 -119
- package/dist/containment/index.js.map +1 -1
- package/dist/containment/types.d.ts +11 -11
- package/dist/containment/types.d.ts.map +1 -1
- package/dist/contracts/index.d.ts +9 -9
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +54 -59
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/types.d.ts +12 -12
- package/dist/contracts/types.d.ts.map +1 -1
- package/dist/crewai/callback.d.ts +2 -2
- package/dist/crewai/callback.d.ts.map +1 -1
- package/dist/crewai/callback.js +27 -27
- package/dist/crewai/callback.js.map +1 -1
- package/dist/crewai/executor.d.ts +95 -4
- package/dist/crewai/executor.d.ts.map +1 -1
- package/dist/crewai/executor.js +457 -16
- package/dist/crewai/executor.js.map +1 -1
- package/dist/crewai/index.d.ts +4 -4
- package/dist/crewai/index.js +4 -4
- package/dist/crewai/tools.d.ts +1 -1
- package/dist/crewai/tools.d.ts.map +1 -1
- package/dist/crewai/tools.js +38 -39
- package/dist/crewai/tools.js.map +1 -1
- package/dist/crewai/types.d.ts +66 -3
- package/dist/crewai/types.d.ts.map +1 -1
- package/dist/enforce/index.d.ts +229 -7
- package/dist/enforce/index.d.ts.map +1 -1
- package/dist/enforce/index.js +52 -80
- package/dist/enforce/index.js.map +1 -1
- package/dist/enforce/trust-aware-enforcement-service.d.ts +8 -8
- package/dist/enforce/trust-aware-enforcement-service.d.ts.map +1 -1
- package/dist/enforce/trust-aware-enforcement-service.js +107 -125
- package/dist/enforce/trust-aware-enforcement-service.js.map +1 -1
- package/dist/governance/fluid-workflow.d.ts +8 -8
- package/dist/governance/fluid-workflow.d.ts.map +1 -1
- package/dist/governance/fluid-workflow.js +86 -114
- package/dist/governance/fluid-workflow.js.map +1 -1
- package/dist/governance/index.d.ts +7 -7
- package/dist/governance/index.d.ts.map +1 -1
- package/dist/governance/index.js +74 -81
- package/dist/governance/index.js.map +1 -1
- package/dist/governance/proof-bridge.d.ts +6 -6
- package/dist/governance/proof-bridge.d.ts.map +1 -1
- package/dist/governance/proof-bridge.js +5 -5
- package/dist/governance/proof-bridge.js.map +1 -1
- package/dist/governance/types.d.ts +9 -16
- package/dist/governance/types.d.ts.map +1 -1
- package/dist/governance/types.js.map +1 -1
- package/dist/index.d.ts +27 -29
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -31
- package/dist/index.js.map +1 -1
- package/dist/intent/index.d.ts +55 -5
- package/dist/intent/index.d.ts.map +1 -1
- package/dist/intent/index.js +21 -24
- package/dist/intent/index.js.map +1 -1
- package/dist/intent/persistent-intent-service.d.ts +2 -2
- package/dist/intent/persistent-intent-service.d.ts.map +1 -1
- package/dist/intent/persistent-intent-service.js +31 -43
- package/dist/intent/persistent-intent-service.js.map +1 -1
- package/dist/intent/supabase-intent-repository.d.ts +124 -0
- package/dist/intent/supabase-intent-repository.d.ts.map +1 -0
- package/dist/intent/supabase-intent-repository.js +404 -0
- package/dist/intent/supabase-intent-repository.js.map +1 -0
- package/dist/langchain/callback.d.ts +2 -2
- package/dist/langchain/callback.d.ts.map +1 -1
- package/dist/langchain/callback.js +30 -30
- package/dist/langchain/callback.js.map +1 -1
- package/dist/langchain/executor.d.ts +4 -4
- package/dist/langchain/executor.d.ts.map +1 -1
- package/dist/langchain/executor.js +80 -82
- package/dist/langchain/executor.js.map +1 -1
- package/dist/langchain/index.d.ts +5 -5
- package/dist/langchain/index.js +5 -5
- package/dist/langchain/tools.d.ts +1 -1
- package/dist/langchain/tools.d.ts.map +1 -1
- package/dist/langchain/tools.js +34 -36
- package/dist/langchain/tools.js.map +1 -1
- package/dist/langchain/types.d.ts +3 -3
- package/dist/langchain/types.d.ts.map +1 -1
- package/dist/layers/implementations/L0-request-format.d.ts +2 -2
- package/dist/layers/implementations/L0-request-format.d.ts.map +1 -1
- package/dist/layers/implementations/L0-request-format.js +52 -54
- package/dist/layers/implementations/L0-request-format.js.map +1 -1
- package/dist/layers/implementations/L1-input-size.d.ts +2 -2
- package/dist/layers/implementations/L1-input-size.d.ts.map +1 -1
- package/dist/layers/implementations/L1-input-size.js +39 -49
- package/dist/layers/implementations/L1-input-size.js.map +1 -1
- package/dist/layers/implementations/L2-charset-sanitizer.d.ts +2 -2
- package/dist/layers/implementations/L2-charset-sanitizer.d.ts.map +1 -1
- package/dist/layers/implementations/L2-charset-sanitizer.js +71 -81
- package/dist/layers/implementations/L2-charset-sanitizer.js.map +1 -1
- package/dist/layers/implementations/L3-schema-conformance.d.ts +3 -3
- package/dist/layers/implementations/L3-schema-conformance.d.ts.map +1 -1
- package/dist/layers/implementations/L3-schema-conformance.js +73 -82
- package/dist/layers/implementations/L3-schema-conformance.js.map +1 -1
- package/dist/layers/implementations/L4-injection-detector.d.ts +4 -4
- package/dist/layers/implementations/L4-injection-detector.d.ts.map +1 -1
- package/dist/layers/implementations/L4-injection-detector.js +81 -85
- package/dist/layers/implementations/L4-injection-detector.js.map +1 -1
- package/dist/layers/implementations/L5-rate-limiter.d.ts +2 -2
- package/dist/layers/implementations/L5-rate-limiter.d.ts.map +1 -1
- package/dist/layers/implementations/L5-rate-limiter.js +20 -20
- package/dist/layers/implementations/L5-rate-limiter.js.map +1 -1
- package/dist/layers/implementations/index.d.ts +6 -6
- package/dist/layers/implementations/index.d.ts.map +1 -1
- package/dist/layers/implementations/index.js +6 -6
- package/dist/layers/implementations/index.js.map +1 -1
- package/dist/layers/index.d.ts +3 -3
- package/dist/layers/index.d.ts.map +1 -1
- package/dist/layers/index.js +71 -99
- package/dist/layers/index.js.map +1 -1
- package/dist/layers/types.d.ts +16 -16
- package/dist/layers/types.d.ts.map +1 -1
- package/dist/persistence/file.d.ts +3 -3
- package/dist/persistence/file.d.ts.map +1 -1
- package/dist/persistence/file.js +28 -32
- package/dist/persistence/file.js.map +1 -1
- package/dist/persistence/index.d.ts +7 -7
- package/dist/persistence/index.d.ts.map +1 -1
- package/dist/persistence/index.js +18 -18
- package/dist/persistence/index.js.map +1 -1
- package/dist/persistence/memory.d.ts +3 -3
- package/dist/persistence/memory.d.ts.map +1 -1
- package/dist/persistence/memory.js +8 -10
- package/dist/persistence/memory.js.map +1 -1
- package/dist/persistence/sqlite.d.ts +3 -3
- package/dist/persistence/sqlite.d.ts.map +1 -1
- package/dist/persistence/sqlite.js +40 -39
- package/dist/persistence/sqlite.js.map +1 -1
- package/dist/persistence/supabase.d.ts +3 -3
- package/dist/persistence/supabase.d.ts.map +1 -1
- package/dist/persistence/supabase.js +45 -43
- package/dist/persistence/supabase.js.map +1 -1
- package/dist/persistence/types.d.ts +5 -5
- package/dist/phase6/ceiling.d.ts +5 -5
- package/dist/phase6/ceiling.d.ts.map +1 -1
- package/dist/phase6/ceiling.js +36 -69
- package/dist/phase6/ceiling.js.map +1 -1
- package/dist/phase6/context.d.ts +3 -3
- package/dist/phase6/context.d.ts.map +1 -1
- package/dist/phase6/context.js +47 -93
- package/dist/phase6/context.js.map +1 -1
- package/dist/phase6/index.d.ts +12 -12
- package/dist/phase6/index.d.ts.map +1 -1
- package/dist/phase6/index.js +15 -15
- package/dist/phase6/index.js.map +1 -1
- package/dist/phase6/presets.d.ts +2 -2
- package/dist/phase6/presets.d.ts.map +1 -1
- package/dist/phase6/presets.js +33 -39
- package/dist/phase6/presets.js.map +1 -1
- package/dist/phase6/provenance.d.ts +4 -4
- package/dist/phase6/provenance.d.ts.map +1 -1
- package/dist/phase6/provenance.js +35 -42
- package/dist/phase6/provenance.js.map +1 -1
- package/dist/phase6/role-gates/index.d.ts +2 -2
- package/dist/phase6/role-gates/index.js +2 -2
- package/dist/phase6/role-gates/kernel.d.ts.map +1 -1
- package/dist/phase6/role-gates/kernel.js +16 -16
- package/dist/phase6/role-gates/kernel.js.map +1 -1
- package/dist/phase6/role-gates/policy.d.ts +2 -2
- package/dist/phase6/role-gates/policy.js +6 -6
- package/dist/phase6/role-gates.d.ts +4 -4
- package/dist/phase6/role-gates.d.ts.map +1 -1
- package/dist/phase6/role-gates.js +58 -80
- package/dist/phase6/role-gates.js.map +1 -1
- package/dist/phase6/types.d.ts +20 -19
- package/dist/phase6/types.d.ts.map +1 -1
- package/dist/phase6/types.js +82 -177
- package/dist/phase6/types.js.map +1 -1
- package/dist/phase6/weight-presets/canonical.d.ts.map +1 -1
- package/dist/phase6/weight-presets/canonical.js +10 -10
- package/dist/phase6/weight-presets/canonical.js.map +1 -1
- package/dist/phase6/weight-presets/deltas.d.ts +2 -2
- package/dist/phase6/weight-presets/deltas.d.ts.map +1 -1
- package/dist/phase6/weight-presets/deltas.js +27 -27
- package/dist/phase6/weight-presets/deltas.js.map +1 -1
- package/dist/phase6/weight-presets/index.d.ts +3 -3
- package/dist/phase6/weight-presets/index.js +3 -3
- package/dist/phase6/weight-presets/merger.d.ts +2 -2
- package/dist/phase6/weight-presets/merger.d.ts.map +1 -1
- package/dist/phase6/weight-presets/merger.js +43 -39
- package/dist/phase6/weight-presets/merger.js.map +1 -1
- package/dist/proof/index.d.ts +3 -3
- package/dist/proof/index.d.ts.map +1 -1
- package/dist/proof/index.js +38 -44
- package/dist/proof/index.js.map +1 -1
- package/dist/proof/merkle.d.ts +24 -3
- package/dist/proof/merkle.d.ts.map +1 -1
- package/dist/proof/merkle.js +116 -32
- package/dist/proof/merkle.js.map +1 -1
- package/dist/proof/zk-proofs.d.ts +6 -6
- package/dist/proof/zk-proofs.d.ts.map +1 -1
- package/dist/proof/zk-proofs.js +43 -42
- package/dist/proof/zk-proofs.js.map +1 -1
- package/dist/provenance/index.d.ts +3 -3
- package/dist/provenance/index.d.ts.map +1 -1
- package/dist/provenance/index.js +17 -19
- package/dist/provenance/index.js.map +1 -1
- package/dist/provenance/types.d.ts +4 -4
- package/dist/provenance/types.d.ts.map +1 -1
- package/dist/sandbox-training/challenges.d.ts +1 -1
- package/dist/sandbox-training/challenges.d.ts.map +1 -1
- package/dist/sandbox-training/challenges.js +228 -228
- package/dist/sandbox-training/challenges.js.map +1 -1
- package/dist/sandbox-training/graduation.d.ts +1 -1
- package/dist/sandbox-training/graduation.d.ts.map +1 -1
- package/dist/sandbox-training/graduation.js +15 -14
- package/dist/sandbox-training/graduation.js.map +1 -1
- package/dist/sandbox-training/index.d.ts +9 -9
- package/dist/sandbox-training/index.d.ts.map +1 -1
- package/dist/sandbox-training/index.js +6 -6
- package/dist/sandbox-training/index.js.map +1 -1
- package/dist/sandbox-training/promotion-service.d.ts +4 -4
- package/dist/sandbox-training/promotion-service.d.ts.map +1 -1
- package/dist/sandbox-training/promotion-service.js +5 -5
- package/dist/sandbox-training/promotion-service.js.map +1 -1
- package/dist/sandbox-training/runner.d.ts +1 -1
- package/dist/sandbox-training/runner.d.ts.map +1 -1
- package/dist/sandbox-training/runner.js +73 -74
- package/dist/sandbox-training/runner.js.map +1 -1
- package/dist/sandbox-training/scorer.d.ts +4 -4
- package/dist/sandbox-training/scorer.js +5 -5
- package/dist/sandbox-training/types.d.ts +4 -4
- package/dist/sandbox-training/types.d.ts.map +1 -1
- package/dist/sandbox-training/types.js +7 -11
- package/dist/sandbox-training/types.js.map +1 -1
- package/dist/trust-engine/ceiling-enforcement/audit.d.ts +1 -1
- package/dist/trust-engine/ceiling-enforcement/audit.d.ts.map +1 -1
- package/dist/trust-engine/ceiling-enforcement/audit.js +4 -3
- package/dist/trust-engine/ceiling-enforcement/audit.js.map +1 -1
- package/dist/trust-engine/ceiling-enforcement/index.d.ts +2 -2
- package/dist/trust-engine/ceiling-enforcement/index.js +2 -2
- package/dist/trust-engine/ceiling-enforcement/kernel.d.ts +12 -10
- package/dist/trust-engine/ceiling-enforcement/kernel.d.ts.map +1 -1
- package/dist/trust-engine/ceiling-enforcement/kernel.js +26 -20
- package/dist/trust-engine/ceiling-enforcement/kernel.js.map +1 -1
- package/dist/trust-engine/context-policy/enforcement.d.ts.map +1 -1
- package/dist/trust-engine/context-policy/factory.d.ts +1 -1
- package/dist/trust-engine/context-policy/factory.d.ts.map +1 -1
- package/dist/trust-engine/context-policy/factory.js +1 -1
- package/dist/trust-engine/context-policy/factory.js.map +1 -1
- package/dist/trust-engine/context-policy/index.d.ts +2 -2
- package/dist/trust-engine/context-policy/index.js +2 -2
- package/dist/trust-engine/creation-modifiers/index.d.ts +1 -1
- package/dist/trust-engine/creation-modifiers/index.js +1 -1
- package/dist/trust-engine/creation-modifiers/types.d.ts.map +1 -1
- package/dist/trust-engine/creation-modifiers/types.js +3 -2
- package/dist/trust-engine/creation-modifiers/types.js.map +1 -1
- package/dist/trust-engine/decay-profiles.d.ts +37 -136
- package/dist/trust-engine/decay-profiles.d.ts.map +1 -1
- package/dist/trust-engine/decay-profiles.js +68 -178
- package/dist/trust-engine/decay-profiles.js.map +1 -1
- package/dist/trust-engine/index.d.ts +135 -168
- package/dist/trust-engine/index.d.ts.map +1 -1
- package/dist/trust-engine/index.js +239 -525
- package/dist/trust-engine/index.js.map +1 -1
- package/dist/trust-engine/phase6-types.d.ts +18 -11
- package/dist/trust-engine/phase6-types.d.ts.map +1 -1
- package/dist/trust-engine/phase6-types.js +33 -29
- package/dist/trust-engine/phase6-types.js.map +1 -1
- package/package.json +1 -1
- package/dist/enforce/types.d.ts +0 -234
- package/dist/enforce/types.d.ts.map +0 -1
- package/dist/enforce/types.js +0 -10
- package/dist/enforce/types.js.map +0 -1
- package/dist/intent/types.d.ts +0 -69
- package/dist/intent/types.d.ts.map +0 -1
- package/dist/intent/types.js +0 -10
- package/dist/intent/types.js.map +0 -1
- package/dist/intent-gateway/index.d.ts +0 -522
- package/dist/intent-gateway/index.d.ts.map +0 -1
- package/dist/intent-gateway/index.js +0 -1499
- package/dist/intent-gateway/index.js.map +0 -1
- package/dist/trust-engine/types.d.ts +0 -77
- package/dist/trust-engine/types.d.ts.map +0 -1
- package/dist/trust-engine/types.js +0 -20
- package/dist/trust-engine/types.js.map +0 -1
|
@@ -10,88 +10,87 @@
|
|
|
10
10
|
*
|
|
11
11
|
* @packageDocumentation
|
|
12
12
|
*/
|
|
13
|
-
import { BaseSecurityLayer, createLayerConfig } from
|
|
13
|
+
import { BaseSecurityLayer, createLayerConfig } from '../index.js';
|
|
14
14
|
/**
|
|
15
15
|
* Unicode categories of dangerous characters
|
|
16
16
|
*/
|
|
17
17
|
const DANGEROUS_PATTERNS = [
|
|
18
18
|
{
|
|
19
|
-
name:
|
|
19
|
+
name: 'bidi_override',
|
|
20
20
|
// Bi-directional override characters (used in trojan source attacks)
|
|
21
|
-
pattern: /
|
|
22
|
-
severity:
|
|
23
|
-
description:
|
|
21
|
+
pattern: /[\u200E\u200F\u202A-\u202E\u2066-\u2069]/g,
|
|
22
|
+
severity: 'critical',
|
|
23
|
+
description: 'Bi-directional text override characters can disguise malicious content',
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
|
-
name:
|
|
26
|
+
name: 'zero_width',
|
|
27
27
|
// Zero-width characters (invisible text injection)
|
|
28
|
-
pattern: /
|
|
29
|
-
severity:
|
|
30
|
-
description:
|
|
28
|
+
pattern: /[\u200B\u200C\u200D\uFEFF]/g,
|
|
29
|
+
severity: 'high',
|
|
30
|
+
description: 'Zero-width characters can hide content from human reviewers',
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
|
-
name:
|
|
33
|
+
name: 'control_chars',
|
|
34
34
|
// C0/C1 control characters except common whitespace (tab, newline, carriage return)
|
|
35
|
-
// eslint-disable-next-line no-control-regex
|
|
36
35
|
pattern: /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x80-\x9F]/g,
|
|
37
|
-
severity:
|
|
38
|
-
description:
|
|
36
|
+
severity: 'high',
|
|
37
|
+
description: 'Control characters can corrupt parsing or inject escape sequences',
|
|
39
38
|
},
|
|
40
39
|
{
|
|
41
|
-
name:
|
|
40
|
+
name: 'tag_chars',
|
|
42
41
|
// Unicode tag characters (U+E0001-U+E007F) — used to hide instructions
|
|
43
|
-
pattern:
|
|
44
|
-
severity:
|
|
45
|
-
description:
|
|
42
|
+
pattern: /[\uDB40][\uDC01-\uDC7F]/g,
|
|
43
|
+
severity: 'high',
|
|
44
|
+
description: 'Unicode tag characters can embed hidden instructions',
|
|
46
45
|
},
|
|
47
46
|
{
|
|
48
|
-
name:
|
|
47
|
+
name: 'interlinear_annotation',
|
|
49
48
|
// Interlinear annotation characters
|
|
50
49
|
pattern: /[\uFFF9\uFFFA\uFFFB]/g,
|
|
51
|
-
severity:
|
|
52
|
-
description:
|
|
50
|
+
severity: 'medium',
|
|
51
|
+
description: 'Annotation characters can inject hidden metadata',
|
|
53
52
|
},
|
|
54
53
|
{
|
|
55
|
-
name:
|
|
54
|
+
name: 'replacement_char',
|
|
56
55
|
// Object replacement character (can mask embedded objects)
|
|
57
56
|
pattern: /\uFFFC/g,
|
|
58
|
-
severity:
|
|
59
|
-
description:
|
|
57
|
+
severity: 'medium',
|
|
58
|
+
description: 'Object replacement character may mask embedded content',
|
|
60
59
|
},
|
|
61
60
|
{
|
|
62
|
-
name:
|
|
61
|
+
name: 'variation_selector_abuse',
|
|
63
62
|
// Excessive variation selectors (emoji/glyph variant abuse)
|
|
64
63
|
pattern: /[\uFE00-\uFE0F]{3,}/g,
|
|
65
|
-
severity:
|
|
66
|
-
description:
|
|
64
|
+
severity: 'low',
|
|
65
|
+
description: 'Excessive variation selectors suggest encoding manipulation',
|
|
67
66
|
},
|
|
68
67
|
];
|
|
69
68
|
/**
|
|
70
69
|
* Common homoglyph mappings (confusable characters → ASCII equivalent)
|
|
71
70
|
*/
|
|
72
71
|
const HOMOGLYPH_MAP = {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
72
|
+
'\u0410': 'A', // Cyrillic А → Latin A
|
|
73
|
+
'\u0412': 'B', // Cyrillic В → Latin B
|
|
74
|
+
'\u0421': 'C', // Cyrillic С → Latin C
|
|
75
|
+
'\u0415': 'E', // Cyrillic Е → Latin E
|
|
76
|
+
'\u041D': 'H', // Cyrillic Н → Latin H
|
|
77
|
+
'\u041A': 'K', // Cyrillic К → Latin K
|
|
78
|
+
'\u041C': 'M', // Cyrillic М → Latin M
|
|
79
|
+
'\u041E': 'O', // Cyrillic О → Latin O
|
|
80
|
+
'\u0420': 'P', // Cyrillic Р → Latin P
|
|
81
|
+
'\u0422': 'T', // Cyrillic Т → Latin T
|
|
82
|
+
'\u0425': 'X', // Cyrillic Х → Latin X
|
|
83
|
+
'\u0430': 'a', // Cyrillic а → Latin a
|
|
84
|
+
'\u0435': 'e', // Cyrillic е → Latin e
|
|
85
|
+
'\u043E': 'o', // Cyrillic о → Latin o
|
|
86
|
+
'\u0440': 'p', // Cyrillic р → Latin p
|
|
87
|
+
'\u0441': 'c', // Cyrillic с → Latin c
|
|
88
|
+
'\u0443': 'y', // Cyrillic у → Latin y
|
|
89
|
+
'\u0445': 'x', // Cyrillic х → Latin x
|
|
90
|
+
'\u0456': 'i', // Cyrillic і → Latin i
|
|
91
|
+
'\u0458': 'j', // Cyrillic ј → Latin j
|
|
92
|
+
'\u0455': 's', // Cyrillic ѕ → Latin s
|
|
93
|
+
'\u0501': 'd', // Cyrillic ԁ → Latin d
|
|
95
94
|
};
|
|
96
95
|
/**
|
|
97
96
|
* L2 Character Set Sanitizer
|
|
@@ -100,12 +99,12 @@ const HOMOGLYPH_MAP = {
|
|
|
100
99
|
*/
|
|
101
100
|
export class L2CharsetSanitizer extends BaseSecurityLayer {
|
|
102
101
|
constructor() {
|
|
103
|
-
super(createLayerConfig(2,
|
|
104
|
-
description:
|
|
105
|
-
tier:
|
|
106
|
-
primaryThreat:
|
|
107
|
-
secondaryThreats: [
|
|
108
|
-
failMode:
|
|
102
|
+
super(createLayerConfig(2, 'Character Set Sanitizer', {
|
|
103
|
+
description: 'Detects and sanitizes dangerous Unicode sequences, invisible characters, and homoglyph attacks',
|
|
104
|
+
tier: 'input_validation',
|
|
105
|
+
primaryThreat: 'prompt_injection',
|
|
106
|
+
secondaryThreats: ['deceptive_output', 'audit_evasion'],
|
|
107
|
+
failMode: 'block',
|
|
109
108
|
required: true,
|
|
110
109
|
timeoutMs: 300,
|
|
111
110
|
parallelizable: true,
|
|
@@ -118,20 +117,20 @@ export class L2CharsetSanitizer extends BaseSecurityLayer {
|
|
|
118
117
|
const findings = [];
|
|
119
118
|
const modifications = [];
|
|
120
119
|
// Walk all string values in the payload
|
|
121
|
-
this.scanObject(input.payload,
|
|
120
|
+
this.scanObject(input.payload, '', findings, modifications);
|
|
122
121
|
const timing = this.buildTiming(startedAt, t0);
|
|
123
|
-
const hasCritical = findings.some((f) => f.severity ===
|
|
124
|
-
const hasHigh = findings.some((f) => f.severity ===
|
|
122
|
+
const hasCritical = findings.some((f) => f.severity === 'critical');
|
|
123
|
+
const hasHigh = findings.some((f) => f.severity === 'high');
|
|
125
124
|
const passed = !hasCritical && !hasHigh;
|
|
126
125
|
if (passed) {
|
|
127
|
-
return this.createSuccessResult(
|
|
126
|
+
return this.createSuccessResult('allow', 0.9, findings, modifications, timing);
|
|
128
127
|
}
|
|
129
|
-
return this.createFailureResult(hasCritical ?
|
|
128
|
+
return this.createFailureResult(hasCritical ? 'deny' : 'escalate', 0.85, findings, timing);
|
|
130
129
|
}
|
|
131
130
|
scanObject(obj, path, findings, modifications) {
|
|
132
131
|
if (obj === null || obj === undefined)
|
|
133
132
|
return;
|
|
134
|
-
if (typeof obj ===
|
|
133
|
+
if (typeof obj === 'string') {
|
|
135
134
|
this.scanString(obj, path, findings, modifications);
|
|
136
135
|
return;
|
|
137
136
|
}
|
|
@@ -141,10 +140,10 @@ export class L2CharsetSanitizer extends BaseSecurityLayer {
|
|
|
141
140
|
}
|
|
142
141
|
return;
|
|
143
142
|
}
|
|
144
|
-
if (typeof obj ===
|
|
143
|
+
if (typeof obj === 'object') {
|
|
145
144
|
for (const [key, val] of Object.entries(obj)) {
|
|
146
145
|
// Also scan keys for homoglyphs
|
|
147
|
-
this.scanString(key, `${path ? path +
|
|
146
|
+
this.scanString(key, `${path ? path + '.' : ''}(key:${key})`, findings, modifications);
|
|
148
147
|
this.scanObject(val, path ? `${path}.${key}` : key, findings, modifications);
|
|
149
148
|
}
|
|
150
149
|
}
|
|
@@ -157,24 +156,21 @@ export class L2CharsetSanitizer extends BaseSecurityLayer {
|
|
|
157
156
|
const matches = value.match(pattern);
|
|
158
157
|
if (matches && matches.length > 0) {
|
|
159
158
|
findings.push({
|
|
160
|
-
type:
|
|
159
|
+
type: 'threat_detected',
|
|
161
160
|
severity,
|
|
162
161
|
code: `L2_${name.toUpperCase()}`,
|
|
163
162
|
description: `${description} at '${path}'`,
|
|
164
163
|
evidence: [
|
|
165
164
|
`Found ${matches.length} instance(s)`,
|
|
166
|
-
`Code points: ${matches
|
|
167
|
-
.slice(0, 5)
|
|
168
|
-
.map((c) => `U+${c.charCodeAt(0).toString(16).toUpperCase().padStart(4, "0")}`)
|
|
169
|
-
.join(", ")}`,
|
|
165
|
+
`Code points: ${matches.slice(0, 5).map((c) => `U+${c.charCodeAt(0).toString(16).toUpperCase().padStart(4, '0')}`).join(', ')}`,
|
|
170
166
|
],
|
|
171
167
|
remediation: `Remove ${name} characters from the input`,
|
|
172
168
|
});
|
|
173
169
|
modifications.push({
|
|
174
170
|
target: path,
|
|
175
|
-
type:
|
|
171
|
+
type: 'sanitize',
|
|
176
172
|
originalValue: `[${matches.length} ${name} chars]`,
|
|
177
|
-
newValue:
|
|
173
|
+
newValue: '[stripped]',
|
|
178
174
|
reason: description,
|
|
179
175
|
});
|
|
180
176
|
}
|
|
@@ -183,14 +179,12 @@ export class L2CharsetSanitizer extends BaseSecurityLayer {
|
|
|
183
179
|
const homoglyphs = this.detectHomoglyphs(value);
|
|
184
180
|
if (homoglyphs.length > 0) {
|
|
185
181
|
findings.push({
|
|
186
|
-
type:
|
|
187
|
-
severity:
|
|
188
|
-
code:
|
|
182
|
+
type: 'threat_detected',
|
|
183
|
+
severity: 'high',
|
|
184
|
+
code: 'L2_HOMOGLYPH_ATTACK',
|
|
189
185
|
description: `Mixed-script homoglyph characters detected at '${path}'`,
|
|
190
|
-
evidence: homoglyphs
|
|
191
|
-
|
|
192
|
-
.map((h) => `'${h.char}' (U+${h.codePoint}) looks like '${h.looksLike}'`),
|
|
193
|
-
remediation: "Use consistent character scripts (do not mix Cyrillic with Latin)",
|
|
186
|
+
evidence: homoglyphs.slice(0, 10).map((h) => `'${h.char}' (U+${h.codePoint}) looks like '${h.looksLike}'`),
|
|
187
|
+
remediation: 'Use consistent character scripts (do not mix Cyrillic with Latin)',
|
|
194
188
|
});
|
|
195
189
|
}
|
|
196
190
|
}
|
|
@@ -205,11 +199,7 @@ export class L2CharsetSanitizer extends BaseSecurityLayer {
|
|
|
205
199
|
if (mapped) {
|
|
206
200
|
results.push({
|
|
207
201
|
char,
|
|
208
|
-
codePoint: char
|
|
209
|
-
.charCodeAt(0)
|
|
210
|
-
.toString(16)
|
|
211
|
-
.toUpperCase()
|
|
212
|
-
.padStart(4, "0"),
|
|
202
|
+
codePoint: char.charCodeAt(0).toString(16).toUpperCase().padStart(4, '0'),
|
|
213
203
|
looksLike: mapped,
|
|
214
204
|
});
|
|
215
205
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"L2-charset-sanitizer.js","sourceRoot":"","sources":["../../../src/layers/implementations/L2-charset-sanitizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AASnE;;GAEG;AACH,MAAM,kBAAkB,GAKnB;IACH;QACE,IAAI,EAAE,eAAe;QACrB,qEAAqE;QACrE,OAAO,
|
|
1
|
+
{"version":3,"file":"L2-charset-sanitizer.js","sourceRoot":"","sources":["../../../src/layers/implementations/L2-charset-sanitizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
*
|
|
11
11
|
* @packageDocumentation
|
|
12
12
|
*/
|
|
13
|
-
import { BaseSecurityLayer } from
|
|
14
|
-
import type { LayerInput, LayerExecutionResult } from
|
|
13
|
+
import { BaseSecurityLayer } from '../index.js';
|
|
14
|
+
import type { LayerInput, LayerExecutionResult } from '../types.js';
|
|
15
15
|
/**
|
|
16
16
|
* Schema definition for a known action
|
|
17
17
|
*/
|
|
@@ -25,7 +25,7 @@ export interface ActionSchema {
|
|
|
25
25
|
/** Maximum number of extra fields allowed beyond defined ones */
|
|
26
26
|
maxExtraFields?: number;
|
|
27
27
|
}
|
|
28
|
-
type FieldType =
|
|
28
|
+
type FieldType = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'string[]' | 'number[]';
|
|
29
29
|
/**
|
|
30
30
|
* L3 Schema Conformance Validator
|
|
31
31
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"L3-schema-conformance.d.ts","sourceRoot":"","sources":["../../../src/layers/implementations/L3-schema-conformance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,iBAAiB,EAAqB,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"L3-schema-conformance.d.ts","sourceRoot":"","sources":["../../../src/layers/implementations/L3-schema-conformance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,iBAAiB,EAAqB,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAA6B,MAAM,aAAa,CAAC;AAE/F;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACpC,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACrC,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,KAAK,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;AA4ChG;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,iBAAiB;IACxD,OAAO,CAAC,OAAO,CAA4B;gBAE/B,iBAAiB,CAAC,EAAE,YAAY,EAAE;IA0B9C;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAIpC,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA2H/D,OAAO,CAAC,SAAS;IAyCjB,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,WAAW;CAUpB"}
|
|
@@ -10,50 +10,45 @@
|
|
|
10
10
|
*
|
|
11
11
|
* @packageDocumentation
|
|
12
12
|
*/
|
|
13
|
-
import { BaseSecurityLayer, createLayerConfig } from
|
|
13
|
+
import { BaseSecurityLayer, createLayerConfig } from '../index.js';
|
|
14
14
|
/**
|
|
15
15
|
* Built-in action schemas for the ATSF governance pipeline
|
|
16
16
|
*/
|
|
17
17
|
const KNOWN_ACTION_SCHEMAS = [
|
|
18
18
|
{
|
|
19
|
-
action:
|
|
20
|
-
required: { content:
|
|
21
|
-
optional: {
|
|
22
|
-
context: "object",
|
|
23
|
-
model: "string",
|
|
24
|
-
temperature: "number",
|
|
25
|
-
maxTokens: "number",
|
|
26
|
-
},
|
|
19
|
+
action: 'query',
|
|
20
|
+
required: { content: 'string' },
|
|
21
|
+
optional: { context: 'object', model: 'string', temperature: 'number', maxTokens: 'number' },
|
|
27
22
|
maxExtraFields: 10,
|
|
28
23
|
},
|
|
29
24
|
{
|
|
30
|
-
action:
|
|
31
|
-
required: { content:
|
|
32
|
-
optional: { args:
|
|
25
|
+
action: 'execute',
|
|
26
|
+
required: { content: 'string', target: 'string' },
|
|
27
|
+
optional: { args: 'object', timeout: 'number', dryRun: 'boolean' },
|
|
33
28
|
maxExtraFields: 5,
|
|
34
29
|
},
|
|
35
30
|
{
|
|
36
|
-
action:
|
|
37
|
-
required: { content:
|
|
38
|
-
optional: { format:
|
|
31
|
+
action: 'read',
|
|
32
|
+
required: { content: 'string', resource: 'string' },
|
|
33
|
+
optional: { format: 'string', limit: 'number', offset: 'number' },
|
|
39
34
|
maxExtraFields: 5,
|
|
40
35
|
},
|
|
41
36
|
{
|
|
42
|
-
action:
|
|
43
|
-
required: { content:
|
|
44
|
-
optional: { overwrite:
|
|
37
|
+
action: 'write',
|
|
38
|
+
required: { content: 'string', resource: 'string', data: 'object' },
|
|
39
|
+
optional: { overwrite: 'boolean', format: 'string' },
|
|
45
40
|
maxExtraFields: 5,
|
|
46
41
|
},
|
|
47
42
|
{
|
|
48
|
-
action:
|
|
49
|
-
required: { content:
|
|
50
|
-
optional: { recursive:
|
|
43
|
+
action: 'delete',
|
|
44
|
+
required: { content: 'string', resource: 'string' },
|
|
45
|
+
optional: { recursive: 'boolean', force: 'boolean' },
|
|
51
46
|
maxExtraFields: 3,
|
|
52
47
|
},
|
|
53
48
|
{
|
|
54
|
-
action:
|
|
55
|
-
required: { content:
|
|
56
|
-
optional: { channel:
|
|
49
|
+
action: 'communicate',
|
|
50
|
+
required: { content: 'string', recipient: 'string' },
|
|
51
|
+
optional: { channel: 'string', priority: 'string', metadata: 'object' },
|
|
57
52
|
maxExtraFields: 5,
|
|
58
53
|
},
|
|
59
54
|
];
|
|
@@ -65,12 +60,12 @@ const KNOWN_ACTION_SCHEMAS = [
|
|
|
65
60
|
export class L3SchemaConformance extends BaseSecurityLayer {
|
|
66
61
|
schemas;
|
|
67
62
|
constructor(additionalSchemas) {
|
|
68
|
-
super(createLayerConfig(3,
|
|
69
|
-
description:
|
|
70
|
-
tier:
|
|
71
|
-
primaryThreat:
|
|
72
|
-
secondaryThreats: [
|
|
73
|
-
failMode:
|
|
63
|
+
super(createLayerConfig(3, 'Schema Conformance', {
|
|
64
|
+
description: 'Validates payload action and fields against known schemas',
|
|
65
|
+
tier: 'input_validation',
|
|
66
|
+
primaryThreat: 'unauthorized_action',
|
|
67
|
+
secondaryThreats: ['capability_abuse', 'prompt_injection'],
|
|
68
|
+
failMode: 'block',
|
|
74
69
|
required: true,
|
|
75
70
|
timeoutMs: 200,
|
|
76
71
|
parallelizable: true,
|
|
@@ -98,57 +93,57 @@ export class L3SchemaConformance extends BaseSecurityLayer {
|
|
|
98
93
|
const findings = [];
|
|
99
94
|
const payload = input.payload;
|
|
100
95
|
// 1. Check that action field exists
|
|
101
|
-
const action = payload[
|
|
96
|
+
const action = payload['action'];
|
|
102
97
|
if (action === undefined || action === null) {
|
|
103
98
|
findings.push({
|
|
104
|
-
type:
|
|
105
|
-
severity:
|
|
106
|
-
code:
|
|
99
|
+
type: 'threat_detected',
|
|
100
|
+
severity: 'high',
|
|
101
|
+
code: 'L3_MISSING_ACTION',
|
|
107
102
|
description: 'Payload has no "action" field — cannot determine request type',
|
|
108
|
-
evidence: [
|
|
103
|
+
evidence: ['payload.action is undefined'],
|
|
109
104
|
remediation: 'Include an "action" field in the payload (e.g., "query", "execute", "read")',
|
|
110
105
|
});
|
|
111
106
|
const timing = this.buildTiming(startedAt, t0);
|
|
112
|
-
return this.createFailureResult(
|
|
107
|
+
return this.createFailureResult('deny', 0.9, findings, timing);
|
|
113
108
|
}
|
|
114
|
-
if (typeof action !==
|
|
109
|
+
if (typeof action !== 'string') {
|
|
115
110
|
findings.push({
|
|
116
|
-
type:
|
|
117
|
-
severity:
|
|
118
|
-
code:
|
|
111
|
+
type: 'threat_detected',
|
|
112
|
+
severity: 'high',
|
|
113
|
+
code: 'L3_INVALID_ACTION_TYPE',
|
|
119
114
|
description: `Action field must be a string, got ${typeof action}`,
|
|
120
115
|
evidence: [`typeof action = ${typeof action}`],
|
|
121
|
-
remediation:
|
|
116
|
+
remediation: 'Provide action as a string value',
|
|
122
117
|
});
|
|
123
118
|
const timing = this.buildTiming(startedAt, t0);
|
|
124
|
-
return this.createFailureResult(
|
|
119
|
+
return this.createFailureResult('deny', 0.9, findings, timing);
|
|
125
120
|
}
|
|
126
121
|
// 2. Look up schema for this action
|
|
127
122
|
const schema = this.schemas.get(action);
|
|
128
123
|
if (!schema) {
|
|
129
124
|
findings.push({
|
|
130
|
-
type:
|
|
131
|
-
severity:
|
|
132
|
-
code:
|
|
125
|
+
type: 'threat_detected',
|
|
126
|
+
severity: 'medium',
|
|
127
|
+
code: 'L3_UNKNOWN_ACTION',
|
|
133
128
|
description: `Unknown action '${action}' — not in registered schemas`,
|
|
134
129
|
evidence: [
|
|
135
130
|
`action=${action}`,
|
|
136
|
-
`known actions: ${Array.from(this.schemas.keys()).join(
|
|
131
|
+
`known actions: ${Array.from(this.schemas.keys()).join(', ')}`,
|
|
137
132
|
],
|
|
138
|
-
remediation: `Use a known action: ${Array.from(this.schemas.keys()).join(
|
|
133
|
+
remediation: `Use a known action: ${Array.from(this.schemas.keys()).join(', ')}`,
|
|
139
134
|
});
|
|
140
135
|
const timing = this.buildTiming(startedAt, t0);
|
|
141
136
|
// Unknown actions are escalated, not denied — allows extension
|
|
142
|
-
return this.createFailureResult(
|
|
137
|
+
return this.createFailureResult('escalate', 0.7, findings, timing);
|
|
143
138
|
}
|
|
144
139
|
// 3. Check required fields
|
|
145
140
|
for (const [field, expectedType] of Object.entries(schema.required)) {
|
|
146
141
|
const value = payload[field];
|
|
147
142
|
if (value === undefined || value === null) {
|
|
148
143
|
findings.push({
|
|
149
|
-
type:
|
|
150
|
-
severity:
|
|
151
|
-
code:
|
|
144
|
+
type: 'threat_detected',
|
|
145
|
+
severity: 'high',
|
|
146
|
+
code: 'L3_MISSING_REQUIRED_FIELD',
|
|
152
147
|
description: `Required field '${field}' missing for action '${action}'`,
|
|
153
148
|
evidence: [`field=${field}, action=${action}`],
|
|
154
149
|
remediation: `Include required field '${field}' (type: ${expectedType})`,
|
|
@@ -175,7 +170,7 @@ export class L3SchemaConformance extends BaseSecurityLayer {
|
|
|
175
170
|
}
|
|
176
171
|
// 5. Check for unexpected extra fields
|
|
177
172
|
const allKnownFields = new Set([
|
|
178
|
-
|
|
173
|
+
'action',
|
|
179
174
|
...Object.keys(schema.required),
|
|
180
175
|
...Object.keys(schema.optional ?? {}),
|
|
181
176
|
]);
|
|
@@ -183,61 +178,57 @@ export class L3SchemaConformance extends BaseSecurityLayer {
|
|
|
183
178
|
const maxExtra = schema.maxExtraFields ?? 10;
|
|
184
179
|
if (extraFields.length > maxExtra) {
|
|
185
180
|
findings.push({
|
|
186
|
-
type:
|
|
187
|
-
severity:
|
|
188
|
-
code:
|
|
181
|
+
type: 'warning',
|
|
182
|
+
severity: 'medium',
|
|
183
|
+
code: 'L3_EXCESS_EXTRA_FIELDS',
|
|
189
184
|
description: `${extraFields.length} extra fields exceed maximum ${maxExtra} for action '${action}'`,
|
|
190
|
-
evidence: [
|
|
191
|
-
`extra fields: ${extraFields.slice(0, 10).join(", ")}${extraFields.length > 10 ? "..." : ""}`,
|
|
192
|
-
],
|
|
185
|
+
evidence: [`extra fields: ${extraFields.slice(0, 10).join(', ')}${extraFields.length > 10 ? '...' : ''}`],
|
|
193
186
|
remediation: `Reduce extra fields to at most ${maxExtra}`,
|
|
194
187
|
});
|
|
195
188
|
}
|
|
196
189
|
const timing = this.buildTiming(startedAt, t0);
|
|
197
|
-
const hasHigh = findings.some((f) => f.severity ===
|
|
190
|
+
const hasHigh = findings.some((f) => f.severity === 'high' || f.severity === 'critical');
|
|
198
191
|
const passed = !hasHigh;
|
|
199
192
|
if (passed) {
|
|
200
|
-
return this.createSuccessResult(
|
|
193
|
+
return this.createSuccessResult('allow', 0.9, findings, [], timing);
|
|
201
194
|
}
|
|
202
|
-
return this.createFailureResult(
|
|
195
|
+
return this.createFailureResult('deny', 0.85, findings, timing);
|
|
203
196
|
}
|
|
204
197
|
checkType(value, expectedType, field) {
|
|
205
198
|
switch (expectedType) {
|
|
206
|
-
case
|
|
207
|
-
if (typeof value !==
|
|
199
|
+
case 'string':
|
|
200
|
+
if (typeof value !== 'string') {
|
|
208
201
|
return this.typeError(field, expectedType, typeof value);
|
|
209
202
|
}
|
|
210
203
|
break;
|
|
211
|
-
case
|
|
212
|
-
if (typeof value !==
|
|
204
|
+
case 'number':
|
|
205
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
213
206
|
return this.typeError(field, expectedType, typeof value);
|
|
214
207
|
}
|
|
215
208
|
break;
|
|
216
|
-
case
|
|
217
|
-
if (typeof value !==
|
|
209
|
+
case 'boolean':
|
|
210
|
+
if (typeof value !== 'boolean') {
|
|
218
211
|
return this.typeError(field, expectedType, typeof value);
|
|
219
212
|
}
|
|
220
213
|
break;
|
|
221
|
-
case
|
|
222
|
-
if (typeof value !==
|
|
223
|
-
return this.typeError(field, expectedType, Array.isArray(value) ?
|
|
214
|
+
case 'object':
|
|
215
|
+
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
216
|
+
return this.typeError(field, expectedType, Array.isArray(value) ? 'array' : typeof value);
|
|
224
217
|
}
|
|
225
218
|
break;
|
|
226
|
-
case
|
|
219
|
+
case 'array':
|
|
227
220
|
if (!Array.isArray(value)) {
|
|
228
221
|
return this.typeError(field, expectedType, typeof value);
|
|
229
222
|
}
|
|
230
223
|
break;
|
|
231
|
-
case
|
|
232
|
-
if (!Array.isArray(value) ||
|
|
233
|
-
|
|
234
|
-
return this.typeError(field, expectedType, Array.isArray(value) ? "mixed array" : typeof value);
|
|
224
|
+
case 'string[]':
|
|
225
|
+
if (!Array.isArray(value) || !value.every((v) => typeof v === 'string')) {
|
|
226
|
+
return this.typeError(field, expectedType, Array.isArray(value) ? 'mixed array' : typeof value);
|
|
235
227
|
}
|
|
236
228
|
break;
|
|
237
|
-
case
|
|
238
|
-
if (!Array.isArray(value) ||
|
|
239
|
-
|
|
240
|
-
return this.typeError(field, expectedType, Array.isArray(value) ? "mixed array" : typeof value);
|
|
229
|
+
case 'number[]':
|
|
230
|
+
if (!Array.isArray(value) || !value.every((v) => typeof v === 'number')) {
|
|
231
|
+
return this.typeError(field, expectedType, Array.isArray(value) ? 'mixed array' : typeof value);
|
|
241
232
|
}
|
|
242
233
|
break;
|
|
243
234
|
}
|
|
@@ -245,9 +236,9 @@ export class L3SchemaConformance extends BaseSecurityLayer {
|
|
|
245
236
|
}
|
|
246
237
|
typeError(field, expected, actual) {
|
|
247
238
|
return {
|
|
248
|
-
type:
|
|
249
|
-
severity:
|
|
250
|
-
code:
|
|
239
|
+
type: 'threat_detected',
|
|
240
|
+
severity: 'high',
|
|
241
|
+
code: 'L3_TYPE_MISMATCH',
|
|
251
242
|
description: `Field '${field}' expected type '${expected}', got '${actual}'`,
|
|
252
243
|
evidence: [`field=${field}, expected=${expected}, actual=${actual}`],
|
|
253
244
|
remediation: `Provide '${field}' as type '${expected}'`,
|