🚧 Under construction — VoTechWorks is being built. A free tech program — complimentary, as our commitment to get America working.
voTechWorksGrade 13 · a vocational technology learning center, by urbanicity
newSchoolWorks.com › VoTechWorks › Technology & Design › Cybersecurity › Scripting for Cybersecurity › Lesson 6
TEC-CYBE44-05 · Lesson 6 · 12 clock hours · theory

Secure Scripting Practices: Input Validation, Least Privilege, and Credential Handling

Objective. Students identify insecure scripting patterns and rewrite vulnerable code snippets to eliminate command injection, hard-coded credentials, and overly broad file permissions.

⚠ Pending professional review

This lesson, its worked examples and its practice questions has not yet been verified by an industry-certified professional or by a certification or approval body. It is a study draft and may contain errors. Do not use it as instructions for work on a job site or on live equipment. Always follow your instructor, your supervising professional, and current official references and regulations.

VoTechWorks program approval and accreditation are still in progress. Credentials are issued only by the certifying bodies named in each program, after their own exams.

Why Secure Scripting Matters

Automation scripts are everywhere in cybersecurity work: they collect logs, call APIs, manage user accounts, and respond to alerts. Because scripts often run with elevated permissions and interact with sensitive data, a single insecure pattern can give an attacker a foothold in the entire environment. Three patterns cause the majority of scripting vulnerabilities in practice: unsanitized input passed to a shell, credentials stored in plaintext inside source code, and scripts that run with more privilege than the task requires.

Command Injection and Shell=True

When a Python script builds a shell command by concatenating user-supplied input and passes it to `subprocess.run()` or `os.system()` with `shell=True`, the interpreter hands the full string to the operating system shell. An attacker who controls any part of that string can append additional commands using characters such as `;`, `&&`, `|`, or backticks.

Vulnerable pattern:

```python

import subprocess

filename = input("Enter filename: ")

subprocess.run("cat " + filename, shell=True)

```

If a user enters `report.txt; rm -rf /tmp`, the shell executes both commands.

Secure pattern — list argument, no shell:

```python

import subprocess

filename = input("Enter filename: ")

subprocess.run(["cat", filename], shell=False)

```

When you pass a list, Python passes each element as a discrete argument directly to the program; the shell is never involved, so shell metacharacters have no effect. Always validate and allowlist input even when using the list form — reject values that contain path-traversal sequences such as `../`.

Hard-Coded Credentials

Storing passwords, API keys, or tokens directly in source code is one of the most common and most costly mistakes in scripting. Source files end up in version control, get shared across teams, or are accidentally exposed in logs. Anyone who reads the file — or the git history — has the credential.

Vulnerable pattern:

```python

API_KEY = "sk-abc123secret"

```

Secure alternatives:

1. Environment variables — Read the value at runtime with `os.environ.get("API_KEY")`. The variable is set in the shell session or a deployment config file that is never committed to source control.

2. Secrets file with restricted permissions — Store credentials in a file outside the project directory, set its permissions to `600` (owner read/write only) with `chmod 600 secrets.env`, and read it at runtime. Never commit this file; add it to `.gitignore`.

3. Secrets managers — Production environments often use dedicated tools (such as HashiCorp Vault or cloud provider secrets managers) that audit access and rotate credentials automatically.

After removing a hard-coded credential, rotate the credential immediately — assume it was already compromised.

Least Privilege and Privilege Dropping

The principle of least privilege states that a process should have only the permissions it needs to complete its task, and no more. A script that runs as root (UID 0 on Linux) can read, write, or delete any file, modify system configuration, and install software. If the script is exploited, the attacker inherits root.

Privilege-drop pattern in Python:

```python

import os

os.setgid(1000) # set group ID first

os.setuid(1000) # then set user ID

```

Set GID before UID because a root process can change both; once UID is dropped, group changes may be restricted. Use a dedicated service account with the minimum necessary file permissions rather than a regular user account when possible.

For scripts that legitimately need a brief moment of elevated privilege (for example, opening a low-numbered port), perform only that operation as root, drop privileges immediately afterward, and continue execution as a limited user.

File Permissions and Secrets Files

Linux and macOS use octal permission modes. A secrets file should be readable only by its owner:

Set permissions from the command line: `chmod 600 secrets.env`. Scripts that create temporary files containing sensitive data should also set restrictive permissions immediately on creation and delete the files when finished.

