Secure Software Design- Lecture 11
Secure Software Design- Lecture 11
Today’s Agenda
1. Code Security testing and review methods
2. Description , tools , advantages and
disadvantages of each
3. SAST ?
Code Security Review
• Used for identifying , assessing and mitigating
vulnerabilities in software system
• Helps ensure the code is secure against potential
attacks and follow best practices for secure coding
Code Security testing methods
• SAST
• DAST
• Manual code review
• Peer code review
• Fuzz testing
• Penetration testing
• Security Unit testing
• IAST
• SCA
• Security Regression testing
Static Code Analysis (Static Application Security Testing - SAST)
Static Code Analysis (SAST) Pre-execution Catches vulnerabilities early Can produce false positives
Dynamic Code Analysis Detects runtime
Runtime Limited to running code
(DAST) vulnerabilities
Time-consuming, requires
Manual Code Review Pre-execution Detects logic flaws
expertise
Prevents reintroduction of
Security Regression Testing Pre-execution Needs careful maintenance
bugs
Static Code Analysis
• static code analysis as the process of examining
source code before it’s run to detect vulnerabilities,
bugs, and compliance issues.
• early detection and as part of a secure SDLC,
allowing developers to fix issues without the
overhead of runtime debugging.
SAST (Static Application Security
Testing)
• Subset of static analysis focused on detecting
security vulnerabilities, such as SQL injection, cross-
site scripting (XSS), buffer overflows, etc.
Common Vulnerabilities Detected by
SAST with Coding Examples
• Lets see come coding examples
Example 1: SQL Injection
• Vulnerability: When an application dynamically
builds SQL queries with user inputs, attackers may
inject malicious SQL code.
import sqlite3
def get_user_data(user_id):
conn = sqlite3.connect("database.db")
cursor = conn.cursor()
query = "SELECT * FROM users WHERE id = " + user_id
cursor.execute(query)
return cursor.fetchall()
If an attacker enters 1 OR 1=1, the query becomes:
SELECT * FROM users WHERE id = 1 OR 1=1
Fix
def get_user_data(user_id):
conn = sqlite3.connect("database.db")
cursor = conn.cursor()
query = "SELECT * FROM users WHERE id = ?"
cursor.execute(query, (user_id,))
return cursor.fetchall()
Fix explanation
Example 2: Command Injection
Vulnerability: Command injection occurs when
applications run system commands using user input,
allowing attackers to execute arbitrary commands.
import os
def list_files(directory):
os.system("ls " + directory)
Fix
import subprocess
def list_files(directory):
subprocess.run(["ls", directory], check=True)
Fix explanation
Example 3: Path Traversal
Vulnerability: Path traversal exploits improper file
access, allowing attackers to read sensitive files by
navigating the filesystem.
def read_file(filename):
with open("/home/user/data/" + filename, "r") as
file:
return file.read()
Fix
import os
def read_file(filename):
if ".." in filename:
raise ValueError("Invalid filename")
with open(os.path.join("/home/user/data",
filename), "r") as file:
return file.read()
Fix explanation
Example 4: Hardcoded Secrets
• Vulnerability: Hardcoded sensitive data (e.g., API
keys, passwords) in source code exposes them if
code is accessed or leaked.
• API_KEY = "my_secret_api_key"
Fix
import os
API_KEY = os.getenv("API_KEY")
Fix explanation
Example 5: Insufficient Logging and
Monitoring
Vulnerability: Lack of logging for failed authentication
or suspicious activities reduces visibility into potential
security events.
logging.basicConfig(level=logging.INFO)
def encrypt_data(data):
cipher = DES.new(b"12345678", DES.MODE_ECB)
return cipher.encrypt(data)
Fix
from Crypto.Cipher import AES
def encrypt_data(data):
cipher = AES.new(b"mysecretpassword",
AES.MODE_ECB)
return cipher.encrypt(data)
Fix explanation