From 46acfe1ea810b2c4677cba728d8395991273a5a7 Mon Sep 17 00:00:00 2001 From: tlee Date: Mon, 31 Jul 2023 14:29:11 -0400 Subject: [PATCH 1/3] Validation block for first group of OneOf --- .../src/assets/builder.config.validator.ts | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/attack_flow_builder/src/assets/builder.config.validator.ts b/src/attack_flow_builder/src/assets/builder.config.validator.ts index a521be21..79f23b29 100644 --- a/src/attack_flow_builder/src/assets/builder.config.validator.ts +++ b/src/attack_flow_builder/src/assets/builder.config.validator.ts @@ -151,6 +151,44 @@ class AttackFlowValidator extends DiagramValidator { } // Validate links switch(node.template.id) { + case "artifact": + const payloadBin = node.props.value.get("payload_bin"); + const url = node.props.value.get("url"); + const hashes = node.props.value.get("hashes"); + const mimeType = node.props.value.get("mime_type"); + + const payloadRegex = /^([a-z0-9+/]{4})*([a-z0-9+/]{4}|[a-z0-9+/]{3}=|[a-z0-9+/]{2}==)$/i; + const MIME_Regex = /^(application|audio|font|image|message|model|multipart|text|video)\/[a-zA-Z0-9.+_-]+/; + + // Check regex + if(payloadBin?.isDefined()) { + if(!payloadRegex.test(payloadBin.toString())) { + this.addError(id, "Invalid Payload Bin."); + } + } + if(mimeType?.isDefined()) { + if(!MIME_Regex.test(mimeType.toString())) { + this.addError(id, "Invalid MIME Type."); + } + } + + if(!payloadBin?.isDefined() && !url?.isDefined() && !hashes?.isDefined()) { // A blank object + this.addError(id, "Artifact only allows 2 combinations of fields: (Payload Bin with the Url field empty), or (URL+Hashes with the Payload Bin field empty)"); + } else { + // Only allowed combinations: [(Payload), (URL+Hashes-Payload)] + if(payloadBin?.isDefined()) { + if(url?.isDefined()) { + this.addError(id, "Artifact only allows 2 combinations of fields: (Payload) or (URL+Hashes-Payload)"); + } + } else { + if(url?.isDefined() && hashes?.isDefined()) { + // Valid + } else { + this.addError(id, "Artifact only allows 2 combinations of fields: (Payload) or (URL+Hashes-Payload)"); + } + } + } + break; case "email_address": // Additional validation for email addresses if (!AttackFlowValidator.Emailregex.test(String(node.props.value.get("value")))) { this.addError(id, "Invalid email address.") From b122637e5dce8627fd9f6d1534c6861988d1937e Mon Sep 17 00:00:00 2001 From: tlee Date: Tue, 1 Aug 2023 15:15:53 -0400 Subject: [PATCH 2/3] Added optional fields encryption algs and decryption key --- .../src/assets/builder.config.ts | 14 ++++++++++- .../src/assets/builder.config.validator.ts | 23 +++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/attack_flow_builder/src/assets/builder.config.ts b/src/attack_flow_builder/src/assets/builder.config.ts index d6360d29..b6d31040 100644 --- a/src/attack_flow_builder/src/assets/builder.config.ts +++ b/src/attack_flow_builder/src/assets/builder.config.ts @@ -556,7 +556,19 @@ const config: AppConfiguration = { payload_bin : { type: PropertyType.String }, url : { type: PropertyType.String }, hashes : { type: PropertyType.String }, - encryption_algorithm : { type: PropertyType.String }, + encryption_algorithm : { + type: PropertyType.Enum, + options: { + type: PropertyType.List, + form: { type: PropertyType.String }, + value: [ + ["AES-256-GCM", "AES-256-GCM"], + ["ChaCha20-Poly1305", "ChaCha20-Poly1305"], + ["mime-type-indicated", "Mime Type Indicated"], + ] + }, + value: null + }, decryption_key : { type: PropertyType.String }, }, anchor_template: "@__builtin__anchor", diff --git a/src/attack_flow_builder/src/assets/builder.config.validator.ts b/src/attack_flow_builder/src/assets/builder.config.validator.ts index 79f23b29..4e723b77 100644 --- a/src/attack_flow_builder/src/assets/builder.config.validator.ts +++ b/src/attack_flow_builder/src/assets/builder.config.validator.ts @@ -156,6 +156,8 @@ class AttackFlowValidator extends DiagramValidator { const url = node.props.value.get("url"); const hashes = node.props.value.get("hashes"); const mimeType = node.props.value.get("mime_type"); + const decryptionKey = node.props.value.get("decryption_key"); + const encryptionAlg = node.props.value.get("encryption_algorithm") const payloadRegex = /^([a-z0-9+/]{4})*([a-z0-9+/]{4}|[a-z0-9+/]{3}=|[a-z0-9+/]{2}==)$/i; const MIME_Regex = /^(application|audio|font|image|message|model|multipart|text|video)\/[a-zA-Z0-9.+_-]+/; @@ -172,19 +174,30 @@ class AttackFlowValidator extends DiagramValidator { } } - if(!payloadBin?.isDefined() && !url?.isDefined() && !hashes?.isDefined()) { // A blank object - this.addError(id, "Artifact only allows 2 combinations of fields: (Payload Bin with the Url field empty), or (URL+Hashes with the Payload Bin field empty)"); + if(!payloadBin?.isDefined() && !url?.isDefined() && !hashes?.isDefined() && !encryptionAlg?.isDefined() && !decryptionKey?.isDefined()) { // A blank object + this.addError(id, "Artifact must have one of following combinations of fields filled out: (Payload Bin), or (URL + Hashes - Payload Bin)"); } else { - // Only allowed combinations: [(Payload), (URL+Hashes-Payload)] if(payloadBin?.isDefined()) { if(url?.isDefined()) { - this.addError(id, "Artifact only allows 2 combinations of fields: (Payload) or (URL+Hashes-Payload)"); + // Invalid combination + this.addError(id, "Artifact must have one of following combinations of fields filled out: (Payload Bin), or (URL + Hashes - Payload Bin)"); } } else { + if(encryptionAlg?.isDefined()) { + // Valid + if(encryptionAlg.toRawValue()?.toString() == "mime-type-indicated" && !mimeType?.isDefined()) { + this.addError(id, "For Encryption Algorithm to be 'Mime Type Indicated', the field 'Mime Type' cannot be empty."); + } + } else { + if(decryptionKey?.isDefined()) { + this.addError(id, "An Artifact with a Decryption Key must also have an Encryption Algorithm."); + } + } + if(url?.isDefined() && hashes?.isDefined()) { // Valid } else { - this.addError(id, "Artifact only allows 2 combinations of fields: (Payload) or (URL+Hashes-Payload)"); + this.addError(id, "Artifact must have one of following combinations of fields filled out: (Payload Bin), or (URL + Hashes - Payload Bin)"); } } } From 5ee57ec94da1110cbfd4b473eed8d67d770386a8 Mon Sep 17 00:00:00 2001 From: Michael Carenzo <79934822+mikecarenzo@users.noreply.github.com> Date: Tue, 29 Aug 2023 12:03:48 -0400 Subject: [PATCH 3/3] align artifact checks with STIX documentation --- .../src/assets/builder.config.validator.ts | 39 +++++++------------ 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/src/attack_flow_builder/src/assets/builder.config.validator.ts b/src/attack_flow_builder/src/assets/builder.config.validator.ts index 43950fc6..5560a879 100644 --- a/src/attack_flow_builder/src/assets/builder.config.validator.ts +++ b/src/attack_flow_builder/src/assets/builder.config.validator.ts @@ -176,32 +176,21 @@ class AttackFlowValidator extends DiagramValidator { } } - if(!payloadBin?.isDefined() && !url?.isDefined() && !hashes?.isDefined() && !encryptionAlg?.isDefined() && !decryptionKey?.isDefined()) { // A blank object - this.addError(id, "Artifact must have one of following combinations of fields filled out: (Payload Bin), or (URL + Hashes - Payload Bin)"); - } else { - if(payloadBin?.isDefined()) { - if(url?.isDefined()) { - // Invalid combination - this.addError(id, "Artifact must have one of following combinations of fields filled out: (Payload Bin), or (URL + Hashes - Payload Bin)"); - } - } else { - if(encryptionAlg?.isDefined()) { - // Valid - if(encryptionAlg.toRawValue()?.toString() == "mime-type-indicated" && !mimeType?.isDefined()) { - this.addError(id, "For Encryption Algorithm to be 'Mime Type Indicated', the field 'Mime Type' cannot be empty."); - } - } else { - if(decryptionKey?.isDefined()) { - this.addError(id, "An Artifact with a Decryption Key must also have an Encryption Algorithm."); - } - } - - if(url?.isDefined() && hashes?.isDefined()) { - // Valid - } else { - this.addError(id, "Artifact must have one of following combinations of fields filled out: (Payload Bin), or (URL + Hashes - Payload Bin)"); - } + // Validate Payload Bin, URL, and Hashes + if(payloadBin?.isDefined() && url?.isDefined()) { + this.addError(id, "Artifact must have either have a Payload Bin or URL, not both."); + } + if(url?.isDefined() && !hashes?.isDefined()) { + this.addError(id, "Artifact URL must also have a Hash."); + } + + // Validate encryption and decryption algorithms + if(encryptionAlg?.isDefined()) { + if(encryptionAlg.toRawValue()?.toString() == "mime-type-indicated" && !mimeType?.isDefined()) { + this.addError(id, "For Encryption Algorithm to be 'Mime Type Indicated', the field 'Mime Type' cannot be empty."); } + } else if(decryptionKey?.isDefined()) { + this.addError(id, "An Artifact with a Decryption Key must also have an Encryption Algorithm."); } break; case "email_address": // Additional validation for email addresses