Getting Started
Write your first security rule in 5 minutes. This hands-on guide will have you detecting vulnerabilities immediately.
Prerequisites
Before writing rules, make sure you have Code Pathfinder installed:
npm install -g codepathfinderVerify the installation:
pathfinder --versionYour First Rule
Let's write a rule to detect hardcoded passwords. Create a file called my_first_rule.py:
from codepathfinder import rule, calls
@rule(
id="hardcoded-password",
severity="high",
cwe="CWE-798"
)
def detect_hardcoded_password():
"""Detects hardcoded passwords in database connections"""
return calls("connect", match_name={"password": "*"})How this works:
@rule(...)- Decorator that marks this as a security ruleid- Unique identifier for the ruleseverity- How serious this issue is (critical/high/medium/low)cwe- Maps to Common Weakness Enumerationcalls("connect", ...)- Find calls to any function named "connect"match_name={"password": "*"}- Where password argument has any value
Running the Rule
Create a test file to scan. Save this as test_app.py:
import psycopg2
# BAD: Hardcoded password
conn = psycopg2.connect(
host="localhost",
database="mydb",
user="admin",
password="secret123" # This will be detected!
)
# GOOD: Password from environment
import os
conn = psycopg2.connect(
host="localhost",
database="mydb",
user="admin",
password=os.environ.get("DB_PASSWORD")
)Now run Code Pathfinder with your rule:
pathfinder scan --rules my_first_rule.py --project .Understanding the Output
You'll see output like this:
[high] hardcoded-password
CWE: CWE-798
Detects hardcoded passwords in database connections
→ test_app.py:4
Found call to 'connect' with password argument
The rule correctly identified the hardcoded password on line 4!
Making It Better
Let's improve the rule to catch more patterns. Update my_first_rule.py:
from codepathfinder import rule, calls, Or
@rule(
id="hardcoded-password",
severity="high",
cwe="CWE-798"
)
def detect_hardcoded_password():
"""Detects hardcoded passwords in database and API connections"""
return Or(
# Database connections
calls("connect", match_name={"password": "*"}),
calls("*.connect", match_name={"password": "*"}),
# HTTP Basic Auth
calls("HTTPBasicAuth", match_position={1: "*"}),
calls("requests.*", match_name={"auth": "*"}),
# Generic password variables
calls("*", match_name={"password": "*", "passwd": "*", "pwd": "*"})
)Improvements made:
Or(...)- Matches if ANY pattern is found*.connect- Wildcard matches any module (psycopg2.connect, mysql.connect, etc.)match_position- Matches positional arguments (second argument in this case)- Multiple keyword names - Catches password, passwd, and pwd arguments
Next Steps
Congratulations! You've written and run your first security rule. Continue learning: