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 type of issue you replace a bare except: (or except BaseException:) with more specific exception handlers, typically except Exception: for “normal” runtime errors, and optionally separate handlers for KeyboardInterrupt and SystemExit if you need special behavior. This ensures that program termination and user interrupts are not accidentally swallowed.

For this specific file:

  • At line 10, instead of except: pass, we should catch the precise error that can occur in the try block. The try block indexes into a list (xs[7] and xs[8]), so the realistic error is IndexError. Replacing the bare except: with except IndexError: preserves the idea of “ignoring out-of-range access” while no longer catching KeyboardInterrupt or SystemExit.
  • The except: continue inside the loop on lines 14–16 is not highlighted by CodeQL in the prompt, so we will leave it unchanged to respect the instruction to only fix the specific reported issue.

No new imports or helper methods are needed; we just update the exception clause on line 10 inside 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,8 @@
 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,8 @@
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, an empty except should either (a) catch only the specific exception type you expect and handle it appropriately (log, recover, or re-raise), or (b) if you truly intend to ignore it, document that explicitly in a comment and usually still narrow the exception type. Avoid bare except: because it hides programming errors like KeyboardInterrupt and SystemExit.

For this specific code, the only realistic exception from print(xs[7]); print(xs[8]) is IndexError when accessing xs[8]. The best fix that preserves existing behavior (the script continues even if the index is out of range) is:

  • Narrow the handler to except IndexError as exc:.
  • Log or print a short message including the exception so that failures are visible instead of silently ignored.

We only need to modify the try/except block around lines 7–10 in devsecops-demo/insecure-01.py. No extra imports are required since a simple print is enough for this demo script.

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 “Except block directly handles BaseException”, replace bare except: with explicit except Exception: or, better, with the specific exception types you expect, and never silently swallow KeyboardInterrupt or SystemExit. If you truly must catch all exceptions, re‑raise KeyboardInterrupt and SystemExit explicitly.

For this snippet, we can preserve existing behavior (ignore only the expected runtime errors) while no longer catching BaseException:

  • On lines 7–10, the code indexes into xs beyond its length. The only likely error is IndexError. Replace except: with except IndexError: and keep pass to maintain the “ignore index errors” semantics.
  • On lines 14–16, the code adds 3 to elements of ys, two of which are None. That raises TypeError. Replace except: with except TypeError: and keep continue so the loop still skips problematic elements.

No new imports or helper functions are needed; we only tighten the exception types in devsecops-demo/insecure-01.py at the two bare except: sites.

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,15 @@
 try:
     print(xs[7])
     print(xs[8])
-except: pass
+except IndexError:
+    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 TypeError:
+        continue  #not how to handle them
 
 #some imports
 import telnetlib
EOF
@@ -7,13 +7,15 @@
try:
print(xs[7])
print(xs[8])
except: pass
except IndexError:
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 TypeError:
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, remove the import statement for the unused module while leaving all other code intact. This eliminates the unnecessary dependency and satisfies the static analysis rule without altering runtime behavior.

In this specific case, remove the line import telnetlib from devsecops-demo/insecure-01.py. Keep the import ftplib line as-is, because we are not shown whether ftplib is used elsewhere in this file, and we should not modify or infer beyond the provided snippet. No new methods, definitions, or imports are required; the fix is purely the deletion of the unused telnetlib import on line 19.

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 the module that is not used anywhere in the file. This reduces unnecessary dependencies and slightly improves readability and load time.

In this specific case, in devsecops-demo/insecure-01.py, line 20 (import ftplib) should be removed, because there are no references to ftplib in the file. We leave the neighboring import hashlib and import telnetlib unchanged, since hashlib is clearly used and telnetlib might be intended for future or external use (and is not the one flagged). No additional methods, imports, or definitions are required; we are only deleting the unused import line.

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