diff --git a/cornucopia.owasp.org/src/domain/mapping/mappingController.ts b/cornucopia.owasp.org/src/domain/mapping/mappingController.ts index 008fe71e7..0083cb8ea 100644 --- a/cornucopia.owasp.org/src/domain/mapping/mappingController.ts +++ b/cornucopia.owasp.org/src/domain/mapping/mappingController.ts @@ -53,6 +53,10 @@ export class MappingController { public getCardMappings(card : string, addition : number = 0) : Mapping { + if (!this.mapping || !this.mapping.suits) { + return {} as Mapping; + } + for(let i = 0 ; i < this.mapping.suits.length ; i++) { for(let j = 0 ; j < this.mapping.suits[i].cards.length ; j++) diff --git a/cornucopia.owasp.org/src/lib/components/cardFound.svelte b/cornucopia.owasp.org/src/lib/components/cardFound.svelte index 51f401cd0..e77615a54 100644 --- a/cornucopia.owasp.org/src/lib/components/cardFound.svelte +++ b/cornucopia.owasp.org/src/lib/components/cardFound.svelte @@ -56,10 +56,10 @@ {$t('cards.cardFound.a')} - {#if card.edition == 'webapp' && card.value != 'A' && card.value != 'B'} + {#if card.edition == 'webapp'} {/if} - {#if card.edition == 'mobileapp' && card.value != 'A' && card.value != 'B'} + {#if card.edition == 'mobileapp'} {/if} {#key card} diff --git a/cornucopia.owasp.org/src/lib/components/cardPreview.svelte b/cornucopia.owasp.org/src/lib/components/cardPreview.svelte index 63c347cb5..2641cc08c 100644 --- a/cornucopia.owasp.org/src/lib/components/cardPreview.svelte +++ b/cornucopia.owasp.org/src/lib/components/cardPreview.svelte @@ -53,10 +53,10 @@ {#if mapping} {card?.card ?? card?.value}

{card?.desc}

- {#if card?.edition == 'webapp' && card?.value != 'A' && card?.value != 'B'} + {#if card?.edition == 'webapp'} {/if} - {#if card?.edition == 'mobileapp' && card?.value != 'A' && card?.value != 'B'} + {#if card?.edition == 'mobileapp'} {/if} {:else if card?.suitName == 'WILD CARD'} diff --git a/cornucopia.owasp.org/src/lib/components/mobileAppCardTaxonomy.svelte b/cornucopia.owasp.org/src/lib/components/mobileAppCardTaxonomy.svelte index 735958ccc..114f4050c 100644 --- a/cornucopia.owasp.org/src/lib/components/mobileAppCardTaxonomy.svelte +++ b/cornucopia.owasp.org/src/lib/components/mobileAppCardTaxonomy.svelte @@ -57,33 +57,37 @@ - {#if card.value != 'A' && card.value != 'B'} + {#if mappings }

{$t('cards.mobileAppCardTaxonomy.h1.1')}

+ {#if mappings.owasp_masvs} + {/if} + {#if mappings.owasp_mastg} + {/if} + {#if mappings.capec} - {/if} - - {#if card.value != 'A' && card.value != 'B'} - + {#if mappings.safecode} + {/if}

{$t('cards.mobileAppCardTaxonomy.h1.2')}

- {#if card.value != 'A' && card.value != 'B'} + {#if attacks } {/if} + {/if} diff --git a/cornucopia.owasp.org/src/lib/components/webAppCardTaxonomy.svelte b/cornucopia.owasp.org/src/lib/components/webAppCardTaxonomy.svelte index 2cd31998f..70270902b 100644 --- a/cornucopia.owasp.org/src/lib/components/webAppCardTaxonomy.svelte +++ b/cornucopia.owasp.org/src/lib/components/webAppCardTaxonomy.svelte @@ -61,6 +61,8 @@ } let mappings: WebAppMapping = $state(controller.getWebAppCardMappings(card.id)); let attacks: Attack[] = $state(GetCardAttacks(card.id)); + + let hasMappings = $derived(mappings && Object.keys(mappings).length > 1); run(() => { mappings = controller.getWebAppCardMappings(card.id); @@ -68,41 +70,53 @@ }); - {#if card.value != 'A' && card.value != 'B'} + {#if hasMappings }

{$t('cards.webAppCardTaxonomy.h1.1')}

+ {#if mappings.stride} + {/if} + {#if mappings.owasp_asvs} + {/if} + {#if mappings.capec} + {/if} + {#if mappings.owasp_dev_guide} + {/if} + {#if mappings.owasp_appsensor} + {/if} + {#if mappings.safecode} "https://safecode.org/publication/SAFECode_Agile_Dev_Security0712.pdf"} /> + {/if} {/if}

ASVS (4.0) Cheat Sheet Series Index

- {#if card.value != 'A' && card.value != 'B'} + {#if hasMappings && mappings.owasp_asvs} +String(s).split('.').slice(0, 2).join('.')))]}> {/if}

{$t('cards.webAppCardTaxonomy.h1.2')}

diff --git a/cornucopia.owasp.org/src/lib/services/deckService.ts b/cornucopia.owasp.org/src/lib/services/deckService.ts index 0c2ffde99..efbdfb740 100644 --- a/cornucopia.owasp.org/src/lib/services/deckService.ts +++ b/cornucopia.owasp.org/src/lib/services/deckService.ts @@ -115,11 +115,29 @@ export class DeckService { { const decks = new Map(); const editions = DeckService.decks; + + // Load all mappings if not already loaded + if (DeckService.mappings.length === 0) { + this.getCardMappingDataAllVersions(); + } + editions.forEach((deck) => { - decks.set( - `${deck.edition}-${deck.version}`, DeckService.mappings.find((mapping) => mapping?.version == deck.version && mapping?.edition == deck.edition)?.data || this.getCardMappingDataAllVersions() - ); + let mappingData = DeckService.mappings.find((mapping) => mapping?.version == deck.version && mapping?.edition == deck.edition)?.data; + // If not found in cache, try to load it + if (!mappingData) { + try { + const yamlData = fs.readFileSync(`${__dirname}${DeckService.path}${DeckService.getEdition(deck.edition)}-mappings-${deck.version}.yaml`, 'utf8'); + mappingData = yaml.load(yamlData); + DeckService.mappings.push({edition: deck.edition, version: deck.version, data: mappingData}); + } catch (e) { + console.error(`Failed to load mapping for ${deck.edition}-${deck.version}:`, e); + } + } + + if (mappingData) { + decks.set(`${deck.edition}-${deck.version}`, mappingData); + } }); return decks; } diff --git a/cornucopia.owasp.org/src/routes/card/[edition]/+page.server.ts b/cornucopia.owasp.org/src/routes/card/[edition]/+page.server.ts index 161953536..3ec4df2e7 100644 --- a/cornucopia.owasp.org/src/routes/card/[edition]/+page.server.ts +++ b/cornucopia.owasp.org/src/routes/card/[edition]/+page.server.ts @@ -3,7 +3,6 @@ import { error } from '@sveltejs/kit'; import { SuitController } from '$domain/suit/suitController'; import { FileSystemHelper } from '$lib/filesystem/fileSystemHelper'; -const editions = ["webapp", "mobileapp"]; export const load = (({ params }) => { const edition = params?.edition; if (!DeckService.hasEdition(edition)) error( diff --git a/cornucopia.owasp.org/src/routes/card/[edition]/[card]/+page.server.ts b/cornucopia.owasp.org/src/routes/card/[edition]/[card]/+page.server.ts index 88b8dd98f..71f85e15e 100644 --- a/cornucopia.owasp.org/src/routes/card/[edition]/[card]/+page.server.ts +++ b/cornucopia.owasp.org/src/routes/card/[edition]/[card]/+page.server.ts @@ -3,8 +3,6 @@ import { error } from '@sveltejs/kit'; import { DeckService } from "$lib/services/deckService"; import type { Route } from "$domain/routes/route"; -const editions = ["webapp", "mobileapp"]; - export const load = (({ params }) => { const edition = params?.edition; const version = edition == 'webapp' ? '2.2' : '1.1'; diff --git a/cornucopia.owasp.org/src/routes/card/[edition]/[card]/[version]/+page.server.ts b/cornucopia.owasp.org/src/routes/card/[edition]/[card]/[version]/+page.server.ts index be5a3b171..f65874b73 100644 --- a/cornucopia.owasp.org/src/routes/card/[edition]/[card]/[version]/+page.server.ts +++ b/cornucopia.owasp.org/src/routes/card/[edition]/[card]/[version]/+page.server.ts @@ -3,10 +3,6 @@ import { error } from '@sveltejs/kit'; import { DeckService } from "$lib/services/deckService"; import type { Route } from "$domain/routes/route"; -const editions = ["webapp", "mobileapp"]; -const languages = ["en", "no_nb", "nl", "es", "pt_pt", "pt_br", "ru", "fr", "it", "hu"]; -const versions = ["3.0", "2.2", "1.0"]; - export const load = (({ params }) => { const edition = params?.edition; const version = params?.version; diff --git a/cornucopia.owasp.org/src/routes/card/[edition]/[card]/[version]/[lang]/+page.server.ts b/cornucopia.owasp.org/src/routes/card/[edition]/[card]/[version]/[lang]/+page.server.ts index 9e88d3e49..282f3c4e2 100644 --- a/cornucopia.owasp.org/src/routes/card/[edition]/[card]/[version]/[lang]/+page.server.ts +++ b/cornucopia.owasp.org/src/routes/card/[edition]/[card]/[version]/[lang]/+page.server.ts @@ -3,10 +3,6 @@ import { DeckService } from "$lib/services/deckService"; import { error } from '@sveltejs/kit'; import type { Route } from "$domain/routes/route"; -const editions = ["webapp", "mobileapp"]; -const languages = ["en", "no_nb", "nl", "es", "pt_pt", "pt_br", "ru", "fr", "it", "hu"]; -const versions = ["3.0", "2.2", "1.0"]; - export const load = (({ params }) => { const edition = params?.edition; const version = params?.version; diff --git a/cornucopia.owasp.org/svelte.config.js b/cornucopia.owasp.org/svelte.config.js index 297a1c719..38006d249 100644 --- a/cornucopia.owasp.org/svelte.config.js +++ b/cornucopia.owasp.org/svelte.config.js @@ -93,7 +93,26 @@ export default { '/api/cre/webapp/pt_pt', '/api/cre/webapp/pt_br', '/api/cre/webapp/no_nb', - '/api/cre/mobileapp/en' + '/api/cre/mobileapp/en', + '/card/mobileapp/PC2/1.1/en', + '/card/webapp/VE2/2.2/es', + '/card/webapp/VE2/2.2/it', + '/card/webapp/VE2/2.2/nl', + '/card/webapp/VE2/2.2/fr', + '/card/webapp/VE2/2.2/pt_pt', + '/card/webapp/VE2/2.2/pt_br', + '/card/webapp/VE2/2.2/no_nb', + '/card/webapp/VE2/2.2/ru', + '/card/webapp/VE2/3.0', + '/card/webapp/VE2/3.0/en', + '/card/webapp/VE2/3.0/es', + '/card/webapp/VE2/3.0/it', + '/card/webapp/VE2/3.0/nl', + '/card/webapp/VE2/3.0/fr', + '/card/webapp/VE2/3.0/pt_pt', + '/card/webapp/VE2/3.0/pt_br', + '/card/webapp/VE2/3.0/no_nb', + '/card/webapp/VE2/3.0/ru', ] }, csrf: { diff --git a/source/mobileapp-mappings-1.1.yaml b/source/mobileapp-mappings-1.1.yaml index de423d99b..e0f74ec6f 100644 --- a/source/mobileapp-mappings-1.1.yaml +++ b/source/mobileapp-mappings-1.1.yaml @@ -6,7 +6,7 @@ meta: version: "1.1" layouts: ["cards", "leaflet"] templates: ["bridge_qr", "bridge", "tarot", "tarot_qr"] - languages: ["en"] + languages: ["en", "ru"] suits: - id: "PC" @@ -655,4 +655,24 @@ suits: owasp_masvs: [ "-" ] owasp_mastg: [ "-" ] capec: [ "-" ] + safecode: [ "-" ] +- + id: "WC" + name: "WILD CARD" + cards: + - + id: "JOAM" + value: "A" + url: "https://cornucopia.owasp.org/cards/JOAM" + owasp_masvs: [ "-" ] + owasp_mastg: [ "-" ] + capec: [ "-" ] + safecode: [ "-" ] + - + id: "JOBM" + value: "A" + url: "https://cornucopia.owasp.org/cards/JOBM" + owasp_masvs: [ "-" ] + owasp_mastg: [ "-" ] + capec: [ "-" ] safecode: [ "-" ] \ No newline at end of file diff --git a/source/webapp-mappings-2.2.yaml b/source/webapp-mappings-2.2.yaml index 6dc55c669..0aa82efb1 100644 --- a/source/webapp-mappings-2.2.yaml +++ b/source/webapp-mappings-2.2.yaml @@ -1298,3 +1298,31 @@ suits: owasp_appsensor: [ "-" ] capec: [ "-" ] safecode: [ "-" ] +- + id: "WC" + name: "WILD CARD" + cards: + - + id: "JOA" + value: "A" + url: "https://cornucopia.owasp.org/cards/JOA" + stride: [] + stride_print: [ ] + owasp_dev_guide: [ "-" ] + owasp_dev_guide_print: [ "-" ] + owasp_asvs: [ "-" ] + owasp_asvs_print: [ "-" ] + capec: [ 184, 242, 248, 441, 444, 523, 549, 636, 691 ] + safecode: [ "-" ] + - + id: "JOB" + value: "B" + url: "https://cornucopia.owasp.org/cards/JOB" + stride: [] + stride_print: [ ] + owasp_dev_guide: [ "-" ] + owasp_dev_guide_print: [ "-" ] + owasp_asvs: [ "-" ] + owasp_asvs_print: [ "-" ] + capec: [ 184, 242, 416, 438, 441, 444, 523, 518, 519, 548, 636, 691 ] + safecode: [ "-" ] \ No newline at end of file diff --git a/source/webapp-mappings-3.0.yaml b/source/webapp-mappings-3.0.yaml index a45686236..fb735ff95 100644 --- a/source/webapp-mappings-3.0.yaml +++ b/source/webapp-mappings-3.0.yaml @@ -1880,12 +1880,12 @@ suits: stride_print: [ 'Information Disclosure' ] owasp_dev_guide: [ SC1, SC2, SC3, SC4, SC5, SC6, SC7, SC8, SC9, SC10, SC11, SC12, SC13, SFL1, SFL2, SFL14, SFL15, SDC2, SDC3, SDC4, SDC5, SDC6, SDA1, PDT1, PDT2, PDT3, PDT4, PDT5, PDT6, PDT7, PDT8, PDT9, PDT10, PDT11 ] owasp_dev_guide_print: [ SC1-13, SFL1-2, SFL14-15, SDC2-6, SDA1, PDT1-11 ] - owasp_asvs: [ 12.1.1, 12.1.2, 12.1.3, 12.1.4, 12.1.5, 12.2.1, 12.2.2, 12.3.1, 12.3.2, 12.3.3, 12.3.4, 12.3.5, 13.2.1, 13.2.2, 13.2.3, 13.3.1, 13.3.2, 13.3.3, 13.3.4, 13.3.5, 13.4.1, 13.4.2, 13.4.3, 13.4.4, 13.4.5, 13.4.6, 13.4.7, 15.1.1, 15.1.2, 15.2.1, 15.2.4, 16.3.3, 16.3.4 ] - owasp_asvs_print: [ 12.1.1-5, 12.2.1-2, 12.3.1-5, 13.2.1-3, 13.3.1-5, 13.4.1-7, 15.1.1-2, 15.2.1, 15.2.4, 16.3.3-4 ] + owasp_asvs: [ 12.1.1, 12.1.2, 12.1.3, 12.1.4, 12.1.5, 12.2.1, 12.2.2, 12.3.1, 12.3.2, 12.3.3, 12.3.4, 12.3.5, 13.2.1, 13.2.2, 13.2.3, 13.3.1, 13.3.2, 13.3.3, 13.3.4, 13.4.1, 13.4.2, 13.4.3, 13.4.4, 13.4.5, 13.4.6, 13.4.7, 15.1.1, 15.1.2, 15.2.1, 15.2.4, 16.3.3, 16.3.4 ] + owasp_asvs_print: [ 12.1.1-5, 12.2.1-2, 12.3.1-5, 13.2.1-3, 13.3.1-4, 13.4.1-7, 15.1.1-2, 15.2.1, 15.2.4, 16.3.3-4 ] capec: [ 37, 121, 159, 169, 217, 220, 310, 446 ] capec_map: 37: - owasp_asvs: [ 13.2.1, 13.2.2, 13.2.3, 13.3.1, 13.3.2, 13.3.3, 13.3.4, 13.3.5, 13.4.1, 13.4.7 ] + owasp_asvs: [ 13.2.1, 13.2.2, 13.2.3, 13.3.1, 13.3.2, 13.3.3, 13.3.4, 13.4.1, 13.4.7 ] 121: owasp_asvs: [ 13.4.2 ] 169: