Skip to content

Commit 50d1d5e

Browse files
committed
Add option answer type and cvss module stub
1 parent 94ad6af commit 50d1d5e

11 files changed

Lines changed: 143 additions & 23 deletions

File tree

trainingportal/challenges.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ let init = async () => {
8484
let moduleDefinitions = getDefinitionsForModule(moduleId);
8585
var modulePath = getModulePath(moduleId);
8686
for(let level of moduleDefinitions){
87-
challengeDefinitions.push(level);
8887
for(let challenge of level.challenges){
8988
if(!util.isNullOrUndefined(challengeNames[challenge.id])){
9089
throw new Error(`Duplicate challenge id: '${challenge.id}'!`);
@@ -206,6 +205,7 @@ let getChallengeDefinitions = async (moduleId) => {
206205

207206
if(util.isNullOrUndefined(moduleId)) return [];
208207
if(util.isNullOrUndefined(modules[moduleId])) return [];
208+
if(!util.isNullOrUndefined(challengeDefinitions[moduleId])) return challengeDefinitions[moduleId];
209209

210210
var modulePath = getModulePath(moduleId);
211211
var moduleDefinitions = getDefinitionsForModule(moduleId);
@@ -224,12 +224,17 @@ let getChallengeDefinitions = async (moduleId) => {
224224
challenge.description = path.join(modulePath, description);
225225
}
226226
if(challenge.type === "quiz"){
227-
challenge.question = qna.getCode(challenge.id);
227+
if(util.isNullOrUndefined(challenge.options)){
228+
challenge.question = qna.getCode(challenge.id);
229+
}
230+
else if(!util.isNullOrUndefined(challenge.answer)){
231+
challenge.question = { "digest": qna.getDigest(challenge.answer)}
232+
}
228233
}
229234
}
230235
returnChallenges.push(level);
231236
}
232-
237+
challengeDefinitions[moduleId] = returnChallenges;
233238
return returnChallenges;
234239
}
235240

@@ -452,8 +457,8 @@ let apiChallengeCode = async (req) => {
452457
}
453458

454459
let answer = null;
455-
if(!util.isNullOrUndefined(req.body.answer)){
456-
answer = req.body.answer.trim();
460+
if(!util.isNullOrUndefined(req.body.answer) && typeof req.body.answer === "string"){
461+
answer = req.body.answer.trim().toLowerCase();
457462
}
458463

459464
if(util.isNullOrUndefined(challengeCode) ||

trainingportal/qna.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@ let getSecretText = (challengeId) => {
2525
return secretText.toUpperCase();
2626
}
2727

28+
let getDigest = (val) => {
29+
return crypto.createHash('sha256').update(val.trim().toLowerCase() + masterSalt).digest('hex');
30+
}
31+
2832
let getRes = (mes, code) => {
29-
let digest = crypto.createHash('sha256').update(mes.trim()+masterSalt).digest('hex');
33+
let digest = getDigest(mes);
3034
return res = {
3135
code:code,
3236
digest:digest,
@@ -241,6 +245,7 @@ const DEFS = {
241245
module.exports = {
242246
DEFS,
243247
getCode,
248+
getDigest,
244249
checkCode,
245250
xorOp
246251
}

trainingportal/static/challenges.html

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,38 @@ <h4>Challenge</h4>
7474
The play link has been provided to you when solving the previous module or challenge.
7575
If you have missed it read the challenge description carefully and try to figure out what it is.
7676
</p>
77-
<div ng-if="challenge.question" class="alert alert-info" style="color: black;">
77+
<div ng-if="challenge.question.code" class="alert alert-info" style="color: black;">
7878
<textarea rows="10" readonly style="background-color: transparent; border: 0px; width: 100%">{{challenge.question.code}}</textarea>
7979
</div>
8080

81+
<span ng-if="challenge.options">
82+
<div class="form-check" ng-repeat="op in challenge.options">
83+
<input class="form-check-input option-{{challenge.id}}" type="radio" value="{{op.value}}" name="option" id="option-{{challenge.id}}-{{$index}}">
84+
<label class="form-check-label" for="option-{{challenge.id}}-{{$index}}">
85+
{{op.display}}
86+
</label>
87+
</div>
88+
</span>
89+
8190
<span ng-if="!challenge.passed">
8291

92+
<span ng-if="challenge.options">
93+
<br>
94+
<a ng-click="submitOption(challenge.id, challenge.question.digest)" class="btn btn-info btn-sm" role="button">Submit Answer</a>
95+
</span>
96+
8397
<span ng-if="challenge.type !== 'quiz'">
8498
<p>
8599
Once you were able to complete the challenge you can generate a code which you can submit below.
86100
</p>
87101
<a ng-href="#!submitCode/{{moduleId}}/{{challenge.id}}/page/0" class="btn btn-info btn-sm" role="button">Submit Code</a>
88102
</span>
89103

90-
<span ng-if="challenge.type === 'quiz'">
91-
<p>
92-
Once you were able to find the answer you can submit it below.
93-
</p>
94-
<a ng-href="#!submitCode/{{moduleId}}/{{challenge.id}}/quiz/{{challenge.question.digest}}" class="btn btn-info btn-sm" role="button">Submit Answer</a>
104+
<span ng-if="challenge.type === 'quiz' && !challenge.options">
105+
<label for="answer-{{challenge.id}}">Answer:</label> &nbsp;
106+
<input type="text" autocomplete="off" class="form-control" style="width: 100%;" id="answer-{{challenge.id}}" value=""/>
107+
<br>
108+
<a ng-click="submitAnswer(challenge.id, challenge.question.digest)" class="btn btn-info btn-sm" role="button">Submit Answer</a>
95109
</span>
96110

97111
</span>

trainingportal/static/challengesCtrl.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,36 @@ app.controller("challengesCtrl", function($scope, $http, $routeParams) {
2424

2525
}
2626

27+
$scope.submitOption = function(id, digest){
28+
let answer = null;
29+
let options = document.getElementsByClassName(`option-${id}`);
30+
for(let op of options){
31+
if(op.checked){
32+
answer = op.value
33+
break;
34+
}
35+
}
36+
$scope.saveAnswer(answer,id,digest);
37+
}
38+
39+
$scope.submitAnswer = function(id, digest){
40+
let answer = null;
41+
let el = document.getElementById(`answer-${id}`);
42+
if(el){
43+
answer = el.value;
44+
}
45+
$scope.saveAnswer(answer,id,digest);
46+
}
47+
48+
$scope.saveAnswer = function(answer, id, digest){
49+
if(answer !== null){
50+
localStorage.setItem("dojo.current.answer", answer);
51+
localStorage.setItem("dojo.current.challenge", window.location.href);
52+
window.location.href = `#!submitCode/${$scope.moduleId}/${id}/quiz/${digest}`;
53+
}
54+
}
55+
56+
2757
$scope.loadChallenges = function(){
2858
$http.get(`/challenges/${$scope.moduleId}`)
2959
.then(function(response) {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#### Agreeing on vulnerability severity
2+
3+
The Common Vulnerability Scoring System (CVSS) is how we agree on vulnerability severity.
4+
5+
We need to agree on severity so we may prioritize investing our time and effort where it matters most.

trainingportal/static/lessons/cvss/cvss_intro.sol.md

Whitespace-only changes.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
[
2+
{
3+
"level":0,
4+
"name":"Vulnerability Investigator",
5+
"challenges":[
6+
{
7+
"id":"cvss_intro",
8+
"name":"About CVSS",
9+
"description": "cvss_intro.md",
10+
"solution": "cvss_intro.sol.md",
11+
"type":"quiz",
12+
"mission":"Choose the correct option",
13+
"options":[
14+
{
15+
"display":"Confidentiality: High, Integrity: High, Availability: High",
16+
"value":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N"
17+
},
18+
{
19+
"display":"Confidentiality: High, Integrity: High, Availability: None",
20+
"value":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N"
21+
},
22+
{
23+
"display":"Confidentiality: High, Integrity: None, Availability: None",
24+
"value":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N"
25+
},
26+
{
27+
"display":"Confidentiality: None, Integrity: None, Availability: None",
28+
"value":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:N/SI:N/SA:N"
29+
}
30+
],
31+
"answer":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
32+
"codeBlockIds":[]
33+
}
34+
]
35+
}
36+
]

trainingportal/static/lessons/modules.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@
1414
},
1515
"requiredModules":[]
1616
},
17+
"cvss":{
18+
"name":"Vulnerability Investigator",
19+
"summary":"Understanding vulnerability severity",
20+
"description":"This module covers the most important aspects of the Common Vulnerability Scoring System (CVSS)",
21+
"description2": "Includes <TBD> lessons. Estimated duration 2 hours.",
22+
"badgeInfo":{
23+
"line1":"Secure Coding Dojo",
24+
"line2":"Vulnerability Investigator",
25+
"line3":"",
26+
"bg":"darkorange"
27+
},
28+
"requiredModules":[]
29+
},
1730
"cryptoBreaker":{
1831
"name":"Crypto Breaker - Part 1",
1932
"summary":"Introduction to Cryptography",

trainingportal/static/submitCode.html

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,21 @@
66
<h4 ng-if="challengeCodeValue === '0'">When you have solved the challenge, take the salt below to obtain the verification code.</h4>
77
<br>
88
<form autocomplete="off">
9-
<div ng-if="challengeType === 'quiz'" class="form-group form-inline">
10-
<label for="answer">Answer:</label> &nbsp;
11-
<input type="text" autocomplete="off" class="form-control" style="width: 100%;" id="answer" value=""/>
12-
</div>
13-
<div ng-if="challengeCodeValue === '0'" class="form-group form-inline">
9+
<div ng-if="challengeType !== 'quiz'" class="form-group form-inline">
1410
<label for="salt">Salt:</label> &nbsp;
1511
<input type="text" autocomplete="off" class="form-control" id="saltEl" value="{{salt}}"/>
1612
<button type="button" class="btn btn-default" onclick="document.getElementById('saltEl').select();document.execCommand('copy');">
1713
<span class="oi oi-clipboard"></span>
1814
</button>
1915
</div>
20-
<div ng-if="challengeCodeValue === '0'" class="form-group ">
16+
<div ng-if="challengeType !== 'quiz'" class="form-group ">
2117
<label for="challengeCode">Challenge code:</label>
2218
<input type="text" autocomplete="off" class="form-control" id="challengeCode">
2319
</div>
2420
</form>
25-
<button class="btn btn-primary" ng-click="submitAnswer()">Submit</button>
26-
<button class="btn btn-secondary" onclick="window.history.back()">Back</button>
21+
<button ng-if="challengeType !== 'quiz'" class="btn btn-primary" ng-click="submitAnswer()">Submit</button>
22+
<button ng-if="challengeType !== 'quiz'" class="btn btn-secondary" onclick="window.history.back()">Back</button>
23+
<button ng-if="challengeType === 'quiz'" class="btn btn-secondary" ng-click="goBack()">Back</button>
2724

2825

2926
<!-- Code Block Dialog -->

trainingportal/static/submitCodeCtrl.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@ app.controller("submitCodeCtrl", function($scope, $http, $routeParams) {
1919
$scope.init = function(){
2020
var challengeCodeValue = $routeParams.challengeCode;
2121
$scope.challengeType = $routeParams.challengeType;
22+
23+
let answerString = localStorage.getItem("dojo.current.answer");
24+
25+
if(answerString){
26+
localStorage.removeItem("dojo.current.answer");
27+
$scope.answer = answerString;
28+
$scope.submitAnswer()
29+
}
30+
2231
if(challengeCodeValue === '0'){ //this is the old style of challenge verification
2332
$http.get("/api/salt",window.getAjaxOpts())
2433
.then(function(response) {
@@ -37,13 +46,19 @@ app.controller("submitCodeCtrl", function($scope, $http, $routeParams) {
3746
$scope.isCodeErrorMessage = false;
3847
}
3948

49+
$scope.goBack = () => {
50+
let challengeHref = localStorage.getItem("dojo.current.challenge");
51+
if(challengeHref){
52+
localStorage.removeItem("dojo.current.challenge");
53+
window.location.href = challengeHref;
54+
}
55+
}
4056

4157
$scope.submitAnswer = function(){
4258
var moduleId = $routeParams.moduleId;
4359
var challengeId = $routeParams.challengeId;
4460
var challengeType = $routeParams.challengeType;
45-
var answerValue = "";
46-
if(typeof answer !== "undefined") answerValue = answer.value;
61+
var answerValue = $scope.answer
4762

4863
var challengeCodeValue = "";
4964
if(typeof challengeCode !== "undefined"){

0 commit comments

Comments
 (0)