Code Security
Version 0.1.0
Semgrep Engineering
January 2026
Note:
This document is mainly for agents and LLMs to follow when maintaining,
generating, or refactoring codebases with a focus on security best practices. Humans
may also find it useful, but guidance here is optimized for automation
and consistency by AI-assisted workflows.
Abstract
Comprehensive code security guide, designed for AI agents and LLMs.
Table of Contents
- SQL Injection — CRITICAL
- Command Injection — CRITICAL
- Cross-Site Scripting — CRITICAL
- XML External Entity — CRITICAL
- Path Traversal — CRITICAL
- Insecure Deserialization — CRITICAL
- Code Injection — CRITICAL
- Hardcoded Secrets — CRITICAL
- Memory Safety — CRITICAL
- Insecure Cryptography — HIGH
- Insecure Transport — HIGH
- 11.1 Use Secure Transport
- Server-Side Request Forgery — HIGH
- JWT Authentication — HIGH
- Cross-Site Request Forgery — HIGH
- Prototype Pollution — HIGH
- Unsafe Functions — HIGH
- Terraform AWS Security — HIGH
- Terraform Azure Security — HIGH
- Terraform GCP Security — HIGH
- Kubernetes Security — HIGH
- Docker Security — HIGH
- GitHub Actions Security — HIGH
- Regular Expression DoS — MEDIUM
- Race Conditions — MEDIUM
- Code Correctness — MEDIUM
- 25.1 Code Correctness
- Best Practices — LOW
- 26.1 Code Best Practices
- Performance — LOW
- Maintainability — LOW
- 28.1 Code Maintainability
1. SQL Injection
Impact: CRITICAL
SQL injection allows attackers to manipulate database queries, leading to data theft, modification, or deletion. OWASP Top 10.
1.1 Prevent SQL Injection
Impact: CRITICAL (Attackers can read, modify, or delete database data)
SQL injection allows attackers to manipulate database queries by injecting malicious SQL through user input. Never concatenate user input into SQL queries - always use parameterized queries or prepared statements.
Vulnerable patterns: String concatenation (+), format strings (.format(), %, f-strings, String.Format()), template literals with variables.
Incorrect: string concatenation
import psycopg2
def get_user(user_input):
conn = psycopg2.connect("dbname=test")
cur = conn.cursor()
query = "SELECT * FROM users WHERE name = '" + user_input + "'"
cur.execute(query)
Incorrect: format string
def get_user(user_input):
cur.execute("SELECT * FROM users WHERE id = {}".format(user_input))
Incorrect: f-string
def get_user(user_input):
cur.execute(f"SELECT * FROM users WHERE id = {user_input}")
Correct: parameterized query
def get_user(user_input):
conn = psycopg2.connect("dbname=test")
cur = conn.cursor()
cur.execute("SELECT * FROM users WHERE name = %s", [user_input])
Incorrect: template literal with variable
const { Pool } = require('pg')
const pool = new Pool()
async function getUser(userId) {
const sql = `SELECT * FROM users WHERE id = ${userId}`
const { rows } = await pool.query(sql)
return rows
}
Incorrect: string concatenation
async function getUser(userId) {
const sql = "SELECT * FROM users WHERE id = " + userId
const { rows } = await pool.query(sql)
return rows
}
Correct: parameterized query
async function getUser(userId) {
const sql = 'SELECT * FROM users WHERE id = $1'
const { rows } = await pool.query(sql, [userId])
return rows
}
Incorrect: string concatenation with Statement
public ResultSet getUser(String input) throws SQLException {
Statement stmt = connection.createStatement();
String sql = "SELECT * FROM users WHERE name = '" + input + "'";
return stmt.executeQuery(sql);
}
Incorrect: String.format
public ResultSet getUser(String input) throws SQLException {
Statement stmt = connection.createStatement();
return stmt.executeQuery(String.format("SELECT * FROM users WHERE name = '%s'", input));
}
Correct: PreparedStatement with parameters
public ResultSet getUser(String input) throws SQLException {
PreparedStatement pstmt = connection.prepareStatement(
"SELECT * FROM users WHERE name = ?");
pstmt.setString(1, input);
return pstmt.executeQuery();
}
Incorrect: string concatenation
func getUser(db *sql.DB, userInput string) {
query := "SELECT * FROM users WHERE name = '" + userInput + "'"
db.Query(query)
}
Incorrect: fmt.Sprintf
func getUser(db *sql.DB, email string) {
query := fmt.Sprintf("SELECT * FROM users WHERE email = '%s'", email)
db.Query(query)
}
Correct: parameterized query
func getUser(db *sql.DB, userInput string) {
db.Query("SELECT * FROM users WHERE name = $1", userInput)
}
Incorrect: string concatenation
def get_user(user_input)
conn = PG.connect(dbname: 'test')
query = "SELECT * FROM users WHERE name = '" + user_input + "'"
conn.exec(query)
end
Incorrect: string interpolation
def get_user(user_input)
conn = PG.connect(dbname: 'test')
conn.exec("SELECT * FROM users WHERE name = '#{user_input}'")
end
Correct: parameterized query
def get_user(user_input)
conn = PG.connect(dbname: 'test')
conn.exec_params('SELECT * FROM users WHERE name = $1', [user_input])
end
Incorrect: String.Format
public void GetUser(string userInput)
{
SqlCommand command = connection.CreateCommand();
command.CommandText = String.Format(
"SELECT * FROM users WHERE name = '{0}'", userInput);
}
Incorrect: string concatenation
public void GetUser(string userInput)
{
SqlCommand command = new SqlCommand(
"SELECT * FROM users WHERE name = '" + userInput + "'");
}
Correct: SqlParameter
public void GetUser(string userInput)
{
string sql = "SELECT * FROM users WHERE name = @Name";
SqlCommand command = new SqlCommand(sql);
command.Parameters.Add("@Name", SqlDbType.NVarChar);
command.Parameters["@Name"].Value = userInput;
}
References:
2. Command Injection
Impact: CRITICAL
OS command injection allows attackers to execute arbitrary system commands, leading to full system compromise. CWE-78.
2.1 Prevent Command Injection
Impact: CRITICAL (Remote code execution allowing attackers to run arbitrary commands on the host system)
Command injection occurs when untrusted input is passed to system shell commands. Attackers can execute arbitrary commands on the host system, potentially downloading malware, stealing data, or taking complete control of the server.
Incorrect: vulnerable to command injection via subprocess
import subprocess
import flask
app = flask.Flask(__name__)
@app.route("/ping")
def ping():
ip = flask.request.args.get("ip")
subprocess.run("ping " + ip, shell=True)
Correct: use array form without shell=True
import subprocess
import flask
app = flask.Flask(__name__)
@app.route("/ping")
def ping():
ip = flask.request.args.get("ip")
subprocess.run(["ping", ip])
Incorrect: vulnerable child_process with user input
const { exec } = require('child_process');
function runCommand(userInput) {
exec(`cat ${userInput}`, (error, stdout, stderr) => {
console.log(stdout);
});
}
Correct: use spawn with array arguments
const { spawn } = require('child_process');
function runCommand(userInput) {
const proc = spawn('cat', [userInput]);
proc.stdout.on('data', (data) => {
console.log(data.toString());
});
}
Incorrect: ProcessBuilder with user input via shell
public class CommandRunner {
public void runCommand(String userInput) throws IOException {
String[] cmd = {"/bin/bash", "-c", userInput};
ProcessBuilder builder = new ProcessBuilder(cmd);
Process proc = builder.start();
}
}
Correct: use ProcessBuilder with array arguments, no shell
public class CommandRunner {
public void runCommand(String filename) throws IOException {
ProcessBuilder builder = new ProcessBuilder("cat", filename);
Process proc = builder.start();
}
}
Incorrect: dangerous command with user input via stdin
import (
"fmt"
"os/exec"
)
func runCommand(userInput string) {
cmd := exec.Command("bash")
cmdWriter, _ := cmd.StdinPipe()
cmd.Start()
cmdString := fmt.Sprintf("echo %s", userInput)
cmdWriter.Write([]byte(cmdString + "\n"))
cmd.Wait()
}
Correct: use exec.Command with explicit arguments
import (
"os/exec"
)
func runCommand(filename string) {
cmd := exec.Command("cat", filename)
output, _ := cmd.Output()
println(string(output))
}
Incorrect: Shell methods with tainted input
require 'shell'
def read_file(params)
Shell.cat(params[:filename])
end
Correct: use hardcoded or validated paths
require 'shell'
def read_log
Shell.cat("/var/log/www/access.log")
end
References:
3. Cross-Site Scripting
Impact: CRITICAL
XSS allows attackers to inject malicious scripts into web pages, leading to session hijacking, defacement, or malware distribution. CWE-79.
3.1 Prevent Cross-Site Scripting (XSS)
Impact: CRITICAL (Client-side code execution, session hijacking, credential theft)
XSS occurs when untrusted data is included in web pages without proper validation or escaping. Attackers can execute scripts in victim's browser to steal cookies, session tokens, or other sensitive data.
Incorrect: vulnerable to XSS
function renderUserContent(userInput) {
document.body.innerHTML = '<div>' + userInput + '</div>';
}
Correct: use textContent or sanitization
function renderUserContent(userInput) {
const div = document.createElement('div');
div.textContent = userInput;
document.body.appendChild(div);
}
References:
Incorrect: user input in response
from flask import make_response, request
def search():
query = request.args.get("q")
return make_response(f"Results for: {query}")
Correct: escape output
from flask import make_response, request
from markupsafe import escape
def search():
query = request.args.get("q")
return make_response(f"Results for: {escape(query)}")
References:
Incorrect: request data in HttpResponse
from django.http import HttpResponse
def greet(request):
name = request.GET.get("name", "")
return HttpResponse(f"Hello, {name}!")
Correct: use template or escape
from django.http import HttpResponse
from django.utils.html import escape
def greet(request):
name = request.GET.get("name", "")
return HttpResponse(f"Hello, {escape(name)}!")
References:
Incorrect: writing request parameters directly
public class UserServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String name = req.getParameter("name");
resp.getWriter().write("<h1>Hello " + name + "</h1>");
}
}
Correct: encode output
import org.owasp.encoder.Encode;
public class UserServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String name = req.getParameter("name");
resp.getWriter().write("<h1>Hello " + Encode.forHtml(name) + "</h1>");
}
}
References:
Incorrect: writing user input to ResponseWriter
func greetHandler(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
template := "<html><body><h1>Hello %s</h1></body></html>"
w.Write([]byte(fmt.Sprintf(template, name)))
}
Correct: use html/template
func greetHandler(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
tmpl := template.Must(template.New("greet").Parse(
"<html><body><h1>Hello {{.}}</h1></body></html>"))
tmpl.Execute(w, name)
}
References:
Incorrect: echoing user input
<?php
function greet() {
$name = $_REQUEST['name'];
echo "Hello: " . $name;
}
Correct: use htmlspecialchars
<?php
function greet() {
$name = $_REQUEST['name'];
echo "Hello: " . htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
}
References:
4. XML External Entity
Impact: CRITICAL
XXE attacks exploit XML parsers to access local files, perform SSRF, or cause denial of service. CWE-611.
4.1 Prevent XML External Entity (XXE) Injection
Impact: CRITICAL (File disclosure, SSRF, denial of service)
XXE occurs when XML input containing a reference to an external entity is processed by a weakly configured XML parser. Attackers can access local files, perform SSRF, or cause DoS.
Incorrect: vulnerable to XXE
class BadDocumentBuilderFactory {
public void parseXml() throws ParserConfigurationException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.newDocumentBuilder();
}
}
Correct: XXE disabled
class GoodDocumentBuilderFactory {
public void parseXml() throws ParserConfigurationException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.newDocumentBuilder();
}
}
References:
Incorrect: vulnerable to XXE
def parse_xml():
from xml.etree import ElementTree
tree = ElementTree.parse('data.xml')
root = tree.getroot()
Correct: safe usage
def parse_xml():
import defusedxml.ElementTree as ElementTree
tree = ElementTree.parse('data.xml')
root = tree.getroot()
References:
Incorrect: vulnerable to XXE
var libxmljs = require("libxmljs");
module.exports.parseXml = function(req, res) {
libxmljs.parseXml(req.body, { noent: true, noblanks: true });
}
Correct: XXE disabled
var libxmljs = require("libxmljs");
module.exports.parseXml = function(req, res) {
libxmljs.parseXml(req.body, { noent: false, noblanks: true });
}
References:
Incorrect: vulnerable to XXE
public void ParseXml(string input) {
XmlReaderSettings rs = new XmlReaderSettings();
rs.DtdProcessing = DtdProcessing.Parse;
XmlReader myReader = XmlReader.Create(new StringReader(input), rs);
while (myReader.Read()) {
Console.WriteLine(myReader.Value);
}
}
Correct: XXE disabled
public void ParseXml(string input) {
XmlReaderSettings rs = new XmlReaderSettings();
rs.DtdProcessing = DtdProcessing.Prohibit;
XmlReader myReader = XmlReader.Create(new StringReader(input), rs);
while (myReader.Read()) {
Console.WriteLine(myReader.Value);
}
}
References:
Incorrect: vulnerable to XXE
import (
"fmt"
"github.com/lestrrat-go/libxml2/parser"
)
func parseXml() {
const s = `<!DOCTYPE d [<!ENTITY e SYSTEM "file:///etc/passwd">]><t>&e;</t>`
p := parser.New(parser.XMLParseNoEnt)
doc, err := p.ParseString(s)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(doc)
}
Correct: XXE disabled
import (
"fmt"
"github.com/lestrrat-go/libxml2/parser"
)
func parseXml() {
const s = `<!DOCTYPE d [<!ENTITY e SYSTEM "file:///etc/passwd">]><t>&e;</t>`
p := parser.New()
doc, err := p.ParseString(s)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(doc)
}
References:
5. Path Traversal
Impact: CRITICAL
Path traversal allows attackers to access files outside intended directories using sequences like "../". CWE-22.
5.1 Prevent Path Traversal
Impact: CRITICAL (Arbitrary file access, information disclosure, file manipulation)
Path traversal occurs when user input is used to construct file paths without proper validation, allowing attackers to access files outside intended directories using sequences like "../". This can lead to sensitive data exposure, arbitrary file reads/writes, and system compromise.
Incorrect: vulnerable to path traversal
def unsafe(request):
filename = request.POST.get('filename')
f = open(filename, 'r')
data = f.read()
f.close()
return HttpResponse(data)
Correct: static path
def safe(request):
filename = "/tmp/data.txt"
f = open(filename)
data = f.read()
f.close()
return HttpResponse(data)
References:
Incorrect: vulnerable to path traversal
const fs = require('fs');
function readUserFile(fileName) {
fs.readFile(fileName, (err, data) => {
if (err) throw err;
console.log(data);
});
}
Correct: safe with literal path
const fs = require('fs');
function readConfigFile() {
fs.readFile('config/settings.json', (err, data) => {
if (err) throw err;
console.log(data);
});
}
References:
Incorrect: vulnerable to path traversal
const path = require('path');
function getFile(entry) {
var extractPath = path.join(opts.path, entry.path);
return extractFile(extractPath);
}
Correct: resolve and enforce boundary
const path = require('path');
function getFileSafe(req, res) {
const baseDir = path.resolve(opts.path);
const resolved = path.resolve(baseDir, '.' + req.body.path);
if (!resolved.startsWith(baseDir + path.sep)) {
throw new Error('path traversal attempt');
}
return extractFile(resolved);
}
References:
Incorrect: vulnerable to path traversal
public class FileServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String image = request.getParameter("image");
File file = new File("static/images/", image);
if (!file.exists()) {
response.sendError(404);
}
}
}
Correct: sanitized with FilenameUtils
public class FileServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String image = request.getParameter("image");
File file = new File("static/images/", FilenameUtils.getName(image));
if (!file.exists()) {
response.sendError(404);
}
}
}
References:
Incorrect: Clean does not prevent traversal
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/file", func(w http.ResponseWriter, r *http.Request) {
filename := filepath.Clean(r.URL.Path)
filename = filepath.Join(root, strings.Trim(filename, "/"))
contents, err := ioutil.ReadFile(filename)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
w.Write(contents)
})
}
Correct: prefix with "/" before Clean
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/file", func(w http.ResponseWriter, r *http.Request) {
filename := path.Clean("/" + r.URL.Path)
filename = filepath.Join(root, strings.Trim(filename, "/"))
contents, err := ioutil.ReadFile(filename)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
w.Write(contents)
})
}
Best Practice: Use filepath.FromSlash(path.Clean("/"+strings.Trim(req.URL.Path, "/"))) or the SecureJoin function from github.com/cyphar/filepath-securejoin.
References:
Incorrect: vulnerable to path traversal/RFI
<?php
$user_input = $_GET["page"];
include($user_input);
?>
Correct: constant paths
<?php
include('templates/header.php');
require_once(CONFIG_DIR . '/settings.php');
?>
References:
Incorrect: vulnerable to path traversal
<?php
$data = $_GET["file"];
unlink("/storage/" . $data);
?>
Correct: constant path
<?php
unlink('/storage/cache/temp.txt');
?>
References:
6. Insecure Deserialization
Impact: CRITICAL
Deserializing untrusted data can lead to remote code execution, DoS, or authentication bypass. CWE-502.
6.1 Prevent Insecure Deserialization
Impact: CRITICAL (Remote code execution allowing attackers to run arbitrary code on the server)
Insecure deserialization occurs when untrusted data is used to abuse the logic of an application, inflict denial of service attacks, or execute arbitrary code. Objects can be serialized into strings and later loaded from strings, but deserialization of untrusted data can lead to remote code execution (RCE). Never deserialize data from untrusted sources. Use safer alternatives like JSON for data interchange.
Incorrect: using pickle with user input
import pickle
from base64 import b64decode
from flask import Flask, request
app = Flask(__name__)
@app.route('/', methods=['GET'])
def index():
user_obj = request.cookies.get('uuid')
return "Hey there! {}!".format(pickle.loads(b64decode(user_obj)))
Correct: use JSON or load from trusted file
import pickle
import json
@app.route("/ok")
def ok():
# Load from trusted local file
data = pickle.load(open('./config/settings.dat', "rb"))
# Or use JSON for untrusted data
user_data = json.loads(request.data)
return user_data
References:
Incorrect: using insecure deserialization libraries
var node_serialize = require("node-serialize")
module.exports.handler = function (req, res) {
var data = req.files.products.data.toString('utf8')
node_serialize.unserialize(data)
}
Correct: use JSON.parse for untrusted data
module.exports.handler = function (req, res) {
var data = req.body.toString('utf8')
var parsed = JSON.parse(data)
return parsed
}
References:
Incorrect: using ObjectInputStream to deserialize untrusted data
import java.io.InputStream;
import java.io.ObjectInputStream;
public class Deserializer {
public Object deserializeObject(InputStream receivedData) throws Exception {
ObjectInputStream in = new ObjectInputStream(receivedData);
return in.readObject();
}
}
Correct: use JSON or implement input validation
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.InputStream;
public class SafeDeserializer {
public MyClass deserialize(InputStream data) throws Exception {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(data, MyClass.class);
}
}
References:
Incorrect: using Marshal.load or YAML.load with user input
def bad_deserialization
data = params['data']
obj = Marshal.load(data)
yaml_data = params['yaml']
config = YAML.load(yaml_data)
end
Correct: use safe options or trusted data
def ok_deserialization
# Use YAML.safe_load for untrusted data
config = YAML.safe_load(params['yaml'])
# Load from trusted file
obj = YAML.load(File.read("config.yml"))
# Use JSON for untrusted data
data = JSON.parse(params['data'])
end
References:
Incorrect: using BinaryFormatter which is inherently insecure
using System.Runtime.Serialization.Formatters.Binary;
public class InsecureDeserialization {
public void Deserialize(string data) {
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(data));
object obj = formatter.Deserialize(stream);
}
}
Correct: use System.Text.Json or Newtonsoft with safe settings
using System.Text.Json;
public class SafeDeserialization {
public MyClass Deserialize(string json) {
return JsonSerializer.Deserialize<MyClass>(json);
}
}
References:
Incorrect: unserializing user-controlled data
<?php
$data = $_GET["data"];
$object = unserialize($data);
Correct: use JSON or hardcoded data
<?php
// Use json_decode for untrusted data
$object = json_decode($_GET["data"], true);
// Or use unserialize only with hardcoded strings
$object = unserialize('O:1:"a":1:{s:5:"value";s:3:"100";}');
References:
References:
7. Code Injection
Impact: CRITICAL
Code injection (eval, template injection) allows attackers to execute arbitrary code in the application context. CWE-94.
7.1 Prevent Code Injection
Impact: CRITICAL (Remote code execution via eval/exec)
Code injection vulnerabilities occur when an attacker can insert and execute arbitrary code within your application. This includes direct code evaluation (eval, exec), reflection-based attacks, and dynamic method invocation. These vulnerabilities can lead to complete system compromise, data theft, and remote code execution.
Incorrect: Python - eval with user input
def unsafe(request):
code = request.POST.get('code')
eval(code)
Correct: Python - avoid eval entirely, use safe alternatives
import ast
def safe_parse(user_expr):
# ast.literal_eval only allows literals (strings, numbers, tuples, lists, dicts, booleans, None)
return ast.literal_eval(user_expr)
# For math expressions, use a purpose-built parser instead of eval
Incorrect: JavaScript - eval with dynamic content
let dynamic = window.prompt()
eval(dynamic + 'possibly malicious code');
function evalSomething(something) {
eval(something);
}
Correct: JavaScript - avoid eval, use safe alternatives
// Instead of eval for JSON parsing:
const data = JSON.parse(jsonString);
// Instead of eval for dynamic property access:
const value = obj[propertyName];
// Instead of eval for math: use a sandboxed expression parser
Incorrect: Java - ScriptEngine injection
public class ScriptEngineSample {
private static ScriptEngineManager sem = new ScriptEngineManager();
private static ScriptEngine se = sem.getEngineByExtension("js");
public static void scripting(String userInput) throws ScriptException {
Object result = se.eval("test=1;" + userInput);
}
}
Correct: Java - static ScriptEngine evaluation
public class ScriptEngineSample {
public static void scriptingSafe() throws ScriptException {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("js");
String code = "var test=3;test=test*2;";
Object result = scriptEngine.eval(code);
}
}
Incorrect: Ruby - dangerous eval
b = params['something']
eval(b)
eval(params['cmd'])
Correct: Ruby - static eval
eval("def zen; 42; end")
class Thing
end
a = %q{def hello() "Hello there!" end}
Thing.module_eval(a)
Incorrect: PHP - code injection via eval/assert
$code = $_GET['code'];
eval($code);
$input = $_POST['input'];
assert($input); // assert() evaluates strings as code in PHP < 8.0
Correct: PHP - avoid eval, use structured alternatives
// Instead of eval for dynamic config, use a data format:
$config = json_decode(file_get_contents('config.json'), true);
// Instead of eval for templates, use a template engine (Twig, Blade)
8. Hardcoded Secrets
Impact: CRITICAL
Hardcoded credentials, API keys, and tokens in source code lead to unauthorized access when code is exposed. CWE-798.
8.1 Avoid Hardcoded Secrets
Impact: CRITICAL (Credential exposure and unauthorized access)
Hardcoded credentials, API keys, tokens, and other secrets in source code pose a critical security risk. When secrets are committed to version control, they can be exposed to unauthorized parties through repository access, leaked in public repositories or through data breaches, difficult to rotate without code changes and redeployment, and discovered by automated secret scanning tools used by attackers. Always use environment variables, secret managers, or secure vaults to provide credentials at runtime.
Incorrect: Python - hardcoded AWS credentials
import boto3
client("s3", aws_secret_access_key="jWnyxxxxxxxxxxxxxxxxX7ZQxxxxxxxxxxxxxxxx")
s3 = boto3.resource(
"s3",
aws_access_key_id="AKIAxxxxxxxxxxxxxxxx",
aws_secret_access_key="jWnyxxxxxxxxxxxxxxxxX7ZQxxxxxxxxxxxxxxxx",
region_name="us-east-1",
)
Correct: Python - AWS credentials from environment
import boto3
import os
key = os.environ.get("ACCESS_KEY_ID")
secret = os.environ.get("SECRET_ACCESS_KEY")
s3 = boto3.resource(
"s3",
aws_access_key_id=key,
aws_secret_access_key=secret,
region_name="us-east-1",
)
Incorrect: JavaScript - hardcoded JWT secret
const jsonwt = require('jsonwebtoken')
function signToken() {
const payload = {foo: 'bar'}
const token = jsonwt.sign(payload, 'my-secret-key')
return token
}
Correct: JavaScript - JWT secret from environment
const jsonwt = require('jsonwebtoken')
function signToken() {
const payload = {foo: 'bar'}
const secret = process.env.JWT_SECRET
const token = jsonwt.sign(payload, secret)
return token
}
Incorrect: JavaScript - hardcoded express-jwt secret
var jwt = require('express-jwt');
app.get('/protected', jwt({ secret: 'shhhhhhared-secret' }), function(req, res) {
if (!req.user.admin) return res.sendStatus(401);
res.sendStatus(200);
});
Correct: JavaScript - express-jwt secret from environment
var jwt = require('express-jwt');
app.get('/protected', jwt({ secret: process.env.JWT_SECRET }), function(req, res) {
if (!req.user.admin) return res.sendStatus(401);
res.sendStatus(200);
});
Incorrect: Python Flask - hardcoded SECRET_KEY
import flask
app = flask.Flask(__name__)
app.config["SECRET_KEY"] = '_5#y2L"F4Q8z\n\xec]/'
Correct: Python Flask - SECRET_KEY from environment
import os
import flask
app = flask.Flask(__name__)
app.config["SECRET_KEY"] = os.environ["SECRET_KEY"]
Incorrect: Python - empty password string
from models import UserProfile
def set_user_password(user_profile: UserProfile) -> None:
password = ""
user_profile.set_password(password)
user_profile.save()
Correct: Python - password from secure source
from models import UserProfile
def set_user_password(user_profile: UserProfile, password: str) -> None:
user_profile.set_password(password)
user_profile.save()
Incorrect: JavaScript - hardcoded Stripe token
const stripe = require('stripe');
const client = stripe('sk_test_20cbqx6v2hpftsbq203r36yqccazez');
Correct: JavaScript - Stripe token from environment
const stripe = require('stripe');
const client = stripe(process.env.STRIPE_SECRET_KEY);
Incorrect: Python - hardcoded GitHub token
import requests
headers = {"Authorization": "token ghp_emmtytndiqky5a98w0s98w36fakekey"}
response = requests.get("https://api.github.com/user", headers=headers)
Correct: Python - GitHub token from environment
import os
import requests
headers = {"Authorization": f"token {os.environ['GITHUB_TOKEN']}"}
response = requests.get("https://api.github.com/user", headers=headers)
9. Memory Safety
Impact: CRITICAL
Memory safety issues (buffer overflow, use-after-free) can lead to code execution or crashes. CWE-119, CWE-416.
9.1 Ensure Memory Safety
Impact: CRITICAL (Arbitrary code execution and data corruption)
Memory safety vulnerabilities are among the most critical security issues in software development. They can lead to arbitrary code execution, data corruption, denial of service, and information disclosure. This guide covers common memory safety issues in C/C++ including double-free, use-after-free, and buffer overflow vulnerabilities.
Freeing memory twice can cause memory corruption, crashes, or allow attackers to execute arbitrary code.
Incorrect:
int bad_code() {
char *var = malloc(sizeof(char) * 10);
free(var);
free(var); // Double free vulnerability
return 0;
}
Correct:
int safe_code() {
char *var = malloc(sizeof(char) * 10);
free(var);
var = NULL; // Set to NULL after free
free(var); // Safe: freeing NULL is a no-op
return 0;
}
Accessing memory after it has been freed can lead to crashes, data corruption, or code execution.
Incorrect:
typedef struct name {
char *myname;
void (*func)(char *str);
} NAME;
int bad_code() {
NAME *var;
var = (NAME *)malloc(sizeof(struct name));
free(var);
var->func("use after free"); // Accessing freed memory
return 0;
}
Correct:
typedef struct name {
char *myname;
void (*func)(char *str);
} NAME;
int safe_code() {
NAME *var;
var = (NAME *)malloc(sizeof(struct name));
free(var);
var = NULL; // Prevents accidental reuse
// Any access to var now causes immediate crash (easier to debug)
return 0;
}
Writing beyond buffer boundaries can overwrite adjacent memory, leading to crashes or code execution.
Incorrect:
void bad_code(char *user_input) {
char buffer[64];
strcpy(buffer, user_input); // No bounds checking
}
Correct:
void safe_code(char *user_input) {
char buffer[64];
snprintf(buffer, sizeof(buffer), "%s", user_input); // Bounds-checked, always null-terminates
}
Using user-controlled format strings can allow attackers to read or write arbitrary memory.
Incorrect:
void bad_printf(char *user_input) {
printf(user_input); // User controls format string
}
Correct:
void safe_printf(char *user_input) {
printf("%s", user_input); // Format string is fixed
}
10. Insecure Cryptography
Impact: HIGH
Weak hashing (MD5, SHA1), weak encryption (DES, RC4), or improper key management compromises data confidentiality. CWE-327.
10.1 Avoid Insecure Cryptography
Impact: HIGH (Data decryption and signature forgery)
Using weak or broken cryptographic algorithms puts sensitive data at risk. Attackers can exploit known vulnerabilities in deprecated algorithms to decrypt data, forge signatures, or predict "random" values.
Key vulnerabilities:
Incorrect: MD5/SHA1 hashing
import hashlib
hash_val = hashlib.md5(data).hexdigest()
hash_val = hashlib.sha1(data).hexdigest()
Correct: SHA256 hashing
import hashlib
hash_val = hashlib.sha256(data).hexdigest()
Incorrect: DES cipher
from Crypto.Cipher import DES
key = b'-8B key-'
cipher = DES.new(key, DES.MODE_CTR, counter=ctr)
Correct: AES cipher
from Crypto.Cipher import AES
key = b'Sixteen byte key'
cipher = AES.new(key, AES.MODE_EAX, nonce=nonce)
Incorrect: MD5 hashing
const crypto = require("crypto");
function hashPassword(pwtext) {
return crypto.createHash("md5").update(pwtext).digest("hex");
}
Correct: bcrypt for password hashing
const bcrypt = require("bcrypt");
async function hashPassword(pwtext) {
return bcrypt.hash(pwtext, 12);
}
async function verifyPassword(pwtext, hash) {
return bcrypt.compare(pwtext, hash);
}
Incorrect: MD5/SHA1 hashing
import java.security.MessageDigest;
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(password.getBytes());
byte[] hash = md5.digest();
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
Correct: BCrypt for password hashing
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String hash = encoder.encode(password);
boolean matches = encoder.matches(password, hash);
Incorrect: DES cipher
Cipher c = Cipher.getInstance("DES/ECB/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, k);
Correct: AES with GCM
Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
Incorrect: MD5 hashing
import (
"crypto/md5"
"fmt"
)
func hashData(data []byte) {
h := md5.New()
h.Write(data)
fmt.Printf("%x", h.Sum(nil))
}
Correct: SHA256 hashing
import (
"crypto/sha256"
"fmt"
)
func hashData(data []byte) {
h := sha256.New()
h.Write(data)
fmt.Printf("%x", h.Sum(nil))
}
Incorrect: DES cipher
import "crypto/des"
func encrypt() {
key := []byte("example key 1234")
block, _ := des.NewCipher(key[:8])
}
Correct: AES cipher
import "crypto/aes"
func encrypt() {
key := []byte("example key 12345678901234567890")
block, _ := aes.NewCipher(key[:32])
}
| Language | Weak Algorithm | Secure Alternative |
|---|---|---|
| Python | hashlib.md5, hashlib.sha1 | hashlib.sha256, hashlib.sha512 |
| Python | DES.new() | AES.new() with EAX/GCM mode |
| JavaScript | createHash("md5") | createHash("sha256") |
| Java | getInstance("MD5"), getInstance("SHA-1") | getInstance("SHA-512") |
| Java | getInstance("DES") | getInstance("AES/GCM/NoPadding") |
| Go | crypto/md5, crypto/sha1 | crypto/sha256, crypto/sha512 |
| Go | crypto/des | crypto/aes |
11. Insecure Transport
Impact: HIGH
Cleartext transmission, disabled certificate verification, or weak TLS exposes data in transit. CWE-319.
11.1 Use Secure Transport
Impact: HIGH (Exposure of sensitive data through cleartext transmission or improper certificate validation)
Insecure transport vulnerabilities occur when applications transmit sensitive data over unencrypted connections or when TLS/SSL certificate validation is disabled. This exposes data to man-in-the-middle (MITM) attacks where attackers can intercept, read, and modify communications. Key issues include:
Incorrect: HTTP requests without TLS
const http = require('http');
http.get('http://nodejs.org/dist/index.json', (res) => {
const { statusCode } = res;
});
Correct: HTTPS requests with TLS
const https = require('https');
https.get('https://nodejs.org/dist/index.json', (res) => {
const { statusCode } = res;
});
Incorrect: disabled TLS verification
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
var req = https.request({
host: '192.168.1.1',
port: 443,
path: '/',
method: 'GET',
rejectUnauthorized: false
});
Correct: TLS verification enabled
var req = https.request({
host: '192.168.1.1',
port: 443,
path: '/',
method: 'GET',
rejectUnauthorized: true
});
Incorrect: HTTP requests without TLS
func bad() {
resp, err := http.Get("http://example.com/")
}
Correct: HTTPS requests
func ok() {
resp, err := http.Get("https://example.com/")
}
Incorrect: disabled TLS verification
import (
"crypto/tls"
"net/http"
)
func bad() {
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
}
Correct: TLS verification enabled
func ok() {
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: false,
},
},
}
}
Incorrect: HTTP requests without TLS
import requests
requests.get("http://example.com")
Correct: HTTPS requests
import requests
requests.get("https://example.com")
Incorrect: disabled certificate verification
import requests
r = requests.get("https://example.com", verify=False)
Correct: certificate verification enabled
import requests
r = requests.get("https://example.com")
Incorrect: HTTP requests without TLS
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://openjdk.java.net/"))
.build();
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
Correct: HTTPS requests
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://openjdk.java.net/"))
.build();
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
Incorrect: disabled TLS verification via empty X509TrustManager
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(X509Certificate[] certs, String authType) { }
public void checkServerTrusted(X509Certificate[] certs, String authType) { }
}
Correct — Option A: Use the JVM default trust manager (preferred):
// HttpClient uses the JVM default SSLContext, which validates certificates properly
HttpClient client = HttpClient.newBuilder().build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/"))
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
Correct — Option B: Explicit SSLContext with default TrustManagerFactory (when custom configuration is needed):
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null); // uses the JVM default trust store
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
// Enable hostname verification
SSLParameters sslParams = new SSLParameters();
sslParams.setEndpointIdentificationAlgorithm("HTTPS");
HttpClient client = HttpClient.newBuilder()
.sslContext(sslContext)
.sslParameters(sslParams)
.build();
References:
Reference: https://nodejs.org/api/https.html, https://golang.org/pkg/crypto/tls/, https://docs.python.org/3/library/ssl.html
12. Server-Side Request Forgery
Impact: HIGH
SSRF allows attackers to make requests from the server to internal systems or cloud metadata endpoints. CWE-918.
12.1 Prevent Server-Side Request Forgery
Impact: HIGH (Attackers can make requests from the server to internal systems, cloud metadata endpoints, or external services)
Server-Side Request Forgery (SSRF) occurs when an attacker can make a server-side application send HTTP requests to an arbitrary domain of the attacker's choosing. This can be used to:
Incorrect: user input flows into URL host
from django.http import HttpResponse
import requests
def fetch_user_data(request):
host = request.POST.get('host')
user_id = request.POST.get('user_id')
response = requests.get(f"https://{host}/api/users/{user_id}")
return HttpResponse(response.content)
Correct: fixed host, user data only in path
from django.http import HttpResponse
import requests
def fetch_user_data(request):
user_id = request.POST.get('user_id')
response = requests.get(f"https://api.example.com/users/{user_id}")
return HttpResponse(response.content)
Incorrect: user input in URL
const express = require('express');
const axios = require('axios');
const app = express();
app.get('/fetch', async (req, res) => {
const url = req.query.url;
const response = await axios.get(url);
res.send(response.data);
});
Correct: fixed host, user data only in path
const express = require('express');
const axios = require('axios');
const app = express();
app.get('/fetch', async (req, res) => {
const resourceId = req.query.id;
const response = await axios.get(`https://api.example.com/resources/${resourceId}`);
res.send(response.data);
});
Incorrect: user-controlled URL
import java.net.URL;
import java.net.URLConnection;
import org.springframework.web.bind.annotation.RequestParam;
@RestController
public class FetchController {
@GetMapping("/fetch")
public byte[] fetchImage(@RequestParam("url") String imageUrl) throws Exception {
URL u = new URL(imageUrl);
URLConnection conn = u.openConnection();
return conn.getInputStream().readAllBytes();
}
}
Correct: fixed host, user data in path
import java.net.URL;
import org.springframework.web.bind.annotation.RequestParam;
@RestController
public class FetchController {
@GetMapping("/fetch")
public byte[] fetchImage(@RequestParam("id") String imageId) throws Exception {
String url = String.format("https://images.example.com/%s", imageId);
URL u = new URL(url);
return u.openConnection().getInputStream().readAllBytes();
}
}
Incorrect: user input in URL host
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
host := r.URL.Query().Get("host")
url := fmt.Sprintf("https://%s/api/data", host)
resp, _ := http.Get(url)
defer resp.Body.Close()
}
Correct: fixed host, user data in path
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
resourceId := r.URL.Query().Get("id")
url := fmt.Sprintf("https://api.example.com/data/%s", resourceId)
resp, _ := http.Get(url)
defer resp.Body.Close()
}
Incorrect: user input in URL
<?php
function fetchData() {
$url = $_GET['url'];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
?>
Correct: fixed host, user data in path
<?php
function fetchData() {
$resourceId = $_GET['id'];
$url = 'https://api.example.com/resources/' . $resourceId;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
?>
Incorrect: user input in HTTP request
require 'net/http'
def fetch_data
url = params[:url]
uri = URI(url)
Net::HTTP.get_response(uri)
end
Correct: fixed host, user data in path
require 'net/http'
def fetch_data
resource_id = params[:id]
uri = URI("https://api.example.com/resources/#{resource_id}")
Net::HTTP.get_response(uri)
end
References:
13. JWT Authentication
Impact: HIGH
JWT vulnerabilities include the "none" algorithm attack, weak secrets, and missing signature verification. CWE-347.
13.1 Secure JWT Authentication
Impact: HIGH (Authentication bypass and token forgery)
JSON Web Tokens (JWT) are widely used for authentication and authorization. However, improper implementation can lead to serious security vulnerabilities including authentication bypass and token forgery. The most critical JWT vulnerability is decoding tokens without verifying their signatures, which allows attackers to forge tokens with arbitrary claims, impersonate any user, or escalate privileges.
Related CWEs: CWE-287 (Improper Authentication), CWE-345 (Insufficient Verification of Data Authenticity), CWE-347 (Improper Verification of Cryptographic Signature).
Incorrect: JavaScript jsonwebtoken - decode without verify
const jwt = require('jsonwebtoken');
function getUserData(token) {
const decoded = jwt.decode(token, true);
if (decoded.isAdmin) {
return getAdminData();
}
}
Correct: JavaScript jsonwebtoken - use verify which returns decoded payload
const jwt = require('jsonwebtoken');
function getUserData(token, secretKey) {
const decoded = jwt.verify(token, secretKey);
if (decoded.isAdmin) {
return getAdminData();
}
}
Incorrect: Python PyJWT - verify_signature disabled
import jwt
def get_user_claims(token, key):
decoded = jwt.decode(token, key, options={"verify_signature": False})
return decoded
Correct: Python PyJWT - verify_signature enabled
import jwt
def get_user_claims(token, key):
decoded = jwt.decode(token, key, algorithms=["HS256"])
return decoded
Incorrect: Java auth0 java-jwt - decode without verify
import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
public class TokenHandler {
public DecodedJWT getUserClaims(String token) {
DecodedJWT jwt = JWT.decode(token);
return jwt;
}
}
Correct: Java auth0 java-jwt - verify before use
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
public class TokenHandler {
public DecodedJWT getUserClaims(String token, String secret) {
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer("auth0")
.build();
DecodedJWT jwt = verifier.verify(token);
return jwt;
}
}
References:
14. Cross-Site Request Forgery
Impact: HIGH
CSRF attacks force authenticated users to perform unwanted actions without their knowledge. CWE-352.
14.1 Prevent Cross-Site Request Forgery
Impact: HIGH (Attackers can force authenticated users to perform unwanted actions, potentially modifying data, transferring funds, or changing account settings)
Cross-Site Request Forgery (CSRF) is an attack that forces authenticated users to execute unwanted actions on a web application. When a user is authenticated, their browser automatically includes session cookies with requests. Attackers can craft malicious pages that trigger requests to vulnerable applications, causing actions to be performed without the user's consent.
Incorrect: using @csrf_exempt decorator
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def my_view(request):
return HttpResponse('Hello world')
Correct: remove csrf_exempt decorator
from django.http import HttpResponse
def my_view(request):
return HttpResponse('Hello world')
References:
Incorrect: Express app without CSRF protection
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
app.post('/process', bodyParser.urlencoded({ extended: false }), function(req, res) {
res.send('data is being processed')
})
Correct — Option A: csrf-csrf (Double-Submit Cookie pattern):
const express = require('express')
const cookieParser = require('cookie-parser')
const { doubleCsrf } = require('csrf-csrf')
const { doubleCsrfProtection, generateToken } = doubleCsrf({
getSecret: () => process.env.CSRF_SECRET,
cookieName: '__Host-psifi.x-csrf-token',
cookieOptions: { sameSite: 'strict', secure: true },
})
const app = express()
app.use(cookieParser())
app.use(doubleCsrfProtection)
// Generate a token for forms/SPA clients
app.get('/csrf-token', (req, res) => {
res.json({ token: generateToken(req, res) })
})
Correct — Option B: csrf-sync (Synchronizer Token pattern):
const express = require('express')
const { csrfSync } = require('csrf-sync')
const { csrfSynchronisedProtection, generateToken } = csrfSync()
const app = express()
app.use(csrfSynchronisedProtection)
Additional defenses: complement token-based CSRF protection
References:
Incorrect: explicitly disabling CSRF protection
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated();
}
}
Correct: CSRF protection enabled by default
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated();
}
}
References:
Incorrect: controller without protect_from_forgery
class DangerousController < ActionController::Base
puts "do more stuff"
end
Correct: controller with protect_from_forgery
class SafeController < ActionController::Base
protect_from_forgery with: :exception
puts "do more stuff"
end
References:
General References:
15. Prototype Pollution
Impact: HIGH
Prototype pollution in JavaScript can lead to property injection, denial of service, or code execution. CWE-1321.
15.1 Prevent Prototype Pollution
Impact: HIGH (Attackers can modify object prototypes to inject malicious properties)
Prototype pollution is a vulnerability that occurs when an attacker can modify the prototype of a base object, such as Object.prototype in JavaScript. This can create attributes that exist on every object or replace critical attributes with malicious ones.
Mitigations: Freeze prototypes with Object.freeze(Object.prototype), use Object.create(null), block proto and constructor keys, or use Map instead of objects.
Incorrect: JavaScript - dynamic property assignment from user input
app.get('/test/:id', (req, res) => {
let id = req.params.id;
let items = req.session.todos[id];
if (!items) {
items = req.session.todos[id] = {};
}
items[req.query.name] = req.query.text;
res.end(200);
});
Correct: JavaScript - validate keys and use null-prototype objects
const DANGEROUS_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
app.post('/test/:id', (req, res) => {
const id = req.params.id;
const name = req.query.name;
if (DANGEROUS_KEYS.has(id) || DANGEROUS_KEYS.has(name)) {
return res.status(400).end();
}
let items = req.session.todos[id];
if (!items) {
items = req.session.todos[id] = Object.create(null);
}
items[name] = req.query.text;
res.end(200);
});
Incorrect: JavaScript - nested property assignment in loop
function setNestedValue(obj, props, value) {
props = props.split('.');
var lastProp = props.pop();
while ((thisProp = props.shift())) {
if (typeof obj[thisProp] == 'undefined') {
obj[thisProp] = {};
}
obj = obj[thisProp];
}
obj[lastProp] = value;
}
Correct: JavaScript - use numeric index or Map
function safeIteration(name) {
let config = this.config;
name = name.split('.');
for (let i = 0; i < name.length; i++) {
config = config[i];
}
return this;
}
Incorrect: JavaScript - Object.assign with user input
function controller(req, res) {
const defaultData = {foo: true}
let data = Object.assign(defaultData, req.body)
doSmthWith(data)
}
Correct: JavaScript - use trusted data sources
function controller(req, res) {
const defaultData = {foo: {bar: true}}
let data = Object.assign(defaultData, {foo: getTrustedFoo()})
doSmthWith(data)
}
References:
16. Unsafe Functions
Impact: HIGH
Inherently dangerous functions (gets, strcpy, eval) bypass safety checks and should be avoided. CWE-242.
16.1 Avoid Unsafe Functions
Impact: HIGH (Buffer overflows and memory corruption)
Certain functions in various programming languages are inherently dangerous because they do not perform boundary checks, can lead to buffer overflows, have been deprecated, or bypass type safety mechanisms. Using these functions can result in security vulnerabilities, memory corruption, and arbitrary code execution.
Incorrect: C - strcat buffer overflow
int bad_strcpy(src, dst) {
n = DST_BUFFER_SIZE;
if ((dst != NULL) && (src != NULL) && (strlen(dst)+strlen(src)+1 <= n))
{
// ruleid: insecure-use-strcat-fn
strcat(dst, src);
// ruleid: insecure-use-strcat-fn
strncat(dst, src, 100);
}
}
Correct: C - use strcat_s with bounds checking
// Use strcat_s which performs bounds checking
Incorrect: C - strcpy buffer overflow
int bad_strcpy(src, dst) {
n = DST_BUFFER_SIZE;
if ((dst != NULL) && (src != NULL) && (strlen(dst)+strlen(src)+1 <= n))
{
// ruleid: insecure-use-string-copy-fn
strcpy(dst, src);
// ruleid: insecure-use-string-copy-fn
strncpy(dst, src, 100);
}
}
Correct: C - use strcpy_s with bounds checking
// Use strcpy_s which performs bounds checking
Incorrect: C - strtok modifies buffer
int bad_code() {
char str[DST_BUFFER_SIZE];
fgets(str, DST_BUFFER_SIZE, stdin);
// ruleid:insecure-use-strtok-fn
strtok(str, " ");
printf("%s", str);
return 0;
}
Correct: C - use strtok_r instead
int main() {
char str[DST_BUFFER_SIZE];
char dest[DST_BUFFER_SIZE];
fgets(str, DST_BUFFER_SIZE, stdin);
// ok:insecure-use-strtok-fn
strtok_r(str, " ", *dest);
printf("%s", str);
return 0;
}
Incorrect: C - scanf buffer overflow
int bad_code() {
char str[DST_BUFFER_SIZE];
// ruleid:insecure-use-scanf-fn
scanf("%s", str);
printf("%s", str);
return 0;
}
Correct: C - use fgets instead
int main() {
char str[DST_BUFFER_SIZE];
// ok:insecure-use-scanf-fn
fgets(str);
printf("%s", str);
return 0;
}
Incorrect: C - gets buffer overflow
int bad_code() {
char str[DST_BUFFER_SIZE];
// ruleid:insecure-use-gets-fn
gets(str);
printf("%s", str);
return 0;
}
Correct: C - use fgets or gets_s instead
int main() {
char str[DST_BUFFER_SIZE];
// ok:insecure-use-gets-fn
fgets(str);
printf("%s", str);
return 0;
}
Incorrect: PHP - deprecated mcrypt functions
<?php
// ruleid: mcrypt-use
mcrypt_ecb(MCRYPT_BLOWFISH, $key, base64_decode($input), MCRYPT_DECRYPT);
// ruleid: mcrypt-use
mcrypt_create_iv($iv_size, MCRYPT_RAND);
// ruleid: mcrypt-use
mdecrypt_generic($td, $c_t);
Correct: PHP - use Sodium or OpenSSL
<?php
// ok: mcrypt-use
sodium_crypto_secretbox("Hello World!", $nonce, $key);
// ok: mcrypt-use
openssl_encrypt($plaintext, $cipher, $key, $options=0, $iv, $tag);
Incorrect: Python - tempfile.mktemp race condition
import tempfile as tf
# ruleid: tempfile-insecure
x = tempfile.mktemp()
# ruleid: tempfile-insecure
x = tempfile.mktemp(dir="/tmp")
Correct: Python - use NamedTemporaryFile
import tempfile
# Use NamedTemporaryFile instead
with tempfile.NamedTemporaryFile() as tmp:
tmp.write(b"data")
Incorrect: Go - unsafe package bypasses type safety
package main
import (
"fmt"
"unsafe"
foobarbaz "unsafe"
)
type Fake struct{}
func (Fake) Good() {}
func main() {
unsafeM := Fake{}
unsafeM.Good()
intArray := [...]int{1, 2}
fmt.Printf("\nintArray: %v\n", intArray)
intPtr := &intArray[0]
fmt.Printf("\nintPtr=%p, *intPtr=%d.\n", intPtr, *intPtr)
// ruleid: use-of-unsafe-block
addressHolder := uintptr(foobarbaz.Pointer(intPtr)) + unsafe.Sizeof(intArray[0])
// ruleid: use-of-unsafe-block
intPtr = (*int)(foobarbaz.Pointer(addressHolder))
fmt.Printf("\nintPtr=%p, *intPtr=%d.\n\n", intPtr, *intPtr)
}
Correct: Go - avoid unsafe package
// Avoid using the unsafe package. Use Go's type-safe alternatives for memory operations.
Incorrect: Rust - calling C FFI without unsafe block
// ruleid: unsafe-usage
// This will not compile — libc::getpid() is an extern "C" function and requires unsafe
let pid = libc::getpid() as u32;
Correct — Option A (Rust - use safe standard library alternative, preferred):
// ok: unsafe-usage
// std::process::id() is a safe wrapper that returns the OS-assigned PID
let pid: u32 = std::process::id();
Correct — Option B (Rust - minimally scoped unsafe block with SAFETY comment):
// ok: unsafe-usage
// SAFETY: libc::getpid() is a read-only syscall with no preconditions
let pid = unsafe { libc::getpid() } as u32;
Incorrect: OCaml - unsafe functions skip bounds checks
let cb = Array.make 10 2 in
(* ruleid:ocamllint-unsafe *)
Printf.printf "%d\n" (Array.unsafe_get cb 12)
Correct: OCaml - use bounds-checked functions
let cb = Array.make 10 2 in
(* Use bounds-checked version *)
Printf.printf "%d\n" (Array.get cb 0)
17. Terraform AWS Security
Impact: HIGH
AWS infrastructure misconfigurations including public S3 buckets, unencrypted resources, and overly permissive IAM.
17.1 Secure AWS Terraform Configurations
Impact: HIGH (Cloud misconfigurations and data exposure)
Security best practices for AWS Terraform configurations to prevent common misconfigurations.
Incorrect: bucket without server-side encryption
resource "aws_s3_bucket" "bucket" {
bucket = "my-bucket"
}
Correct: bucket-level KMS encryption via aws_s3_bucket_server_side_encryption_configuration
resource "aws_s3_bucket" "bucket" {
bucket = "my-bucket"
}
resource "aws_s3_bucket_server_side_encryption_configuration" "pass" {
bucket = aws_s3_bucket.bucket.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
kms_master_key_id = aws_kms_key.example.arn
}
bucket_key_enabled = true
}
}
Incorrect: wildcard admin
resource "aws_iam_policy" "fail" {
policy = <<POLICY
{"Version":"2012-10-17","Statement":[{"Action":"*","Effect":"Allow","Resource":"*"}]}
POLICY
}
Correct: least privilege
resource "aws_iam_policy" "pass" {
policy = <<POLICY
{"Version":"2012-10-17","Statement":[{"Action":["s3:GetObject*"],"Effect":"Allow","Resource":"arn:aws:s3:::bucket/*"}]}
POLICY
}
Incorrect: wildcard AssumeRole
resource "aws_iam_role" "fail" {
assume_role_policy = <<POLICY
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"sts:AssumeRole"}]}
POLICY
}
Correct: restricted AssumeRole
resource "aws_iam_role" "pass" {
assume_role_policy = <<POLICY
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"sts:AssumeRole"}]}
POLICY
}
Incorrect: EBS
resource "aws_ebs_volume" "fail" {
availability_zone = "us-west-2a"
encrypted = false
}
Correct: EBS
resource "aws_ebs_volume" "pass" {
availability_zone = "us-west-2a"
encrypted = true
}
Incorrect: RDS no backup
resource "aws_db_instance" "fail" { backup_retention_period = 0 }
Correct: RDS with backup
resource "aws_db_instance" "pass" { backup_retention_period = 35 }
Incorrect: DynamoDB
resource "aws_dynamodb_table" "fail" {
name = "Table"; hash_key = "Id"
attribute { name = "Id"; type = "S" }
}
Correct: DynamoDB with CMK
resource "aws_dynamodb_table" "pass" {
name = "Table"; hash_key = "Id"
attribute { name = "Id"; type = "S" }
server_side_encryption { enabled = true; kms_key_arn = "arn:aws:kms:..." }
}
Incorrect: SQS/SNS
resource "aws_sqs_queue" "fail" { name = "queue" }
resource "aws_sns_topic" "fail" {}
Correct: SQS/SNS encrypted
resource "aws_sqs_queue" "pass" { name = "queue"; sqs_managed_sse_enabled = true }
resource "aws_sns_topic" "pass" { kms_master_key_id = "alias/aws/sns" }
Incorrect: public SSH
resource "aws_security_group_rule" "fail" {
type = "ingress"; protocol = "tcp"; from_port = 22; to_port = 22
cidr_blocks = ["0.0.0.0/0"]
}
Correct: restricted CIDR
resource "aws_security_group_rule" "pass" {
type = "ingress"; protocol = "tcp"; from_port = 22; to_port = 22
cidr_blocks = ["10.0.0.0/8"]
}
Incorrect: public IP
resource "aws_instance" "fail" {
ami = "ami-12345"; instance_type = "t3.micro"
associate_public_ip_address = true
}
Correct: no public IP
resource "aws_instance" "pass" {
ami = "ami-12345"; instance_type = "t3.micro"
associate_public_ip_address = false
}
Incorrect: KMS no rotation
resource "aws_kms_key" "fail" { enable_key_rotation = false }
Correct: KMS with rotation
resource "aws_kms_key" "pass" { enable_key_rotation = true }
Incorrect: CloudTrail
resource "aws_cloudtrail" "fail" { name = "trail"; s3_bucket_name = "bucket" }
Correct: CloudTrail encrypted
resource "aws_cloudtrail" "pass" {
name = "trail"; s3_bucket_name = "bucket"; kms_key_id = aws_kms_key.key.arn
}
Incorrect: hardcoded
provider "aws" {
region = "us-west-2"; access_key = "AKIAEXAMPLE"; secret_key = "secret"
}
Correct: external credentials
provider "aws" {
region = "us-west-2"; shared_credentials_file = "~/.aws/creds"; profile = "myprofile"
}
18. Terraform Azure Security
Impact: HIGH
Azure infrastructure misconfigurations including public endpoints, missing encryption, and insecure network settings.
18.1 Secure Azure Terraform Configurations
Impact: HIGH (Cloud misconfigurations and data exposure)
Security best practices for Azure infrastructure via Terraform. Misconfigurations can lead to data breaches and unauthorized access.
Incorrect:
resource "azurerm_storage_account" "bad" {
name = "storageaccountname"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
min_tls_version = "TLS1_0"
allow_nested_items_to_be_public = true
}
resource "azurerm_storage_container" "bad" {
name = "vhds"
storage_account_name = azurerm_storage_account.example.name
container_access_type = "blob"
}
Correct:
resource "azurerm_storage_account" "good" {
name = "storageaccountname"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
min_tls_version = "TLS1_2"
allow_nested_items_to_be_public = false
network_rules {
default_action = "Deny"
ip_rules = ["100.0.0.1"]
virtual_network_subnet_ids = [azurerm_subnet.example.id]
bypass = ["Metrics", "AzureServices"]
}
}
resource "azurerm_storage_container" "good" {
name = "vhds"
storage_account_name = azurerm_storage_account.example.name
container_access_type = "private"
}
Incorrect:
resource "azurerm_linux_web_app" "bad" {
name = "example-app-service"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
service_plan_id = azurerm_service_plan.example.id
https_only = false
site_config {
remote_debugging_enabled = true
minimum_tls_version = "1.0"
cors { allowed_origins = ["*"] }
}
auth_settings { enabled = false }
}
Correct:
resource "azurerm_linux_web_app" "good" {
name = "example-app-service"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
service_plan_id = azurerm_service_plan.example.id
https_only = true
site_config {
remote_debugging_enabled = false
minimum_tls_version = "1.2"
cors { allowed_origins = ["https://example.com"] }
}
auth_settings { enabled = true }
}
Incorrect:
resource "azurerm_key_vault" "bad" {
name = "examplekeyvault"
location = azurerm_resource_group.example.location
purge_protection_enabled = false
network_acls { bypass = "AzureServices"; default_action = "Allow" }
}
resource "azurerm_key_vault_key" "bad" {
name = "mykey"
key_vault_id = azurerm_key_vault.example.id
key_type = "RSA"
key_size = 2048
key_opts = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey"]
}
Correct:
resource "azurerm_key_vault" "good" {
name = "examplekeyvault"
location = azurerm_resource_group.example.location
soft_delete_retention_days = 7
purge_protection_enabled = true
network_acls { bypass = "AzureServices"; default_action = "Deny" }
}
resource "azurerm_key_vault_key" "good" {
name = "mykey"
key_vault_id = azurerm_key_vault.example.id
key_type = "RSA"
key_size = 2048
expiration_date = "2027-12-31T00:00:00Z"
key_opts = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey"]
}
Incorrect:
resource "azurerm_mssql_server" "bad" {
name = "mssqlserver"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
version = "12.0"
minimum_tls_version = "1.0"
public_network_access_enabled = true
}
resource "azurerm_mysql_firewall_rule" "bad" {
name = "office"
server_name = azurerm_mysql_server.example.name
start_ip_address = "0.0.0.0"
end_ip_address = "255.255.255.255"
}
Correct:
resource "azurerm_mssql_server" "good" {
name = "mssqlserver"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
version = "12.0"
minimum_tls_version = "1.2"
public_network_access_enabled = false
azuread_administrator {
login_username = "AzureAD Admin"
object_id = "00000000-0000-0000-0000-000000000000"
}
}
resource "azurerm_mysql_firewall_rule" "good" {
name = "office"
server_name = azurerm_mysql_server.example.name
start_ip_address = "40.112.8.12"
end_ip_address = "40.112.8.17"
}
Incorrect:
resource "azurerm_kubernetes_cluster" "bad" {
name = "example-aks1"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
dns_prefix = "exampleaks1"
private_cluster_enabled = false
api_server_authorized_ip_ranges = []
default_node_pool { name = "default"; node_count = 1; vm_size = "Standard_D2_v2" }
identity { type = "SystemAssigned" }
}
Correct:
resource "azurerm_kubernetes_cluster" "good" {
name = "example-aks1"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
dns_prefix = "exampleaks1"
private_cluster_enabled = true
disk_encryption_set_id = azurerm_disk_encryption_set.example.id
default_node_pool { name = "default"; node_count = 1; vm_size = "Standard_D2_v2" }
identity { type = "SystemAssigned" }
}
Incorrect:
resource "azurerm_linux_virtual_machine_scale_set" "bad" {
name = "example-vmss"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
sku = "Standard_F2"
admin_username = "adminuser"
admin_password = "P@55w0rd1234!"
encryption_at_host_enabled = false
disable_password_authentication = false
}
Correct:
resource "azurerm_linux_virtual_machine_scale_set" "good" {
name = "example-vmss"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
sku = "Standard_F2"
admin_username = "adminuser"
encryption_at_host_enabled = true
disable_password_authentication = true
admin_ssh_key { username = "adminuser"; public_key = tls_private_key.new.public_key_pem }
}
Always disable public network access and use virtual networks where possible.
Incorrect:
resource "azurerm_cosmosdb_account" "bad" {
name = "tfex-cosmos-db"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
offer_type = "Standard"
kind = "GlobalDocumentDB"
public_network_access_enabled = true
}
resource "azurerm_container_group" "bad" {
name = "example-continst"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
ip_address_type = "public"
os_type = "Linux"
container { name = "hello-world"; image = "microsoft/aci-helloworld:latest"; cpu = "0.5"; memory = "1.5" }
}
Correct:
resource "azurerm_cosmosdb_account" "good" {
name = "tfex-cosmos-db"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
offer_type = "Standard"
kind = "GlobalDocumentDB"
public_network_access_enabled = false
key_vault_key_id = azurerm_key_vault_key.example.versionless_id
}
resource "azurerm_container_group" "good" {
name = "example-continst"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
ip_address_type = "private"
os_type = "Linux"
subnet_ids = [azurerm_subnet.example.id]
container { name = "hello-world"; image = "microsoft/aci-helloworld:latest"; cpu = "0.5"; memory = "1.5" }
}
Incorrect:
resource "azurerm_role_definition" "bad" {
name = "my-custom-role"
scope = data.azurerm_subscription.primary.id
permissions { actions = ["*"]; not_actions = [] }
assignable_scopes = [data.azurerm_subscription.primary.id]
}
Correct:
resource "azurerm_role_definition" "good" {
name = "my-custom-role"
scope = data.azurerm_subscription.primary.id
permissions {
actions = [
"Microsoft.Authorization/*/read",
"Microsoft.Insights/alertRules/*",
"Microsoft.Resources/deployments/write",
"Microsoft.Support/*"
]
not_actions = []
}
assignable_scopes = [data.azurerm_subscription.primary.id]
}
19. Terraform GCP Security
Impact: HIGH
GCP infrastructure misconfigurations including public resources, disabled logging, and insecure IAM bindings.
19.1 Secure GCP Terraform Configurations
Impact: HIGH (Cloud misconfigurations and data exposure)
Impact: HIGH
Secure configuration patterns for Google Cloud Platform (GCP) resources using Terraform.
Incorrect:
resource "google_storage_bucket" "insecure" {
name = "example"
location = "EU"
uniform_bucket_level_access = false
}
resource "google_storage_bucket_iam_member" "public" {
bucket = google_storage_bucket.insecure.name
role = "roles/storage.admin"
member = "allUsers"
}
Correct:
resource "google_storage_bucket" "secure" {
name = "example"
location = "EU"
uniform_bucket_level_access = true
versioning { enabled = true }
logging { log_bucket = "my-logging-bucket" }
}
resource "google_storage_bucket_iam_member" "restricted" {
bucket = google_storage_bucket.secure.name
role = "roles/storage.admin"
member = "user:jane@example.com"
}
Incorrect:
resource "google_compute_instance" "insecure" {
name = "test"; machine_type = "n1-standard-1"; zone = "us-central1-a"
can_ip_forward = true; boot_disk {}
metadata = { serial-port-enable = true, enable-oslogin = false }
network_interface { network = "default"; access_config {} }
}
resource "google_compute_firewall" "open" {
name = "allow-all"; network = google_compute_network.vpc.name
allow { protocol = "tcp"; ports = [22, 3389] }
source_ranges = ["0.0.0.0/0"]
}
Correct:
resource "google_compute_instance" "secure" {
name = "test"; machine_type = "n1-standard-1"; zone = "us-central1-a"
can_ip_forward = false
boot_disk { kms_key_self_link = google_kms_crypto_key.key.id }
metadata = { enable-oslogin = true }
network_interface { network = "default" }
shielded_instance_config { enable_vtpm = true; enable_integrity_monitoring = true }
}
resource "google_compute_firewall" "restricted" {
name = "allow-ssh"; network = google_compute_network.vpc.name
allow { protocol = "tcp"; ports = ["22"] }
source_ranges = ["172.1.2.3/32"]; target_tags = ["ssh"]
}
Incorrect:
resource "google_container_cluster" "insecure" {
name = "my-cluster"; location = "us-central1-a"; initial_node_count = 3
enable_legacy_abac = true; logging_service = "none"
master_auth { username = "admin"; password = "password123" }
}
Correct:
resource "google_container_cluster" "secure" {
name = "my-cluster"; location = "us-central1-a"; initial_node_count = 3
enable_legacy_abac = false; enable_shielded_nodes = true; enable_binary_authorization = true
private_cluster_config { enable_private_nodes = true; master_ipv4_cidr_block = "10.0.0.0/28" }
master_authorized_networks_config { cidr_blocks { cidr_block = "10.0.0.0/8" } }
master_auth { client_certificate_config { issue_client_certificate = false } }
network_policy { enabled = true }
}
resource "google_container_node_pool" "secure" {
name = "my-pool"; cluster = "my-cluster"
management { auto_repair = true; auto_upgrade = true }
}
Incorrect:
resource "google_sql_database_instance" "insecure" {
database_version = "MYSQL_8_0"; name = "instance"
settings {
tier = "db-f1-micro"
ip_configuration { ipv4_enabled = true; authorized_networks { value = "0.0.0.0/0" } }
}
}
Correct:
resource "google_sql_database_instance" "secure" {
database_version = "MYSQL_8_0"; name = "instance"
settings {
tier = "db-f1-micro"
ip_configuration { ipv4_enabled = false; require_ssl = true; private_network = google_compute_network.net.id }
}
}
Incorrect:
resource "google_project_iam_member" "dangerous" {
project = "your-project-id"; role = "roles/iam.serviceAccountTokenCreator"
member = "serviceAccount:test-compute@developer.gserviceaccount.com"
}
resource "google_compute_subnetwork" "no_logs" {
name = "example"; ip_cidr_range = "10.0.0.0/16"; network = google_compute_network.vpc.id
}
resource "google_project" "default_network" {
name = "My Project"; project_id = "your-project-id"; org_id = "1234567"
}
Correct:
resource "google_project_iam_member" "safe" {
project = "your-project-id"; role = "roles/viewer"; member = "user:jane@example.com"
}
resource "google_compute_subnetwork" "with_logs" {
name = "example"; ip_cidr_range = "10.0.0.0/16"; network = google_compute_network.vpc.self_link
log_config { aggregation_interval = "INTERVAL_10_MIN"; flow_sampling = 0.5 }
}
resource "google_project" "no_default_network" {
name = "My Project"; project_id = "your-project-id"; org_id = "1234567"; auto_create_network = false
}
Incorrect:
resource "google_kms_crypto_key" "unprotected" {
name = "key"; key_ring = google_kms_key_ring.keyring.id; rotation_period = "15552000s"
}
resource "google_redis_instance" "insecure" { name = "my-instance"; memory_size_gb = 1; auth_enabled = false }
resource "google_bigquery_dataset" "unencrypted" { dataset_id = "example"; location = "EU" }
resource "google_pubsub_topic" "unencrypted" { name = "example-topic" }
Correct:
resource "google_kms_crypto_key" "protected" {
name = "key"; key_ring = google_kms_key_ring.keyring.id; rotation_period = "15552000s"
lifecycle { prevent_destroy = true }
}
resource "google_redis_instance" "secure" {
name = "my-instance"; memory_size_gb = 1; auth_enabled = true; transit_encryption_mode = "SERVER_AUTHENTICATION"
}
resource "google_bigquery_dataset" "encrypted" {
dataset_id = "example"; location = "EU"
default_encryption_configuration { kms_key_name = google_kms_crypto_key.example.name }
}
resource "google_pubsub_topic" "encrypted" { name = "topic"; kms_key_name = google_kms_crypto_key.key.id }
Incorrect:
resource "google_cloud_run_service_iam_member" "public" {
location = google_cloud_run_service.default.location; service = google_cloud_run_service.default.name
role = "roles/run.invoker"; member = "allUsers"
}
resource "google_cloudbuild_worker_pool" "public" { name = "pool"; location = "eu-west1"; worker_config { no_external_ip = false } }
resource "google_dataproc_cluster" "public" { name = "cluster"; region = "us-central1"; cluster_config { gce_cluster_config { internal_ip_only = false } } }
resource "google_notebooks_instance" "public" {
name = "instance"; location = "us-west1-a"; machine_type = "e2-medium"
vm_image { project = "deeplearning-platform-release"; image_family = "tf-latest-cpu" }; no_public_ip = false
}
Correct:
resource "google_cloud_run_service_iam_member" "restricted" {
location = google_cloud_run_service.default.location; service = google_cloud_run_service.default.name
role = "roles/run.invoker"; member = "user:jane@example.com"
}
resource "google_cloudbuild_worker_pool" "private" { name = "pool"; location = "eu-west1"; worker_config { no_external_ip = true } }
resource "google_dataproc_cluster" "private" { name = "cluster"; region = "us-central1"; cluster_config { gce_cluster_config { internal_ip_only = true } } }
resource "google_notebooks_instance" "private" {
name = "instance"; location = "us-west1-a"; machine_type = "e2-medium"
vm_image { project = "deeplearning-platform-release"; image_family = "tf-latest-cpu" }; no_public_ip = true
}
Incorrect:
resource "google_compute_ssl_policy" "weak" { name = "weak"; min_tls_version = "TLS_1_0" }
resource "google_dns_managed_zone" "weak" {
name = "zone"; dns_name = "example.com."
dnssec_config { state = "on"; default_key_specs { algorithm = "rsasha1"; key_length = 2048; key_type = "keySigning" } }
}
Correct:
resource "google_compute_ssl_policy" "strong" { name = "strong"; min_tls_version = "TLS_1_2"; profile = "MODERN" }
resource "google_dns_managed_zone" "strong" {
name = "zone"; dns_name = "example.com."
dnssec_config { state = "on"; default_key_specs { algorithm = "rsasha256"; key_length = 2048; key_type = "keySigning" } }
}
20. Kubernetes Security
Impact: HIGH
Kubernetes misconfigurations including privileged containers, host namespace access, and excessive RBAC permissions.
20.1 Secure Kubernetes Configurations
Impact: HIGH (Container escapes and cluster compromise)
This guide provides security best practices for Kubernetes YAML configurations. Following these patterns helps prevent common security misconfigurations that could expose your containers and cluster to attacks.
Key Security Principles:
Running containers in privileged mode grants full access to the host, bypassing security boundaries.
Incorrect:
apiVersion: v1
kind: Pod
spec:
containers:
- name: nginx
image: nginx
securityContext:
privileged: true
Correct:
apiVersion: v1
kind: Pod
spec:
containers:
- name: redis
image: redis
securityContext:
privileged: false
Containers should never run as root to limit the impact of container escapes.
Incorrect:
apiVersion: v1
kind: Pod
spec:
securityContext:
runAsNonRoot: false
containers:
- name: redis
image: redis
Correct:
apiVersion: v1
kind: Pod
spec:
securityContext:
runAsNonRoot: true
containers:
- name: nginx
image: nginx
Prevent processes from gaining more privileges than their parent process.
Incorrect:
apiVersion: v1
kind: Pod
spec:
containers:
- name: redis
image: redis
securityContext:
allowPrivilegeEscalation: true
Correct:
apiVersion: v1
kind: Pod
spec:
containers:
- name: haproxy
image: haproxy
securityContext:
allowPrivilegeEscalation: false
Sharing the host PID namespace allows containers to see and interact with all processes on the host.
Incorrect:
apiVersion: v1
kind: Pod
metadata:
name: view-pid
spec:
hostPID: true
containers:
- name: nginx
image: nginx
Correct:
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
containers:
- name: nginx
image: nginx
Sharing the host network namespace exposes the host network stack to the container.
Incorrect:
apiVersion: v1
kind: Pod
metadata:
name: view-network
spec:
hostNetwork: true
containers:
- name: nginx
image: nginx
Correct:
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
containers:
- name: nginx
image: nginx
Sharing the host IPC namespace allows containers to access shared memory on the host.
Incorrect:
apiVersion: v1
kind: Pod
metadata:
name: view-ipc
spec:
hostIPC: true
containers:
- name: nginx
image: nginx
Correct:
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
containers:
- name: nginx
image: nginx
Mounting the Docker socket gives containers full control over the Docker daemon.
Incorrect:
apiVersion: v1
kind: Pod
spec:
containers:
- image: gcr.io/google_containers/test-webserver
name: test-container
volumeMounts:
- mountPath: /var/run/docker.sock
name: docker-sock-volume
volumes:
- name: docker-sock-volume
hostPath:
type: Socket
path: /var/run/docker.sock
Correct:
apiVersion: v1
kind: Pod
spec:
containers:
- image: gcr.io/google_containers/test-webserver
name: test-container
volumeMounts:
- mountPath: /data
name: data-volume
volumes:
- name: data-volume
emptyDir: {}
Never store secrets directly in configuration files. Use external secrets management.
Incorrect:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
USERNAME: Y2FsZWJraW5uZXk=
PASSWORD: UzNjcmV0UGEkJHcwcmQ=
Correct: use Sealed Secrets or external secrets management
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: mysecret
spec:
encryptedData:
password: AgBy8hCi8...encrypted...
21. Docker Security
Impact: HIGH
Docker misconfigurations including running as root, privileged mode, and exposed Docker socket.
21.1 Secure Docker Configurations
Impact: HIGH (Container escapes and privilege escalation)
This guide provides security best practices for Dockerfiles and docker-compose configurations. Following these patterns helps prevent container escapes, privilege escalation, and other security vulnerabilities in containerized environments.
The last user in the container should not be 'root'. If an attacker gains control of the container, they will have root access.
Incorrect:
FROM debian:bookworm
RUN apt-get update && apt-get install -y some-package
USER appuser
USER root
Correct:
FROM debian:bookworm
USER root
RUN apt-get update && apt-get install -y some-package
USER appuser
Images should be tagged with an explicit version to produce deterministic container builds.
Incorrect:
FROM debian
Correct:
FROM debian:bookworm
The 'latest' tag may change the base container without warning, producing non-deterministic builds.
Incorrect:
FROM debian:latest
Correct:
FROM debian:bookworm
Running containers in privileged mode grants the container the equivalent of root capabilities on the host machine. This can lead to container escapes, privilege escalation, and other security concerns.
Incorrect:
version: "3.9"
services:
worker:
image: my-worker-image:1.0
privileged: true
Correct:
version: "3.9"
services:
worker:
image: my-worker-image:1.0
privileged: false
Exposing the host's Docker socket to containers via a volume is equivalent to giving unrestricted root access to your host. Never expose the Docker socket unless absolutely necessary.
Incorrect:
version: "3.9"
services:
worker:
image: my-worker-image:1.0
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Correct: use a named volume instead of host mounts
version: "3.9"
services:
worker:
image: my-worker-image:1.0
volumes:
- worker-data:/app/data
volumes:
worker-data:
If unverified user data can reach the run or create method, it can result in running arbitrary containers.
Incorrect:
import docker
client = docker.from_env()
def run_container(user_input):
client.containers.run(user_input, 'echo hello world')
Correct:
import docker
client = docker.from_env()
def run_container():
client.containers.run("alpine", 'echo hello world')
22. GitHub Actions Security
Impact: HIGH
GitHub Actions vulnerabilities including script injection, unsafe checkout of PR code, and unpinned actions.
22.1 Secure GitHub Actions
Impact: HIGH (Prevents code injection, secrets theft, and supply chain attacks in CI/CD pipelines)
GitHub Actions workflows can be vulnerable to several security issues including script injection, secrets exposure, and supply chain attacks. Attackers who exploit these vulnerabilities can steal repository secrets, inject malicious code, or compromise the entire CI/CD pipeline.
Using variable interpolation ${{...}} with github context data in a run: step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code.
When using pull_request_target, the Action runs in the context of the target repository with access to all repository secrets. Checking out the incoming PR code while having access to secrets is dangerous because you may inadvertently execute arbitrary code from the incoming PR.
Similar to pull_request_target, when using workflow_run, the Action runs in the context of the target repository with access to all repository secrets. Checking out incoming PR code with this trigger is dangerous.
An action sourced from a third-party repository on GitHub is not pinned to a full length commit SHA. Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release.
Incorrect: vulnerable to script injection via PR title
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check PR title
run: |
title="${{ github.event.pull_request.title }}"
echo "$title"
Correct: use environment variable
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check PR title
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
echo "$PR_TITLE"
Fix: Use an intermediate environment variable with env: to store the data and use the environment variable in the run: script. Be sure to use double-quotes around the environment variable.
Incorrect: checking out PR code with pull_request_target
on:
pull_request_target:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
- run: npm install && npm build
Correct: no checkout of PR code
on:
pull_request_target:
jobs:
safe-job:
runs-on: ubuntu-latest
steps:
- name: echo
run: echo "Hello, world"
Incorrect: checking out PR code with workflow_run
on:
workflow_run:
workflows: ["CI"]
types: [completed]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.workflow_run.head.sha }}
- run: npm install
Correct: no checkout of PR code
on:
workflow_run:
workflows: ["CI"]
types: [completed]
jobs:
safe-job:
runs-on: ubuntu-latest
steps:
- run: echo "Safe operation"
Incorrect: using tag reference
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: fakerepo/comment-on-pr@v1
with:
message: "Thank you!"
Correct: pinned to full commit SHA
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: fakerepo/comment-on-pr@5fd3084fc36e372ff1fff382a39b10d03659f355
with:
message: "Thank you!"
Note: GitHub-owned actions (actions/, github/) and local actions (./.github/actions/*) don't require SHA pinning.
References:
Reference: https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#understanding-the-risk-of-script-injections, https://securitylab.github.com/research/github-actions-preventing-pwn-requests/, https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability, https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions
23. Regular Expression DoS
Impact: MEDIUM
ReDoS attacks exploit inefficient regex patterns to cause CPU exhaustion and denial of service. CWE-1333.
23.1 Prevent Regular Expression DoS
Impact: MEDIUM (Service disruption through CPU exhaustion via malicious regex patterns)
Regular Expression Denial of Service (ReDoS) occurs when attackers exploit inefficient regular expression patterns to cause excessive CPU consumption. Certain regex patterns with nested quantifiers or overlapping alternatives can experience "catastrophic backtracking" when matched against malicious input, causing the regex engine to take exponential time to evaluate.
Common vulnerable patterns include:
Incorrect: vulnerable ReDoS pattern
const re = new RegExp("([a-z]+)+$", "i");
var emailRegex = /^\w+([-_+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
emailRegex.test(userInput);
Correct: safe regex patterns
// Use atomic patterns without nested quantifiers
const safeRegex = /^[a-z]+$/i;
// Or use a library with ReDoS protection
import { RE2 } from 're2';
const re = new RE2("([a-z]+)+$");
Incorrect: non-literal RegExp with user input
function searchHandler(userPattern) {
const reg = new RegExp("\\w+" + userPattern);
return reg.exec(data);
}
Correct: hardcoded regex patterns
function searchHandler(userInput) {
const reg = new RegExp("\\w+");
return reg.exec(userInput);
}
Incorrect: incomplete string sanitization
function escapeQuotes(s) {
return s.replace("'", "''"); // Only replaces first occurrence
}
Correct: use regex with global flag
function escapeQuotes(s) {
return s.replace(/'/g, "''"); // Replaces all occurrences
}
References:
Incorrect: inefficient regex pattern
import re
redos_pattern = r"^(a+)+$"
data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaX"
pattern = re.compile(redos_pattern)
pattern.match(data) # Catastrophic backtracking
Correct: safe regex patterns
import re
safe_pattern = r"^a+$"
data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaX"
pattern = re.compile(safe_pattern)
pattern.match(data) # Fast failure, no backtracking
Mitigation strategies:
# Use regex timeout (Python 3.11+)
import re
re.match(pattern, data, timeout=1.0)
# Or use google-re2 library for linear-time matching
import re2
re2.match(r"^(a+)+$", data)
References:
References:
24. Race Conditions
Impact: MEDIUM
TOCTOU race conditions and insecure temporary file creation can lead to privilege escalation. CWE-367.
24.1 Prevent Race Conditions
Impact: MEDIUM (Time-of-check Time-of-use (TOCTOU) vulnerabilities, insecure temporary files, data corruption)
Race conditions occur when the behavior of software depends on the timing or sequence of events that execute in an unpredictable order. Time-of-check Time-of-use (TOCTOU) vulnerabilities are a specific type of race condition where a resource's state is checked at one point in time but used at a later point, allowing an attacker to modify the resource between the check and use.
Common race condition patterns include:
Using Filename.temp_file might lead to race conditions since the file could be altered or replaced by a symlink before being opened.
Incorrect: vulnerable to race condition
(* ruleid:ocamllint-tempfile *)
let ofile = Filename.temp_file "test" "" in
Printf.printf "%s\n" ofile
Correct: use safer alternatives
(* Use open_temp_file which returns both the filename and an open channel *)
let (filename, oc) = Filename.open_temp_file "test" "" in
Printf.fprintf oc "data\n";
close_out oc
References:
Incorrect: vulnerable to race condition
import tempfile
# ruleid: tempfile-insecure
x = tempfile.mktemp()
# ruleid: tempfile-insecure
x = tempfile.mktemp(dir="/tmp")
Correct: use secure alternatives
import os
import tempfile
# Use NamedTemporaryFile which atomically creates and opens the file
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
f.write("data")
filename = f.name
# Or use mkstemp which returns both file descriptor and name
fd, path = tempfile.mkstemp()
try:
with os.fdopen(fd, 'w') as f:
f.write("data")
finally:
os.unlink(path)
References:
Incorrect: hardcoded tmp path
def test1():
# ruleid:hardcoded-tmp-path
f = open("/tmp/blah.txt", 'w')
f.write("hello world")
f.close()
def test2():
# ruleid:hardcoded-tmp-path
f = open("/tmp/blah/blahblah/blah.txt", 'r')
data = f.read()
f.close()
def test4():
# ruleid:hardcoded-tmp-path
with open("/tmp/blah.txt", 'r') as fin:
data = fin.read()
Correct: use tempfile module or relative paths
def test3():
# ok:hardcoded-tmp-path
f = open("./tmp/blah.txt", 'w')
f.write("hello world")
f.close()
def test3a():
# ok:hardcoded-tmp-path
f = open("/var/log/something/else/tmp/blah.txt", 'w')
f.write("hello world")
f.close()
def test5():
# ok:hardcoded-tmp-path
with open("./tmp/blah.txt", 'w') as fout:
fout.write("hello world")
References:
Incorrect: hardcoded tmp path
package samples
import (
"fmt"
"io/ioutil"
)
func main() {
// ruleid:bad-tmp-file-creation
err := ioutil.WriteFile("/tmp/demo2", []byte("This is some data"), 0644)
if err != nil {
fmt.Println("Error while writing!")
}
}
Correct: use os.CreateTemp for atomic creation
import "os"
func main_good() {
// ok:bad-tmp-file-creation
f, err := os.CreateTemp("", "my_temp-*.txt")
if err != nil {
fmt.Println("Error while creating temp file!")
return
}
defer f.Close()
_, err = f.WriteString("secure data")
if err != nil {
fmt.Println("Error while writing!")
}
}
References:
References:
25. Code Correctness
Impact: MEDIUM
Common coding mistakes including exception handling errors, null checks, type errors, and logic bugs.
25.1 Code Correctness
Impact: MEDIUM (Runtime errors and unexpected behavior)
Common coding mistakes that cause runtime errors, unexpected behavior, or logic issues.
Python only instantiates default arguments once. Mutating them affects all future calls.
INCORRECT:
def append_func(default=[]):
default.append(5)
CORRECT:
def append_func(default=None):
if default is None:
default = []
default.append(5)
INCORRECT:
items = [1, 2, 3, 4]
for i in items:
items.pop(0)
CORRECT:
for i in list(items): # Iterate over a copy
items.pop(0)
Using break, continue, or return in finally suppresses exceptions.
INCORRECT:
try:
raise ValueError()
finally:
break # Suppresses the exception!
CORRECT - Let the exception propagate; use finally only for cleanup:
try:
raise ValueError()
finally:
cleanup() # Cleanup runs, exception still propagates
INCORRECT:
raise "error"
CORRECT:
raise Exception("error")
Missing commas cause implicit string concatenation.
INCORRECT:
bad = ["a" "b" "c"] # Results in ["abc"]
CORRECT:
good = ["a", "b", "c"]
INCORRECT:
return `value is {x}` // Missing $
CORRECT:
return `value is ${x}`
Loop variables are shared across iterations (Go < 1.22).
INCORRECT:
for _, val := range values {
funcs = append(funcs, func() {
fmt.Println(&val) // Same pointer for all!
})
}
CORRECT:
for _, val := range values {
val := val // Create new variable
funcs = append(funcs, func() {
fmt.Println(&val)
})
}
INCORRECT:
bigValue, _ := strconv.Atoi("2147483648")
value := int16(bigValue) // Overflow!
CORRECT:
parsed, err := strconv.ParseInt("2147483648", 10, 32)
if err != nil {
// handles out-of-range and invalid syntax
log.Fatal(err)
}
value := int32(parsed)
INCORRECT:
if (a == "hello") return 1;
CORRECT:
if ("hello".equals(a)) return 1;
INCORRECT:
if (myBoolean = true) { // Assignment, not comparison!
CORRECT:
if (myBoolean) {
The ato*() functions cause undefined behavior on overflow.
INCORRECT:
int i = atoi(buf);
CORRECT:
char *endptr;
errno = 0;
long l = strtol(buf, &endptr, 10);
if (errno != 0 || endptr == buf || *endptr != '\0') {
// handle conversion error
}
Unquoted variables split on whitespace.
INCORRECT:
exec $foo
CORRECT:
exec "$foo"
INCORRECT:
if (list.indexOf(item) > 0) // Misses first element!
CORRECT:
if (list.indexOf(item) >= 0)
Atoms are never garbage collected. Use String.to_existing_atom instead of String.to_atom.
Use = not == for value comparison, <> not != for inequality.
26. Best Practices
Impact: LOW
Code style, API usage patterns, deprecated patterns, and general coding recommendations.
26.1 Code Best Practices
Impact: LOW (Code quality and maintainability issues)
This document outlines coding best practices across multiple languages. Following these patterns helps improve code quality, maintainability, and prevents common mistakes.
Incorrect: Python
def func1():
fd = open('foo')
x = 123
Correct: Python - using context manager
def func2():
with open('bar', encoding='utf-8') as fd:
data = fd.read()
open() uses device locale encodings by default. Always specify encoding in text mode.
Incorrect:
fd = open('foo', mode="w")
Correct:
fd = open('foo', encoding='utf-8', mode="w")
Requests without a timeout will hang indefinitely if no response is received.
Incorrect: Python
import requests
r = requests.get(url)
Correct: Python
r = requests.get(url, timeout=30)
Debug statements like alert(), confirm(), prompt(), and debugger should not be in production code.
Incorrect: JavaScript
var name = prompt('what is your name');
alert('your name is ' + name);
debugger;
Lazy loading inside functions complicates bundling and blocks requests synchronously in Node.js.
Incorrect: JavaScript
function smth() {
const mod = require('module-name')
return mod();
}
Correct: JavaScript
const mod = require('module-name')
function smth() {
return mod();
}
File creation in shared tmp directories without proper APIs can lead to security vulnerabilities.
Incorrect: Python
with open('/tmp/myfile.txt', 'w') as f:
f.write(data)
Correct: Python
import tempfile
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
f.write(data)
Always set HttpOnly and Secure flags on security-sensitive cookies.
Incorrect: JavaScript/Express
res.cookie('session', value);
Correct: JavaScript/Express
res.cookie('session', value, { httpOnly: true, secure: true });
Never redirect to user-provided URLs without validation to prevent open redirect vulnerabilities.
Incorrect: JavaScript
res.redirect(req.query.returnUrl);
Correct: JavaScript
const allowedHosts = ['example.com'];
const url = new URL(req.query.returnUrl, 'https://example.com');
if (allowedHosts.includes(url.hostname)) {
res.redirect(url.href);
}
Use actively maintained alternatives instead of deprecated libraries.
Incorrect: JavaScript - Moment.js is deprecated
import moment from 'moment';
Correct: JavaScript - use dayjs
import dayjs from 'dayjs';
27. Performance
Impact: LOW
Performance anti-patterns including inefficient loops, unnecessary database queries, and memory waste.
27.1 Performance Best Practices
Impact: LOW (Unnecessary overhead and inefficiency)
This document covers performance optimizations to write efficient code. These rules identify patterns that cause unnecessary computational overhead, extra database queries, or memory inefficiency.
Use ITEM.user_id rather than ITEM.user.id to prevent running an extra query. Accessing .user.id causes Django to fetch the entire related User object just to get the ID, when the foreign key ID is already available on the model.
INCORRECT - Extra query to fetch related object:
def get_user_id(item):
return item.user.id
CORRECT - Use the foreign key directly:
def get_user_id(item):
return item.user_id
Using QUERY.count() instead of len(QUERY.all()) sends less data to the client since the count is performed server-side. The len(all()) approach fetches all records into memory just to count them.
INCORRECT - Fetches all records into memory:
total = len(persons.all())
CORRECT - Count performed server-side:
total = persons.count()
Rather than adding one element at a time, use batch loading to improve performance. Looping db.session.add() increases session bookkeeping overhead and can trigger per-iteration SQL if autoflush is enabled (e.g., when a query runs during the loop).
INCORRECT - Adding one at a time in a loop:
for song in songs:
db.session.add(song)
CORRECT - Batch add all at once:
db.session.add_all(songs)
By declaring a styled component inside the render method, you dynamically create a new component on every render. This forces React to discard and re-calculate that part of the DOM subtree on each render, leading to performance bottlenecks.
INCORRECT - Styled component declared inside function:
import styled from "styled-components";
function FunctionalComponent() {
const StyledDiv = styled.div`
color: blue;
`
return <StyledDiv />
}
CORRECT - Styled component declared at module level:
import styled from "styled-components";
const StyledDiv = styled.div`
color: blue;
`
function FunctionalComponent() {
return <StyledDiv />
}
Hoist expensive work (object allocations, RegExp compilation, function creation) out of loops.
INCORRECT - RegExp compiled on every iteration:
for (const line of lines) {
const match = line.match(new RegExp('\\d{4}-\\d{2}-\\d{2}'));
if (match) results.push(match[0]);
}
CORRECT - Compile once, reuse in loop:
const datePattern = /\d{4}-\d{2}-\d{2}/;
for (const line of lines) {
const match = line.match(datePattern);
if (match) results.push(match[0]);
}
For operations that require iterating, prefer built-in methods that short-circuit:
INCORRECT - Full iteration to find one item:
const found = items.filter(x => x.id === targetId)[0];
CORRECT - Short-circuit on first match:
const found = items.find(x => x.id === targetId);
28. Maintainability
Impact: LOW
Code organization, deprecated API usage, naming conventions, and long-term code health.
28.1 Code Maintainability
Impact: LOW (Technical debt and code confusion)
Rules that identify code patterns leading to confusion, technical debt, or unexpected behavior. Focus areas: useless code, deprecated APIs, and code organization.
Incorrect: Python - duplicate if condition
if a:
print('1')
elif a:
print('2')
Correct: Python - distinct conditions
if a:
print('1')
elif b:
print('2')
Incorrect: Python - identical if/else branches
if a:
print('1')
else:
print('1')
Correct: Python - different branches or simplified
print('1')
Incorrect: Python - unused inner function
def A():
def B():
print('never used')
return None
Correct: Python - inner function called or returned
def A():
def B():
print('used')
return B()
Incorrect: Python - function reference without call
if example.is_positive:
do_something()
Correct: Python - function called with parentheses
if example.is_positive():
do_something()
Incorrect: Django - duplicate URL paths
urlpatterns = [
path('path/to/view', views.example_view),
path('path/to/view', views.other_view),
]
Correct: Django - unique URL paths
urlpatterns = [
path('path/to/view1', views.example_view),
path('path/to/view2', views.other_view),
]
Incorrect: Flask - deprecated APIs
from flask import json_available
blueprint = request.module
Correct: Flask - modern alternatives
from flask import Flask, request
app = Flask(__name__)