diff --git a/.github/workflows/cd-pipeline.yml b/.github/workflows/cd-pipeline.yml new file mode 100644 index 00000000..23be84de --- /dev/null +++ b/.github/workflows/cd-pipeline.yml @@ -0,0 +1,44 @@ +name: Deploy + +on: workflow_dispatch + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Install Cosign + uses: sigstore/cosign-installer@v3.4.0 + + - name: Verify image signature + env: + IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/devops-labs:latest + GITHUB_ISSUER: https://token.actions.githubusercontent.com + CERT_IDENTITY_REGEXP: https://github.com/margaritasentuna/IATD-DevSecOps/.github/workflows/ci-pipeline.yml + run: | + cosign verify $IMAGE --certificate-identity-regexp $CERT_IDENTITY_REGEXP --certificate-oidc-issuer $GITHUB_ISSUER + submit_results: + needs: [deploy] + if: true + runs-on: ubuntu-latest + steps: + - uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Azure CLI script + id: token-gen + uses: azure/CLI@v1 + with: + azcliversion: 2.63.0 + inlineScript: | + ACCESS_TOKEN=$(az account get-access-token | jq -r .accessToken) + echo "azureAccessToken=$ACCESS_TOKEN" >> "$GITHUB_OUTPUT" + - name: Upload reports + env: + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + AZURE_ACCESS_TOKEN: ${{ steps.token-gen.outputs.azureAccessToken }} + run: | + export FQDN=$(az containerapp show -n devops-app -g devsecops-lab --query properties.configuration.ingress.fqdn -o tsv) + echo "FQDN: $FQDN" + WEEK2_SUBMIT=$(curl -X POST -H "Authorization: Bearer $AZURE_ACCESS_TOKEN" -d "https://$FQDN" https://devsecops-ver.azurewebsites.net/api/week2-submit) + echo "Week2 submit: $WEEK2_SUBMIT" \ No newline at end of file diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml new file mode 100644 index 00000000..96525c10 --- /dev/null +++ b/.github/workflows/ci-pipeline.yml @@ -0,0 +1,254 @@ +name: Python test and build + +on: [push] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Test with pytest + run: | + pip install pytest pytest-cov + pytest api_tests.py --doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html + - name: Archive code coverage results + uses: actions/upload-artifact@v4 + id: artifact-upload-step + with: + name: test-results + path: junit/test-results.xml + image-scan: + needs: [test] + if: true + runs-on: ubuntu-latest + steps: + - name: Scan image + uses: anchore/scan-action@v3 + id: image-scan + with: + image: ${{ secrets.DOCKERHUB_USERNAME }}/devops-labs + fail-build: false + output-format: json + - name: Upload Image report + id: upload-image-report + uses: actions/upload-artifact@v4 + with: + name: image-report + path: ${{ steps.image-scan.outputs.json }} + sonarqube: + needs: test + if: true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + # Disabling shallow clones is recommended for improving the relevancy of reporting + fetch-depth: 0 + - name: SonarQube Scan + uses: sonarsource/sonarqube-scan-action@master + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_URL }} + - name: Download SonarQube report + run: | + sleep 30 + URL="${{ secrets.SONAR_URL }}/api/qualitygates/project_status?p=1&projectKey=devsecops-app&branch=main" + echo "Report URL $URL" + curl -u ${{ secrets.SONAR_TOKEN }}: "$URL" -o sonarqube-report.json + - name: Upload SonarQube report + id: artifact-sonarqube + uses: actions/upload-artifact@v4 + with: + name: sonarqube-report + path: sonarqube-report.json + dast: + needs: test + if: true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - + name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Build and push + uses: docker/build-push-action@v5 + with: + push: true + tags: ${{ secrets.DOCKERHUB_USERNAME }}/devops-labs:dast-test + - uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Deploy DAST Container App + uses: azure/container-apps-deploy-action@v1 + with: + imageToDeploy: ${{ secrets.DOCKERHUB_USERNAME }}/devops-labs:dast-test + containerAppName: devops-test-app + containerAppEnvironment: devops-app-env + resourceGroup: devsecops-lab + location: australiaeast + targetPort: 5000 + - name: Get deployed DAST app url + run: | + export FQDN=$(az containerapp show -n devops-test-app -g devsecops-lab --query properties.configuration.ingress.fqdn -o tsv) + echo "TEST_APP_URL=https://$FQDN" >> $GITHUB_ENV + echo "TEST_APP_URL=https://$FQDN" + curl https://$FQDN/ui + sed -i "s,http://localhost:5000,https://$FQDN,g" $GITHUB_WORKSPACE/openapi_specs/openapi3.yml + - name: ZAP Scan + uses: zaproxy/action-api-scan@v0.6.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + docker_name: 'ghcr.io/zaproxy/zaproxy:stable' + format: openapi + target: /zap/wrk/openapi_specs/openapi3.yml + rules_file_name: .zap/rules.tsv + cmd_options: '-a -c /zap/wrk/.zap/rules.tsv' + fail_action: false + allow_issue_writing: false + + - name: Upload ZAP report + id: artifact-zap + uses: actions/upload-artifact@v4 + with: + name: zap-report + path: report_json.json + build: + # needs: [security_gate] + if: true + permissions: + id-token: write + runs-on: ubuntu-latest + steps: + - + name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - + name: Build and push + uses: docker/build-push-action@v5 + with: + push: true + sbom: true + provenance: true + tags: ${{ secrets.DOCKERHUB_USERNAME }}/devops-labs:latest + + - name: Install Cosign + uses: sigstore/cosign-installer@v3.4.0 + + - name: Sign the images with GitHub OIDC Token + env: + IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/devops-labs:latest + run: | + cosign sign --yes ${IMAGE} + security_gate: + needs: [sonarqube, dast, image-scan] + if: true + runs-on: ubuntu-latest + steps: + - name: Download sonarqube-report + uses: actions/download-artifact@v4 + with: + name: sonarqube-report + path: ${{github.workspace}} + - name: Download zap-report + uses: actions/download-artifact@v4 + with: + name: zap-report + path: ${{github.workspace}} + - name: Download image-report + uses: actions/download-artifact@v4 + with: + name: image-report + path: ${{github.workspace}} + - name: Read reports + run: | + IMAGE_RESULT_HIGH=$(cat results.json | jq '.matches[] | select(.vulnerability.severity=="High") | .vulnerability.id' | wc -l) + if [ $IMAGE_RESULT_HIGH -gt 0 ]; then + echo "Image scan has high severity vulnerabilities" + exit 1 + else + echo "Image scan passed" + fi + + SONAR_RESULT=$(cat sonarqube-report.json | jq -r '.projectStatus.status') + if [ $SONAR_RESULT != "OK" ]; then + echo "Sonar scan has issues" + exit 1 + else + echo "Sonar scan passed" + fi + + ZAP_RESULT_HIGH=$(cat report_json.json | jq -r '.site[].alerts[] | select(.riskdesc | startswith("High")) | .name' | wc -l) + if [ $ZAP_RESULT_HIGH -gt 0 ]; then + echo "Zap scan has high severity vulnerabilities" + exit 1 + else + echo "Zap scan passed" + fi + + echo "All security gates passed" + submit_reports: + needs: [sonarqube, dast, image-scan] + if: true + runs-on: ubuntu-latest + steps: + - uses: actions/download-artifact@v4 + with: + name: sonarqube-report + path: ${{github.workspace}} + - uses: actions/download-artifact@v4 + with: + name: zap-report + path: ${{github.workspace}} + - uses: actions/download-artifact@v4 + with: + name: image-report + path: ${{github.workspace}} + - name: Upload reports + env: + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + AZURE_ACCESS_TOKEN: ${{ steps.token-gen.outputs.azureAccessToken }} + IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/devops-labs + run: | + WEEK1_CONTAINER=$(curl -X POST -H "Authorization: Bearer $AZURE_ACCESS_TOKEN" -d "$DOCKERHUB_USERNAME/devops-labs" https://devsecops-ver.azurewebsites.net/api/week1-container) + echo "Week1 container upload: $WEEK1_CONTAINER" + + SONAR_RESPONSE=$(curl -X POST -H "Authorization: Bearer $AZURE_ACCESS_TOKEN" --data-binary @$GITHUB_WORKSPACE/sonarqube-report.json https://devsecops-ver.azurewebsites.net/api/week3-sonar-report) + echo "Sonar upload: $SONAR_RESPONSE" + ZAP_RESPONSE=$(curl -X POST -H "Authorization: Bearer $AZURE_ACCESS_TOKEN" --data-binary @$GITHUB_WORKSPACE/report_json.json https://devsecops-ver.azurewebsites.net/api/week3-zap-report) + echo "Zap upload: $ZAP_RESPONSE" + + IMAGE_RESPONSE=$(curl -X POST -H "Authorization: Bearer $AZURE_ACCESS_TOKEN" --data-binary @$GITHUB_WORKSPACE/results.json https://devsecops-ver.azurewebsites.net/api/week4-image-report) + echo "Image report upload: $IMAGE_RESPONSE" + + WEEK5_RESPONSE=$(curl -X POST -H "Authorization: Bearer $AZURE_ACCESS_TOKEN" -d "$IMAGE" https://devsecops-ver.azurewebsites.net/api/week5-report) + echo "Week5 report upload: $WEEK5_RESPONSE" + MODEL_RESPONSE=$(curl -X POST -H "Authorization: Bearer $AZURE_ACCESS_TOKEN" --data-binary @$GITHUB_WORKSPACE/threat-model/ci-pipeline.json https://devsecops-ver.azurewebsites.net/api/week6-report) + echo "Model report upload: $MODEL_RESPONSE" \ No newline at end of file diff --git a/__pycache__/app.cpython-312.pyc b/__pycache__/app.cpython-312.pyc new file mode 100644 index 00000000..c7e01ba3 Binary files /dev/null and b/__pycache__/app.cpython-312.pyc differ diff --git a/__pycache__/config.cpython-312.pyc b/__pycache__/config.cpython-312.pyc new file mode 100644 index 00000000..247491eb Binary files /dev/null and b/__pycache__/config.cpython-312.pyc differ diff --git a/api_views/__pycache__/__init__.cpython-312.pyc b/api_views/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..6335db87 Binary files /dev/null and b/api_views/__pycache__/__init__.cpython-312.pyc differ diff --git a/api_views/__pycache__/books.cpython-312.pyc b/api_views/__pycache__/books.cpython-312.pyc new file mode 100644 index 00000000..7c73eb41 Binary files /dev/null and b/api_views/__pycache__/books.cpython-312.pyc differ diff --git a/api_views/__pycache__/json_schemas.cpython-312.pyc b/api_views/__pycache__/json_schemas.cpython-312.pyc new file mode 100644 index 00000000..5ee0952b Binary files /dev/null and b/api_views/__pycache__/json_schemas.cpython-312.pyc differ diff --git a/api_views/__pycache__/main.cpython-312.pyc b/api_views/__pycache__/main.cpython-312.pyc new file mode 100644 index 00000000..d9f0a869 Binary files /dev/null and b/api_views/__pycache__/main.cpython-312.pyc differ diff --git a/api_views/__pycache__/users.cpython-312.pyc b/api_views/__pycache__/users.cpython-312.pyc new file mode 100644 index 00000000..41a92807 Binary files /dev/null and b/api_views/__pycache__/users.cpython-312.pyc differ diff --git a/api_views/users.py b/api_views/users.py index 4d793d8a..c0217c64 100644 --- a/api_views/users.py +++ b/api_views/users.py @@ -81,7 +81,7 @@ def login_user(): return Response(json.dumps(responseObject), 200, mimetype="application/json") if vuln: # Password Enumeration if user and request_data.get('password') != user.password: - return Response(error_message_helper("Password is not correct for the given username."), 200, mimetype="application/json") + return Response(error_message_helper("Password is not correct for the given username.Week2 Completed"), 200, mimetype="application/json") elif not user: # User enumeration return Response(error_message_helper("Username does not exist"), 200, mimetype="application/json") else: diff --git a/app.py b/app.py index a6c70dab..db7e8336 100644 --- a/app.py +++ b/app.py @@ -6,9 +6,10 @@ DO NOTE: some functionalities will still be vulnerable even if the value is set to 0 as it is a matter of bad practice. Such an example is the debug endpoint. ''' + vuln = int(os.getenv('vulnerable', 1)) # vuln=1 -# token alive for how many seconds? +# token alive for how many seconds?$env:vulnerable=0; python3 app.py alive = int(os.getenv('tokentimetolive', 60)) diff --git a/database/database.db b/database/database.db index 9b340a09..40545fe0 100644 Binary files a/database/database.db and b/database/database.db differ diff --git a/enumerate.py b/enumerate.py new file mode 100644 index 00000000..5840ad98 --- /dev/null +++ b/enumerate.py @@ -0,0 +1,22 @@ +import requests + +user_error_message = "Username does not exist" +password_error_message = "Password is not correct for the given username." + +users_list = ["name1", "name2", "name3", "name4", "name5","admin"] +pass_list = ["pass1", "pass2", "pass3", "pass4", "pass5","admin"] + +for user in users_list: + for password in pass_list: + data = { + "username": user, + "password": password + } + response = requests.post("http://localhost:5000/users/v1/login", json=data) + body = response.json() + if body["message"] == password_error_message: + print(f"User {user} does exist, checking passwords") + elif body["message"] == "Successfully logged in.": + print(f"Found {user} with password {password}") + else: + break \ No newline at end of file diff --git a/models/__pycache__/__init__.cpython-312.pyc b/models/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 00000000..6aa26ddc Binary files /dev/null and b/models/__pycache__/__init__.cpython-312.pyc differ diff --git a/models/__pycache__/books_model.cpython-312.pyc b/models/__pycache__/books_model.cpython-312.pyc new file mode 100644 index 00000000..17e35893 Binary files /dev/null and b/models/__pycache__/books_model.cpython-312.pyc differ diff --git a/models/__pycache__/user_model.cpython-312.pyc b/models/__pycache__/user_model.cpython-312.pyc new file mode 100644 index 00000000..3cc6a977 Binary files /dev/null and b/models/__pycache__/user_model.cpython-312.pyc differ diff --git a/threat-model/ci-pipeline.json b/threat-model/ci-pipeline.json new file mode 100644 index 00000000..230df471 --- /dev/null +++ b/threat-model/ci-pipeline.json @@ -0,0 +1,1613 @@ +{ + "version": "2.2.0", + "summary": { + "title": "CI/CD pipeline", + "owner": "Margarita", + "description": "CI/CD pipeline for DecSecOps labs", + "id": 0 + }, + "detail": { + "contributors": [], + "diagrams": [ + { + "id": 0, + "title": "New STRIDE diagram", + "diagramType": "STRIDE", + "placeholder": "New STRIDE diagram description", + "thumbnail": "./public/content/images/thumbnail.stride.jpg", + "version": "2.2.0", + "cells": [ + { + "position": { + "x": 490, + "y": -10 + }, + "size": { + "width": 480, + "height": 350 + }, + "shape": "trust-boundary-box", + "attrs": { + "headerText": { + "text": "Pipeline\nexecuter" + } + }, + "id": "471baaa7-98c3-48b3-8c52-f5501d751a6a", + "zIndex": -1, + "data": { + "type": "tm.BoundaryBox", + "name": "Pipeline\nexecuter", + "description": "", + "isTrustBoundary": true, + "hasOpenThreats": false + } + }, + { + "position": { + "x": 455.99999999999955, + "y": 359.0000000000017 + }, + "size": { + "width": 550, + "height": 180 + }, + "shape": "trust-boundary-box", + "attrs": { + "headerText": { + "text": "Internal instance" + } + }, + "id": "5191de26-4c16-4dce-83c5-3e90969e9ca4", + "zIndex": -1, + "data": { + "type": "tm.BoundaryBox", + "name": "Internal instance", + "description": "", + "isTrustBoundary": true, + "hasOpenThreats": false + } + }, + { + "position": { + "x": 336, + "y": 70 + }, + "size": { + "width": 140, + "height": 210 + }, + "shape": "trust-boundary-box", + "attrs": { + "headerText": { + "text": "SVC" + } + }, + "id": "2488df8a-4a61-4027-be12-223c6b4088f5", + "zIndex": -1, + "data": { + "type": "tm.BoundaryBox", + "name": "SVC", + "description": "", + "isTrustBoundary": true, + "hasOpenThreats": false + } + }, + { + "position": { + "x": 343.75, + "y": -150 + }, + "size": { + "width": 112.5, + "height": 60 + }, + "attrs": { + "text": { + "text": "Administrator" + }, + "body": { + "stroke": "#333333", + "strokeWidth": 1.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "actor", + "id": "009a82ff-ef75-44f6-bd0a-798ab1875b34", + "zIndex": 1, + "data": { + "type": "tm.Actor", + "name": "Administrator", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "providesAuthentication": false, + "threats": [] + } + }, + { + "position": { + "x": 380, + "y": -10 + }, + "size": { + "width": 60, + "height": 60 + }, + "attrs": { + "text": { + "text": "Manage" + }, + "body": { + "stroke": "#333333", + "strokeWidth": 1.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "process", + "id": "749aa17c-b569-42a2-8a1f-c671cd3112bd", + "zIndex": 2, + "data": { + "type": "tm.Process", + "name": "Manage", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "handlesCardPayment": false, + "handlesGoodsOrServices": false, + "isWebApplication": false, + "privilegeLevel": "", + "threats": [] + } + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "86e6331f-e1c9-42d8-8c26-ccc174fed7ea", + "source": { + "x": 365, + "y": -90 + }, + "target": { + "cell": "749aa17c-b569-42a2-8a1f-c671cd3112bd" + } + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "922a4d17-f925-4ede-834c-4ef91ac554dd", + "source": { + "x": 163, + "y": 130 + }, + "target": { + "cell": "9dbee868-0b6e-4311-b371-a7b7ba1ade90" + } + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "a497c943-cf0b-4e8a-8d9e-476d8a4b841c", + "source": { + "x": 550, + "y": 130 + }, + "target": { + "cell": "ad6ddc79-3b28-4d1f-9452-d1f2164df7ed" + } + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "04b9007a-915c-43f4-8cd8-d338caa3c4c6", + "source": { + "x": 550, + "y": 130 + }, + "target": { + "cell": "8f677b76-7f71-4340-aae6-afe0f2ee3db0" + } + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "ed18bc87-2706-4c71-a989-c027e227243c", + "source": { + "cell": "ad6ddc79-3b28-4d1f-9452-d1f2164df7ed" + }, + "target": { + "cell": "8e6a2823-71f4-4b01-ad52-29760fcb6f5c" + }, + "vertices": [ + { + "x": 680, + "y": 63 + } + ] + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "88f3ecb6-22c5-4990-8a70-dea9aa118073", + "source": { + "x": 650, + "y": 69 + }, + "target": { + "cell": "c4f1e3e3-78ca-4d11-b3f9-a3382b49e441" + } + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "1e7211ff-130f-441e-8a1a-02cb9cc38937", + "source": { + "x": 760, + "y": 70 + }, + "target": { + "cell": "8d392677-5a45-451e-a696-569ed38caeb1" + } + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "bc8982ab-6adb-4a07-98e3-f587b43b8a61", + "source": { + "x": 670, + "y": 200 + }, + "target": { + "cell": "68fe9fd1-b6a6-40a5-a3a0-c67831d8d448" + }, + "vertices": [ + { + "x": 730, + "y": 300 + } + ] + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "d0554eeb-d2fa-4a4e-bde7-606b6235e595", + "source": { + "x": 939, + "y": 160 + }, + "target": { + "cell": "acfc06aa-1ea1-4f07-97c5-14bde75bceee" + }, + "vertices": [ + { + "x": 1010, + "y": 160 + } + ] + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "04062f6f-67a2-4184-a3f4-4d261ab42d02", + "source": { + "x": 970, + "y": 270 + }, + "target": { + "cell": "acfc06aa-1ea1-4f07-97c5-14bde75bceee" + } + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "80e9538d-444e-4f0d-b2a8-e8f867e2bd1e", + "source": { + "cell": "68fe9fd1-b6a6-40a5-a3a0-c67831d8d448" + }, + "target": { + "cell": "0181fcee-4b21-4cff-ba97-bd942439b801" + } + }, + { + "shape": "trust-boundary-curve", + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Boundary", + "name": "", + "description": "", + "isTrustBoundary": true, + "hasOpenThreats": false + }, + "id": "6c975775-adbb-4426-8942-c22673b4e43e", + "source": { + "x": 1150, + "y": 40 + }, + "target": { + "x": 1200, + "y": 350 + }, + "vertices": [ + { + "x": 1030, + "y": 100 + }, + { + "x": 1000, + "y": 190 + }, + { + "x": 1040, + "y": 320 + }, + { + "x": 1080, + "y": 320 + } + ] + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "dbace5dd-f0b7-4a9d-a112-d1d53ab1c3fd", + "source": { + "cell": "1ab80526-c535-471e-86c6-29a23d0b7383" + }, + "target": { + "cell": "c4f1e3e3-78ca-4d11-b3f9-a3382b49e441" + } + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "ba637350-d995-4ed2-9dfa-c296e934fd23", + "source": { + "cell": "19f1e896-db39-4ccd-904b-84b82cdbd9af" + }, + "target": { + "cell": "ed0483e6-5d54-4ba5-9932-58423f8d5b08" + }, + "vertices": [ + { + "x": 380, + "y": 190 + } + ] + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "b0d9180e-329a-42e6-be32-0dde673869e3", + "source": { + "x": 282, + "y": 130 + }, + "target": { + "cell": "19f1e896-db39-4ccd-904b-84b82cdbd9af" + }, + "vertices": [] + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "877f3972-ea35-42dc-b81a-36d8d2303578", + "source": { + "cell": "19f1e896-db39-4ccd-904b-84b82cdbd9af" + }, + "target": { + "cell": "7398b252-d81b-4342-b4de-e1292b3b4ede" + }, + "vertices": [ + { + "x": 460, + "y": 130 + } + ] + }, + { + "shape": "trust-boundary-curve", + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Boundary", + "name": "", + "description": "", + "isTrustBoundary": true, + "hasOpenThreats": false + }, + "id": "b6556c44-80b5-4d16-a7d5-d19ec9777e0b", + "source": { + "x": -70, + "y": 40 + }, + "target": { + "x": -30, + "y": 360 + }, + "vertices": [ + { + "x": 320, + "y": 100 + }, + { + "x": 140, + "y": 260 + }, + { + "x": 110, + "y": 280 + } + ] + }, + { + "shape": "flow", + "attrs": { + "line": { + "stroke": "#333333", + "targetMarker": { + "name": "block" + }, + "sourceMarker": { + "name": "" + }, + "strokeDasharray": null + } + }, + "width": 200, + "height": 100, + "zIndex": 10, + "connector": "smooth", + "data": { + "type": "tm.Flow", + "name": "Data Flow", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isBidirectional": false, + "isEncrypted": false, + "isPublicNetwork": false, + "protocol": "", + "threats": [] + }, + "id": "2f4ff6dc-ce20-4b14-a3d3-18580cd2784a", + "source": { + "x": 590, + "y": 250 + }, + "target": { + "cell": "7398b252-d81b-4342-b4de-e1292b3b4ede" + } + }, + { + "position": { + "x": 50, + "y": 100 + }, + "size": { + "width": 112.5, + "height": 60 + }, + "attrs": { + "text": { + "text": "Developer" + }, + "body": { + "stroke": "red", + "strokeWidth": 2.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "actor", + "id": "0abcb0ab-16e1-4fff-a1f9-eaa733e6e6be", + "zIndex": 11, + "data": { + "type": "tm.Actor", + "name": "Developer", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": true, + "providesAuthentication": false, + "threats": [ + { + "id": "0eb51378-1c9c-49fc-a933-c7ad8f28e7b4", + "title": "Developer commits secret to Git", + "status": "Open", + "severity": "Medium", + "type": "Spoofing", + "description": "A Developer commits secrets to version control either accidentally or on purpose. An Angry employee with read access to the repository find the secrets and proceeds to use them to steal end-user data", + "mitigation": "Vault\n\nAdhere to the principal of \"Need to Know\" and ensure that production secrets are not shared with individuals who don't have a need to know\n\n", + "modelType": "STRIDE", + "new": false, + "number": 1, + "score": "" + } + ] + } + }, + { + "position": { + "x": 222, + "y": 100 + }, + "size": { + "width": 60, + "height": 60 + }, + "attrs": { + "text": { + "text": "Git push" + }, + "body": { + "stroke": "#333333", + "strokeWidth": 1.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "process", + "id": "9dbee868-0b6e-4311-b371-a7b7ba1ade90", + "zIndex": 12, + "data": { + "type": "tm.Process", + "name": "Git push", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "handlesCardPayment": false, + "handlesGoodsOrServices": false, + "isWebApplication": false, + "privilegeLevel": "", + "threats": [] + } + }, + { + "position": { + "x": 370, + "y": 100 + }, + "size": { + "width": 60, + "height": 60 + }, + "attrs": { + "text": { + "text": "Process\n Code\n Push" + }, + "body": { + "stroke": "#333333", + "strokeWidth": 1.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "process", + "id": "19f1e896-db39-4ccd-904b-84b82cdbd9af", + "zIndex": 13, + "data": { + "type": "tm.Process", + "name": "Process\n Code\n Push", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "handlesCardPayment": false, + "handlesGoodsOrServices": false, + "isWebApplication": false, + "privilegeLevel": "", + "threats": [] + } + }, + { + "position": { + "x": 500, + "y": 100 + }, + "size": { + "width": 60, + "height": 60 + }, + "attrs": { + "text": { + "text": "Ci \npipeline" + }, + "body": { + "stroke": "#333333", + "strokeWidth": 1.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "process", + "id": "7398b252-d81b-4342-b4de-e1292b3b4ede", + "zIndex": 14, + "data": { + "type": "tm.Process", + "name": "Ci \npipeline", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "handlesCardPayment": false, + "handlesGoodsOrServices": false, + "isWebApplication": false, + "privilegeLevel": "", + "threats": [] + } + }, + { + "position": { + "x": 610, + "y": 160 + }, + "size": { + "width": 60, + "height": 60 + }, + "attrs": { + "text": { + "text": "Build" + }, + "body": { + "stroke": "#333333", + "strokeWidth": 1.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "process", + "id": "8f677b76-7f71-4340-aae6-afe0f2ee3db0", + "zIndex": 15, + "data": { + "type": "tm.Process", + "name": "Build", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "handlesCardPayment": false, + "handlesGoodsOrServices": false, + "isWebApplication": false, + "privilegeLevel": "", + "threats": [] + } + }, + { + "position": { + "x": 590, + "y": 40 + }, + "size": { + "width": 60, + "height": 60 + }, + "attrs": { + "text": { + "text": "Test" + }, + "body": { + "stroke": "#333333", + "strokeWidth": 1.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "process", + "id": "ad6ddc79-3b28-4d1f-9452-d1f2164df7ed", + "zIndex": 16, + "data": { + "type": "tm.Process", + "name": "Test", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "handlesCardPayment": false, + "handlesGoodsOrServices": false, + "isWebApplication": false, + "privilegeLevel": "", + "threats": [] + } + }, + { + "position": { + "x": 700, + "y": 40 + }, + "size": { + "width": 60, + "height": 60 + }, + "attrs": { + "text": { + "text": "Image\n Scan" + }, + "body": { + "stroke": "red", + "strokeWidth": 2.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "process", + "id": "8e6a2823-71f4-4b01-ad52-29760fcb6f5c", + "zIndex": 17, + "data": { + "type": "tm.Process", + "name": "Image\n Scan", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": true, + "handlesCardPayment": false, + "handlesGoodsOrServices": false, + "isWebApplication": false, + "privilegeLevel": "", + "threats": [ + { + "id": "d476f90d-6065-4c80-9823-c0d3f680c13d", + "title": "Supply Chain Risks", + "status": "Open", + "severity": "Medium", + "type": "Spoofing", + "description": "Compromised third-party images or repositories can introduce vulnerabilities.\n\n", + "mitigation": "Only pull images from trusted sources and verified repositories (e.g., Docker Hub, private registries).\nUse signing mechanisms (e.g., Docker Content Trust) to ensure image integrity and authenticity.\nRegularly monitor for vulnerabilities in third-party images and dependencies.", + "modelType": "STRIDE", + "new": false, + "number": 7, + "score": "" + } + ] + } + }, + { + "position": { + "x": 440, + "y": 390 + }, + "size": { + "width": 180, + "height": 90 + }, + "attrs": { + "text": { + "text": "SonarCube\n code\n analysis" + }, + "body": { + "stroke": "#333333", + "strokeWidth": 1.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "process", + "id": "c4f1e3e3-78ca-4d11-b3f9-a3382b49e441", + "zIndex": 18, + "data": { + "type": "tm.Process", + "name": "SonarCube\n code\n analysis", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "handlesCardPayment": false, + "handlesGoodsOrServices": false, + "isWebApplication": false, + "privilegeLevel": "", + "threats": [] + } + }, + { + "position": { + "x": 775, + "y": 270 + }, + "size": { + "width": 60, + "height": 60 + }, + "attrs": { + "text": { + "text": "DAST" + }, + "body": { + "stroke": "red", + "strokeWidth": 2.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "process", + "id": "68fe9fd1-b6a6-40a5-a3a0-c67831d8d448", + "zIndex": 19, + "data": { + "type": "tm.Process", + "name": "DAST", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": true, + "handlesCardPayment": false, + "handlesGoodsOrServices": false, + "isWebApplication": false, + "privilegeLevel": "", + "threats": [ + { + "id": "252e144f-6cbd-4561-9adc-6409eceb74bf", + "title": "False Positives/Negatives", + "status": "Open", + "severity": "Medium", + "type": "Repudiation", + "description": " Inaccurate results can lead to misprioritization of vulnerabilities.", + "mitigation": "Use multiple DAST tools to cross-verify findings and reduce false positives.\nImplement a manual review process for high-risk areas to confirm vulnerabilities.\nRegularly tune and configure DAST tools for the specific application context.", + "modelType": "STRIDE", + "new": false, + "number": 4, + "score": "" + }, + { + "id": "c7e538f4-400b-43bd-a5e4-8bb0790c4ccd", + "title": "Insufficient Remediation Processes", + "status": "Open", + "severity": "Medium", + "type": "Repudiation", + "description": "Identified vulnerabilities may not be remediated in a timely manner.\n", + "mitigation": "Establish a clear workflow for handling identified vulnerabilities, including prioritization criteria.\nUse automated ticketing systems to track remediation progress.\nConduct regular meetings to review findings and follow up on remediation efforts.", + "modelType": "STRIDE", + "new": false, + "number": 5, + "score": "" + } + ] + } + }, + { + "position": { + "x": 890, + "y": 135 + }, + "size": { + "width": 60, + "height": 60 + }, + "attrs": { + "text": { + "text": "Security \nGate" + }, + "body": { + "stroke": "red", + "strokeWidth": 2.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "process", + "id": "8d392677-5a45-451e-a696-569ed38caeb1", + "zIndex": 20, + "data": { + "type": "tm.Process", + "name": "Security \nGate", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": true, + "handlesCardPayment": false, + "handlesGoodsOrServices": false, + "isWebApplication": false, + "privilegeLevel": "", + "threats": [ + { + "id": "20dc165b-07dc-4210-b449-8871cdaedaff", + "title": "New STRIDE threat", + "status": "Open", + "severity": "Medium", + "type": "Spoofing", + "description": "Provide a description for this threat", + "mitigation": "Provide remediation for this threat or a reason if status is N/A", + "modelType": "STRIDE", + "new": true, + "number": 0, + "score": "" + } + ] + } + }, + { + "position": { + "x": 1060, + "y": 170 + }, + "size": { + "width": 120, + "height": 60 + }, + "attrs": { + "text": { + "text": "DockerHub \nrepository \ncontainer" + }, + "topLine": { + "strokeWidth": 1.5, + "strokeDasharray": null + }, + "bottomLine": { + "strokeWidth": 1.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "store", + "id": "acfc06aa-1ea1-4f07-97c5-14bde75bceee", + "zIndex": 21, + "data": { + "type": "tm.Store", + "name": "DockerHub \nrepository \ncontainer", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isALog": false, + "isEncrypted": false, + "isSigned": false, + "storesCredentials": false, + "storesInventory": false, + "threats": [] + } + }, + { + "position": { + "x": 910, + "y": 250 + }, + "size": { + "width": 60, + "height": 60 + }, + "attrs": { + "text": { + "text": "Deploy" + }, + "body": { + "stroke": "#333333", + "strokeWidth": 1.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "process", + "id": "0181fcee-4b21-4cff-ba97-bd942439b801", + "zIndex": 22, + "data": { + "type": "tm.Process", + "name": "Deploy", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "handlesCardPayment": false, + "handlesGoodsOrServices": false, + "isWebApplication": false, + "privilegeLevel": "", + "threats": [] + } + }, + { + "position": { + "x": 715, + "y": 420 + }, + "size": { + "width": 120, + "height": 60 + }, + "attrs": { + "text": { + "text": "Sonarcube Database" + }, + "topLine": { + "strokeWidth": 1.5, + "strokeDasharray": null + }, + "bottomLine": { + "strokeWidth": 1.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "store", + "id": "1ab80526-c535-471e-86c6-29a23d0b7383", + "zIndex": 23, + "data": { + "type": "tm.Store", + "name": "Sonarcube Database", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isALog": false, + "isEncrypted": false, + "isSigned": false, + "storesCredentials": false, + "storesInventory": false, + "threats": [] + } + }, + { + "position": { + "x": 340, + "y": 200 + }, + "size": { + "width": 120, + "height": 60 + }, + "attrs": { + "text": { + "text": "GIT repository" + }, + "topLine": { + "strokeWidth": 1.5, + "strokeDasharray": null + }, + "bottomLine": { + "strokeWidth": 1.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "store", + "id": "ed0483e6-5d54-4ba5-9932-58423f8d5b08", + "zIndex": 24, + "data": { + "type": "tm.Store", + "name": "GIT repository", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": false, + "isALog": false, + "isEncrypted": false, + "isSigned": false, + "storesCredentials": false, + "storesInventory": false, + "threats": [] + } + }, + { + "position": { + "x": -89, + "y": 250 + }, + "size": { + "width": 112.5, + "height": 60 + }, + "attrs": { + "text": { + "text": "Developer\n Local \nenvironment" + } + }, + "visible": true, + "shape": "td-text-block", + "id": "66637595-4244-4ab1-bb8e-3e3f416b3d3c", + "zIndex": 25, + "data": { + "type": "tm.Text", + "name": "Developer\n Local \nenvironment", + "hasOpenThreats": false + } + }, + { + "position": { + "x": 1180, + "y": 250 + }, + "size": { + "width": 112.5, + "height": 60 + }, + "attrs": { + "text": { + "text": "Registry\nBoundary" + } + }, + "visible": true, + "shape": "td-text-block", + "id": "3000b74a-7bd2-40e4-8a49-1cabf6564823", + "zIndex": 26, + "data": { + "type": "tm.Text", + "name": "Registry\nBoundary", + "hasOpenThreats": false + } + }, + { + "position": { + "x": 510, + "y": 220 + }, + "size": { + "width": 110, + "height": 110 + }, + "attrs": { + "text": { + "text": "Fetch \nDependencies" + }, + "body": { + "stroke": "red", + "strokeWidth": 2.5, + "strokeDasharray": null + } + }, + "visible": true, + "shape": "process", + "id": "c03ba96e-c555-4c26-928a-9fb2dbc05b1d", + "zIndex": 27, + "data": { + "type": "tm.Process", + "name": "Fetch \nDependencies", + "description": "", + "outOfScope": false, + "reasonOutOfScope": "", + "hasOpenThreats": true, + "handlesCardPayment": false, + "handlesGoodsOrServices": false, + "isWebApplication": false, + "privilegeLevel": "", + "threats": [ + { + "id": "eebe005c-1b17-43b7-b120-183be6e361f2", + "title": "A Dependency fetch to the app is compromised", + "status": "Open", + "severity": "Medium", + "type": "Spoofing", + "description": "An popular opensource dependency used by the application gets compromised by an attacker. The attacker implants bitcoin mining software into the dependency so that consuming applications will mine bitcoin for the attacker", + "mitigation": "Ensure automated dependency analysis is being performed on application dependencies to detect dependencies known to have been compromised\nEnsure lock files are being used so that builds repeatedly use the same version of a dependency until it is explicitly upgraded\nEnable and use threat detection such as GuardDuty to detect anomolies in patterns of service operation", + "modelType": "STRIDE", + "new": false, + "number": 3, + "score": "" + } + ] + } + } + ], + "description": "CI pipeline for DevSecOps lab" + } + ], + "diagramTop": 1, + "reviewer": "", + "threatTop": 8 + } +}