Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions devsecops-demo/Dockerfile-01
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FROM alpine:3.14.0
RUN echo "testuser:x:10999:10999:,,,:/home/testuser:/bin/bash" >> /etc/passwd && echo "testuser::18761:0:99999:7:::" >> /etc/shadow
129 changes: 129 additions & 0 deletions devsecops-demo/Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

189 changes: 189 additions & 0 deletions devsecops-demo/example-02.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
resource "azurerm_resource_group" "myresourcegroup" {
name = "${var.prefix}-workshop"
location = var.location

tags = {
environment = "Production"
}
}

resource "azurerm_virtual_network" "vnet" {
name = "${var.prefix}-vnet"
location = azurerm_resource_group.myresourcegroup.location
address_space = [var.address_space]
resource_group_name = azurerm_resource_group.myresourcegroup.name
}

resource "azurerm_subnet" "subnet" {
name = "${var.prefix}-subnet"
virtual_network_name = azurerm_virtual_network.vnet.name
resource_group_name = azurerm_resource_group.myresourcegroup.name
address_prefixes = [var.subnet_prefix]
}

resource "azurerm_network_security_group" "catapp-sg" {
name = "${var.prefix}-sg"
location = var.location
resource_group_name = azurerm_resource_group.myresourcegroup.name

security_rule {
name = "HTTP"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "*"
destination_address_prefix = "*"
}

security_rule {
name = "HTTPS"
priority = 102
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "*"
destination_address_prefix = "*"
}

security_rule {
name = "SSH"
priority = 101
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}

Check failure

Code scanning / checkov

Ensure that SSH access is restricted from the internet Error

Ensure that SSH access is restricted from the internet

Check failure

Code scanning / checkov

Ensure that HTTP (port 80) access is restricted from the internet Error

Ensure that HTTP (port 80) access is restricted from the internet
Comment on lines +24 to +64

Check failure

Code scanning / defsec

An inbound network security rule allows traffic from /0. Error

Security group rule allows ingress from public internet.
Comment on lines +24 to +64

Check failure

Code scanning / defsec

An inbound network security rule allows traffic from /0. Error

Security group rule allows ingress from public internet.
Comment on lines +24 to +64

Check failure

Code scanning / defsec

An inbound network security rule allows traffic from /0. Error

Security group rule allows ingress from public internet.
Comment on lines +24 to +64

Check failure

Code scanning / defsec

SSH access should not be accessible from the Internet, should be blocked on port 22 Error

Security group rule allows ingress to SSH port from multiple public internet addresses.

resource "azurerm_network_interface" "catapp-nic" {
name = "${var.prefix}-catapp-nic"
location = var.location
resource_group_name = azurerm_resource_group.myresourcegroup.name

ip_configuration {
name = "${var.prefix}ipconfig"
subnet_id = azurerm_subnet.subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.catapp-pip.id
}
}

Check notice

Code scanning / checkov

Ensure that Network Interfaces don't use public IPs Note

Ensure that Network Interfaces don't use public IPs

resource "azurerm_network_interface_security_group_association" "catapp-nic-sg-ass" {
network_interface_id = azurerm_network_interface.catapp-nic.id
network_security_group_id = azurerm_network_security_group.catapp-sg.id
}

resource "azurerm_public_ip" "catapp-pip" {
name = "${var.prefix}-ip"
location = var.location
resource_group_name = azurerm_resource_group.myresourcegroup.name
allocation_method = "Dynamic"
domain_name_label = "${var.prefix}-meow"
}

resource "azurerm_virtual_machine" "catapp" {
name = "${var.prefix}-meow"
location = var.location
resource_group_name = azurerm_resource_group.myresourcegroup.name
vm_size = var.vm_size

network_interface_ids = [azurerm_network_interface.catapp-nic.id]
delete_os_disk_on_termination = "true"

storage_image_reference {
publisher = var.image_publisher
offer = var.image_offer
sku = var.image_sku
version = var.image_version
}

storage_os_disk {
name = "${var.prefix}-osdisk"
managed_disk_type = "Standard_LRS"
caching = "ReadWrite"
create_option = "FromImage"
}

os_profile {
computer_name = var.prefix
admin_username = var.admin_username
admin_password = var.admin_password
}

os_profile_linux_config {
disable_password_authentication = false
}

tags = {}

# Added to allow destroy to work correctly.
depends_on = [azurerm_network_interface_security_group_association.catapp-nic-sg-ass]
}

Check notice

Code scanning / checkov

Ensure that virtual machines are backed up using Azure Backup Note

Ensure that virtual machines are backed up using Azure Backup

Check notice

Code scanning / checkov

Ensure that Microsoft Antimalware is configured to automatically updates for Virtual Machines Note

Ensure that Microsoft Antimalware is configured to automatically updates for Virtual Machines

Check notice

Code scanning / checkov

Ensure Azure Instance does not use basic authentication(Use SSH Key Instead) Note

Ensure Azure Instance does not use basic authentication(Use SSH Key Instead)
Comment on lines +92 to +129

Check failure

Code scanning / defsec

Password authentication should be disabled on Azure virtual machines Error

Linux virtual machine allows password authentication.

# We're using a little trick here so we can run the provisioner without
# destroying the VM. Do not do this in production.

# If you need ongoing management (Day N) of your virtual machines a tool such
# as Chef or Puppet is a better choice. These tools track the state of
# individual files and can keep them in the correct configuration.

# Here we do the following steps:
# Sync everything in files/ to the remote VM.
# Set up some environment variables for our script.
# Add execute permissions to our scripts.
# Run the deploy_app.sh script.
resource "null_resource" "configure-cat-app" {
depends_on = [
azurerm_virtual_machine.catapp,
]

# Terraform 0.11
# triggers {
# build_number = "${timestamp()}"
# }

# Terraform 0.12
triggers = {
build_number = timestamp()
}

provisioner "file" {
source = "files/"
destination = "/home/${var.admin_username}/"

connection {
type = "ssh"
user = var.admin_username
password = var.admin_password
host = azurerm_public_ip.catapp-pip.fqdn
}
}

provisioner "remote-exec" {
inline = [
"sudo apt -y update",
"sleep 15",
"sudo apt -y update",
"sudo apt -y install apache2",
"sudo systemctl start apache2",
"sudo chown -R ${var.admin_username}:${var.admin_username} /var/www/html",
"chmod +x *.sh",
"PLACEHOLDER=${var.placeholder} WIDTH=${var.width} HEIGHT=${var.height} PREFIX=${var.prefix} ./deploy_app.sh",
]

connection {
type = "ssh"
user = var.admin_username
password = var.admin_password
host = azurerm_public_ip.catapp-pip.fqdn
}
}
}
2 changes: 2 additions & 0 deletions devsecops-demo/insecure-01.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
let injection = "Hello, security vulnerabilities!";
eval(`console.log(\"${injection}\");`);
26 changes: 26 additions & 0 deletions devsecops-demo/insecure-01.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#Commented out sample to pass scanning

import hashlib
print("I am very insecure. Bandit thinks so too.")
#B110
xs=[1,2,3,4,5,6,7,8]
try:
print(xs[7])
print(xs[8])
except: pass

Check notice

Code scanning / CodeQL

Except block handles 'BaseException' Note

Except block directly handles BaseException.

Copilot Autofix

AI 2 days ago

In general, to fix this issue you should avoid bare except: clauses and avoid catching BaseException directly. Instead, catch the specific exception types you actually expect, and allow KeyboardInterrupt and SystemExit (and other unexpected critical exceptions) to propagate.

For this specific file, the first try block at lines 7–10 is at risk. Accessing xs[7] and xs[8] can raise IndexError. We can make the handling explicit by replacing except: with except IndexError: so that only index errors are caught and quietly ignored, while KeyboardInterrupt and SystemExit continue to propagate normally. This preserves existing behavior (ignoring index errors) but removes the overly broad exception handling. The second try block on lines 14–16 is not part of the reported finding; it also uses except: but its behavior (continuing on any error while iterating) depends on catching TypeError. Changing that could alter behavior, and CodeQL did not flag that line in the prompt, so we will leave it unchanged.

No new imports or helper methods are required. The only change is narrowing the exception type in the first except clause in devsecops-demo/insecure-01.py.

Suggested changeset 1
devsecops-demo/insecure-01.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/devsecops-demo/insecure-01.py b/devsecops-demo/insecure-01.py
--- a/devsecops-demo/insecure-01.py
+++ b/devsecops-demo/insecure-01.py
@@ -7,7 +7,7 @@
 try:
     print(xs[7])
     print(xs[8])
-except: pass
+except IndexError: pass
 
 ys=[1, 2, None, None]
 for y in ys:
EOF
@@ -7,7 +7,7 @@
try:
print(xs[7])
print(xs[8])
except: pass
except IndexError: pass

ys=[1, 2, None, None]
for y in ys:
Copilot is powered by AI and may make mistakes. Always verify output.

Check notice

Code scanning / CodeQL

Empty except Note

'except' clause does nothing but pass and there is no explanatory comment.

Copilot Autofix

AI 2 days ago

In general, empty except blocks should be replaced with handlers that (a) catch specific exception types instead of bare except:, and (b) do something meaningful: log the error, clean up resources, re‑raise, or otherwise handle the condition. Swallowing all exceptions with pass hides failures and complicates debugging.

For this snippet, the code inside the first try block is indexing into a fixed list xs. The likely error is IndexError when accessing xs[8]. To fix the issue without changing the observable functionality too much, we can:

  • Replace the bare except: with except IndexError as exc:.
  • Inside the handler, print an informative message including the exception, instead of silently passing.

This preserves that the program continues after an indexing failure but no longer hides the reason. No new imports are required, and only lines around the except statement in devsecops-demo/insecure-01.py need to be changed.

Suggested changeset 1
devsecops-demo/insecure-01.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/devsecops-demo/insecure-01.py b/devsecops-demo/insecure-01.py
--- a/devsecops-demo/insecure-01.py
+++ b/devsecops-demo/insecure-01.py
@@ -7,7 +7,8 @@
 try:
     print(xs[7])
     print(xs[8])
-except: pass
+except IndexError as exc:
+    print(f"Index error while accessing xs: {exc}")
 
 ys=[1, 2, None, None]
 for y in ys:
EOF
@@ -7,7 +7,8 @@
try:
print(xs[7])
print(xs[8])
except: pass
except IndexError as exc:
print(f"Index error while accessing xs: {exc}")

ys=[1, 2, None, None]
for y in ys:
Copilot is powered by AI and may make mistakes. Always verify output.

Check warning

Code scanning / Bandit

Try, Except, Pass detected. Warning

Try, Except, Pass detected.

ys=[1, 2, None, None]
for y in ys:
try:
print(str(y+3)) #TypeErrors ahead
except: continue #not how to handle them

Check notice

Code scanning / CodeQL

Except block handles 'BaseException' Note

Except block directly handles BaseException.

Copilot Autofix

AI 2 days ago

In general, to fix this issue, replace bare except: (or except BaseException:) with handlers for more specific exception classes, most commonly except Exception: or a narrower subset, and handle SystemExit/KeyboardInterrupt separately if they truly need to be caught. This ensures that program termination and user interrupts are not silently swallowed.

For this file, there are two bare except: blocks:

  • Lines 7–10: accesses xs[7] and xs[8], which may raise IndexError.
  • Lines 14–16: does str(y+3) where y may be None, which may raise TypeError.

To preserve behaviour (ignore the error and continue) while avoiding catching KeyboardInterrupt/SystemExit, we should:

  • Narrow the first handler to except Exception: (or even more specific IndexError:). Since the intent is simply “ignore indexing errors”, Exception is sufficient and safer than a bare except:.
  • Narrow the second handler to except Exception: (or more specific TypeError:) so that KeyboardInterrupt and SystemExit are not caught, but type errors still cause the loop to continue as before.

No new imports or helper functions are needed. Only the two except: lines must be changed in devsecops-demo/insecure-01.py.


Suggested changeset 1
devsecops-demo/insecure-01.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/devsecops-demo/insecure-01.py b/devsecops-demo/insecure-01.py
--- a/devsecops-demo/insecure-01.py
+++ b/devsecops-demo/insecure-01.py
@@ -7,13 +7,13 @@
 try:
     print(xs[7])
     print(xs[8])
-except: pass
+except Exception: pass
 
 ys=[1, 2, None, None]
 for y in ys:
     try:
         print(str(y+3)) #TypeErrors ahead
-    except: continue #not how to handle them
+    except Exception: continue #not how to handle them
 
 #some imports
 import telnetlib
EOF
@@ -7,13 +7,13 @@
try:
print(xs[7])
print(xs[8])
except: pass
except Exception: pass

ys=[1, 2, None, None]
for y in ys:
try:
print(str(y+3)) #TypeErrors ahead
except: continue #not how to handle them
except Exception: continue #not how to handle them

#some imports
import telnetlib
Copilot is powered by AI and may make mistakes. Always verify output.

Check warning

Code scanning / Bandit

Try, Except, Continue detected. Warning

Try, Except, Continue detected.

#some imports
import telnetlib

Check notice

Code scanning / CodeQL

Unused import Note

Import of 'telnetlib' is not used.

Copilot Autofix

AI 2 days ago

To fix an unused import, you remove the import statement for the module that is not referenced anywhere in the file. This reduces clutter and avoids misleading readers about dependencies.

In this case, within devsecops-demo/insecure-01.py, the line import telnetlib at line 19 is unused. The best fix that does not change existing functionality is simply to delete this line and leave the rest of the file intact. No additional methods, imports, or definitions are required, and no other code needs to be updated because nothing references telnetlib.

Concretely:

  • Edit devsecops-demo/insecure-01.py.
  • Remove line 19 (import telnetlib), leaving the surrounding code unchanged.
  • Keep import ftplib as-is, since that import is not part of this specific report.
Suggested changeset 1
devsecops-demo/insecure-01.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/devsecops-demo/insecure-01.py b/devsecops-demo/insecure-01.py
--- a/devsecops-demo/insecure-01.py
+++ b/devsecops-demo/insecure-01.py
@@ -16,7 +16,6 @@
     except: continue #not how to handle them
 
 #some imports
-import telnetlib
 import ftplib
 
 #B303 and B324
EOF
@@ -16,7 +16,6 @@
except: continue #not how to handle them

#some imports
import telnetlib
import ftplib

#B303 and B324
Copilot is powered by AI and may make mistakes. Always verify output.
import ftplib

Check notice

Code scanning / CodeQL

Unused import Note

Import of 'ftplib' is not used.

Copilot Autofix

AI 2 days ago

To fix an unused import, the general approach is to remove the import statement for any module that is not referenced in the file. This reduces unnecessary dependencies and makes the code clearer.

In this case, the single best fix without changing functionality is to delete the import ftplib line on line 20 in devsecops-demo/insecure-01.py. No other code changes are needed, since nothing in the snippet uses ftplib. The existing hashlib usages and other code remain untouched.

Suggested changeset 1
devsecops-demo/insecure-01.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/devsecops-demo/insecure-01.py b/devsecops-demo/insecure-01.py
--- a/devsecops-demo/insecure-01.py
+++ b/devsecops-demo/insecure-01.py
@@ -17,7 +17,6 @@
 
 #some imports
 import telnetlib
-import ftplib
 
 #B303 and B324
 s = b"I am a string"
EOF
@@ -17,7 +17,6 @@

#some imports
import telnetlib
import ftplib

#B303 and B324
s = b"I am a string"
Copilot is powered by AI and may make mistakes. Always verify output.

#B303 and B324
s = b"I am a string"
print("MD5: " +hashlib.md5(s).hexdigest())

Check warning

Code scanning / Bandit

Use of weak MD5 hash for security. Consider usedforsecurity=False Warning

Use of weak MD5 hash for security. Consider usedforsecurity=False
print("SHA1: " +hashlib.sha1(s).hexdigest())

Check warning

Code scanning / Bandit

Use of weak SHA1 hash for security. Consider usedforsecurity=False Warning

Use of weak SHA1 hash for security. Consider usedforsecurity=False
print("SHA256: " +hashlib.sha256(s).hexdigest())
Loading
Loading