UNPKG

juice-shop-ctf-cli

Version:

Capture-the-Flag (CTF) environment setup tools for OWASP Juice Shop

91 lines (79 loc) 4.49 kB
/* * Copyright (c) 2016-2025 Bjoern Kimminich & the OWASP Juice Shop contributors. * SPDX-License-Identifier: MIT */ const chai = require('chai') chai.use(require('chai-things')) chai.use(require('chai-subset')) chai.use(require('chai-as-promised')) const expect = chai.expect const generateData = require('../../lib/generators/rtb') const options = require('../../lib/options') const defaultOptions = { insertHints: options.noTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', vulnSnippets: {} } describe('Generated RTB data', () => { let challenges beforeEach(() => { challenges = { c1: { id: 1, key: 'k1', name: 'c1', description: 'C1', difficulty: 1, category: '1' }, c2: { id: 2, key: 'k2', name: 'c2', description: 'C2', difficulty: 2, category: '2' }, c3: { id: 3, key: 'k3', name: 'c3', description: 'C3', difficulty: 3, category: '2' }, c4: { id: 4, key: 'k4', name: 'c4', description: 'C4', difficulty: 4, category: '3' }, c5: { id: 5, key: 'k5', name: 'c5', description: 'C5', difficulty: 5, category: '1' } } }) it('should contain no boxes when given no challenges', () => expect(generateData({}, defaultOptions)).to.eventually.deep.include( '<boxes count="0"/>' ) ) it('should log generator error to console', () => expect(generateData({ c1: undefined }, defaultOptions)).to.be.rejectedWith('Failed to generate challenge data! Cannot read properties of undefined (reading') ) it('should contain one <box> per given challenge category', function () { return expect(generateData(challenges, defaultOptions)).to.eventually.deep.include( '<boxes count="3">' ) }) it('should contain one <category> per given challenge category', function () { return expect(generateData(challenges, defaultOptions)).to.eventually.deep.include( '<categories count="3">' ) }) it('should put each given challenge as a <flag> into the matching category <box>', function () { return expect(generateData(challenges, defaultOptions)).to.eventually.deep.match( /<box gamelevel="0">[\s]{11}<name>1<\/name>[^]*<flags count="2">/ ).and.to.eventually.deep.match( /<box gamelevel="0">[\s]{11}<name>2<\/name>[^]*<flags count="2">/ ).and.to.eventually.deep.match( /<box gamelevel="0">[\s]{11}<name>3<\/name>[^]*<flags count="1">/ ) }) it('should add a <hint> for a text hint defined on a challenge', () => { challenges.c3.hint = 'hint' return Promise.all([ expect(generateData(challenges, { insertHints: options.freeTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.match( /<flag type="static">\s{15}<name>c3<\/name>[^]*<hints count="1">\s{17}<hint>\s{19}<description>hint<\/description>\s{19}<price>0<\/price>/ ), expect(generateData(challenges, { insertHints: options.paidTextHints, insertHintUrls: options.noHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.match( /<flag type="static">\s{15}<name>c3<\/name>[^]*<hints count="1">\s{17}<hint>\s{19}<description>hint<\/description>\s{19}<price>45<\/price>/ ) ]) }) it('should add a <hint> for a hint URL defined on a challenge', () => { challenges.c3.hintUrl = 'hintUrl' return Promise.all([ expect(generateData(challenges, { insertHints: options.noTextHints, insertHintUrls: options.freeHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.match( /<flag type="static">\s{15}<name>c3<\/name>[^]*<hints count="1">\s{17}<hint>\s{19}<description>\[C3]\(hintUrl\)<\/description>\s{19}<price>0<\/price>/ ), expect(generateData(challenges, { insertHints: options.noTextHints, insertHintUrls: options.paidHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.match( /<flag type="static">\s{15}<name>c3<\/name>[^]*<hints count="1">\s{17}<hint>\s{19}<description>\[C3]\(hintUrl\)<\/description>\s{19}<price>90<\/price>/ ) ]) }) it('should extract the link text for a hint URL from its anchor', () => { challenges.c3.hintUrl = 'hintUrl#this-is-the-anchor-to-the-ebook-section' return expect(generateData(challenges, { insertHints: options.noTextHints, insertHintUrls: options.freeHintUrls, ctfKey: '', vulnSnippets: {} })).to.eventually.deep.match( /<hint>\s{19}<description>\[This Is The Anchor To The Ebook Section]\(hintUrl#this-is-the-anchor-to-the-ebook-section\)<\/description>/ ) }) })