>
Software Security Training

Exercise: The Missing Gate

In this activity, you will implement a Secure Development Lifecycle (SDLC) control by automating a security scan in the build pipeline.

Scenario: You are a DevOps Engineer. Your team's current build script pushes code directly to production. You need to implement a "Break the Build" policy.

Your Task

  1. Examine the run_pipeline function.
  2. Call stage_security_scan() before the deploy step.
  3. CRITICAL: This function returns True (Pass) or False (Fail).
  4. You must write an if statement: If the scan fails, print an error and return immediately to stop deployment.
  5. When finished, click "Export PDF" to submit.

Why This Matters

A "Security Gate" is useless if it only warns you. To be effective, the pipeline must automatically abort deployment if vulnerabilities are detected.

PYTHON EDITOR (build_script.py)
1
SECURITY CONSOLE OUTPUT
Ready... Waiting for pipeline execution.
from js import document, window import sys import random def setup(): loading = document.getElementById("loading") if loading: loading.style.display = "none" setup() class ConsoleOutput: def write(self, text): if text.strip(): log(text.strip(), "normal") def flush(self): pass sys.stdout = ConsoleOutput() sys.stderr = ConsoleOutput() def log(message, type="normal"): console = document.getElementById("console-output") if type == "clear": console.innerHTML = "" return color = "#ffffff" if type == "pass": color = "#2ecc71" if type == "fail": color = "#e74c3c" if type == "info": color = "#3498db" if type == "system": color = "#d4d4d4" safe_message = message.replace("<", "<").replace(">", ">") console.innerHTML += f'
{safe_message}
' console.scrollTop = console.scrollHeight # --- MOCK PIPELINE FUNCTIONS --- execution_log = [] scan_result_mode = True def stage_checkout(): print("[+] Git Checkout: Fetching latest code...") execution_log.append("checkout") def stage_build(): print("[+] Build: Compiling binaries...") execution_log.append("build") def stage_security_scan(): if scan_result_mode: print("[*] SECURITY SCAN: No issues found. (PASS)") execution_log.append("scan_pass") return True else: print("[!] SECURITY SCAN: Critical Vulnerability Found! (FAIL)") execution_log.append("scan_fail") return False def stage_deploy(): print("[!] DEPLOY: Pushing to Production Server...") execution_log.append("deploy") # --- TEST RUNNER --- def run_tests(*args): global scan_result_mode log("", "clear") log("[SYSTEM] Starting Test Suite...", "system") user_code = document.getElementById("code-editor").value # 1. TEST CASE A: CLEAN CODE (Should Deploy) log("--- TEST CASE 1: Clean Code (Should Pass & Deploy) ---", "system") execution_log.clear() scan_result_mode = True test_env = { "stage_checkout": stage_checkout, "stage_build": stage_build, "stage_security_scan": stage_security_scan, "stage_deploy": stage_deploy } try: # Use test_env as globals/locals to fix scope exec(user_code, test_env) if "run_pipeline" in test_env: test_env["run_pipeline"]() if "deploy" not in execution_log: log(" -> FAIL: Pipeline stopped even though code was safe.", "fail") return else: log(" -> PASS: Safe code was deployed.", "pass") except Exception as e: log(f"[!] Runtime Error: {e}", "fail") return # 2. TEST CASE B: VULNERABLE CODE (Should BLOCK Deploy) log("", "normal") log("--- TEST CASE 2: Vulnerable Code (Should BLOCK Deploy) ---", "system") execution_log.clear() scan_result_mode = False try: # Re-run pipeline with failing scan test_env["run_pipeline"]() # Grading Logic if "scan_fail" not in execution_log: log(" -> FAIL: You didn't run the security scan!", "fail") window.submissionStatus = "FAILED - Missing Scan" return if "deploy" in execution_log: log(" -> FAIL: You ran the scan, but ignored the error!", "fail") log(" The build deployed despite a security failure.", "fail") window.submissionStatus = "FAILED - Ignored Error" return log(" -> PASS: Deployment blocked successfully!", "pass") log(" SUCCESS: Security Gate is active.", "pass") window.submissionStatus = "PASSED - Secure" except Exception as e: log(f"[!] Runtime Error: {e}", "fail") window.submissionStatus = "ERROR - Syntax/Runtime"