Safety in the SOC Environment

Safe scripting is not only about code — it includes the physical workspace. Security Operations Center (SOC) analysts and scripting practitioners face real ergonomic and electrical hazards:

The OSHA General Duty Clause (Section 5(a)(1) of the OSH Act) requires employers to provide a workplace free from recognized hazards likely to cause serious harm. This applies to IT workplaces just as it does to factories.

Summary

Secure scripts avoid shell injection by using subprocess with a list argument and no `shell=True` on user-supplied input. They never store credentials in source code, relying instead on environment variables, restricted secrets files, or secrets managers. They run with the minimum privilege required, dropping elevated rights as soon as possible. Combined with physical safety awareness in the workspace, these practices form the foundation of responsible automation work in cybersecurity.

Key terms9

Command injectionAn attack in which unsanitized user input is interpreted as shell commands by the operating system, allowing an attacker to execute arbitrary code.
shell=TrueA Python subprocess parameter that passes the command string to the operating-system shell for interpretation, enabling shell metacharacters and making injection attacks possible.
Least privilegeThe security principle that a process, user account, or script should be granted only the minimum permissions needed to perform its intended function.
Hard-coded credentialA password, API key, or other secret embedded directly in source code rather than read from a secure external source at runtime.
Privilege droppingThe practice of a process voluntarily reducing its own privileges (for example, from root to a limited user) after completing any task that required elevated rights.
Environment variableA named value stored in the operating-system environment of a running process, used to pass configuration data such as credentials without embedding them in source code.
File permission modeAn octal value (such as 600 or 400) that controls which users and groups may read, write, or execute a file on a Unix-like operating system.
Input validationThe process of checking that data received from a user or external source conforms to expected types, lengths, formats, and allowlists before the data is used in any operation.
OSHA General Duty ClauseSection 5(a)(1) of the Occupational Safety and Health Act, which requires employers to provide a workplace free from recognized hazards likely to cause death or serious physical harm, applicable to IT workplaces as well as industrial settings.
In class: Case-study analysis: students examine three deliberately flawed scripts (one with a shell-injection vulnerability via unsanitized user input, one with a hard-coded API key, one that runs as root unnecessarily) and write a one-paragraph risk explanation for each. · Remediation exercise: students fix each of the three flawed scripts using subprocess with a list argument instead of shell=True, environment variables or a secrets file with restricted permissions for credentials, and a privilege-drop pattern. · Group discussion: class reviews OSHA General Duty Clause applicability to IT safety and discusses physical and ergonomic hazards in a SOC environment (extended screen time, cable management, electrical safety), reinforcing Safety+ principles from course 1.
Materials: Flawed script handouts (instructor-prepared), Python subprocess and os module docs, OSHA 29 CFR 1910 General Industry standards (general reference), course lab guide chapter 6
Check: All three remediated scripts pass a manual instructor code review confirming no shell=True on user-supplied input, no plaintext credentials in source, and no unnecessary root execution; all three must pass for credit.

Practice check8

Answer each question, then check it. Nothing is recorded; this is your own practice.

Threats, Attacks and Vulnerabilities
1. A script runs the following line: `subprocess.run("ping " + hostname, shell=True)`. Which attack does this most directly enable?
Threats, Attacks and Vulnerabilities
2. Which subprocess call correctly eliminates the shell-injection risk when running 'cat' on a user-supplied filename?
Risk Management
3. A developer commits a script containing the line `TOKEN = "ghp_abc123xyz"` to a public repository. What is the FIRST remediation step?
Identity and Access Management
4. According to the principle of least privilege, a log-parsing script that reads files in /var/log should run as which of the following?
Technologies and Tools
5. A secrets file containing an API key should be set to which octal permission mode so that only the file owner can read or write it?
Technologies and Tools
6. In Python, what is the correct order of operations when a privileged script needs to drop from root to a limited user?
Risk Management
7. Which OSHA provision most directly applies to a SOC employer who allows unsecured power cables to create trip hazards in the workspace?
Identity and Access Management
8. A cybersecurity analyst writes a script that reads credentials using `os.environ.get('DB_PASSWORD')` instead of a hard-coded string. Which security benefit does this approach PRIMARILY provide?
Record this lesson on my transcript. Sign in with your key and enrollment email to record lessons (enroll free if you have no key). This page stays open to read and practise.