Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
661 changes: 661 additions & 0 deletions python-dsl/LICENSE

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions python-dsl/MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
include LICENSE
include README.md
include pyproject.toml
recursive-include codepathfinder *.py
recursive-exclude tests *
recursive-exclude htmlcov *
recursive-exclude .pytest_cache *
recursive-exclude .mypy_cache *
recursive-exclude .ruff_cache *
global-exclude *.pyc
global-exclude __pycache__
218 changes: 29 additions & 189 deletions python-dsl/README.md
Original file line number Diff line number Diff line change
@@ -1,210 +1,50 @@
# Code-Pathfinder Python DSL

Python DSL for defining security patterns in code-pathfinder.
Python DSL for defining security patterns in Code Pathfinder - an open-source security suite combining structural code analysis with AI-powered vulnerability detection.

**Project Goals:**
- Real-time IDE integration bringing security insights directly into your editor
- AI-assisted analysis leveraging LLMs to understand context and identify vulnerabilities
- Unified workflow coverage from local development to CI/CD pipelines
- Flexible reporting supporting DefectDojo, GitHub Advanced Security, SARIF, and other platforms

**Documentation**: https://codepathfinder.dev/

## Installation

```bash
pip install codepathfinder
```

## Quick Start

```python
from codepathfinder import rule, calls, variable

@rule(id="code-injection", severity="critical", cwe="CWE-94")
def detect_eval():
"""Detects dangerous code execution via eval/exec"""
return calls("eval", "exec")

@rule(id="user-input", severity="high")
def detect_user_input():
"""Detects user input variables"""
return variable("user_input")
```

## Core Matchers

### `calls(*patterns)`

Matches function/method calls.
## Quick Example

```python
from codepathfinder import calls

# Exact match
calls("eval")

# Multiple patterns
calls("eval", "exec", "compile")

# Wildcard patterns
calls("request.*") # Matches request.GET, request.POST, etc.
calls("*.execute") # Matches cursor.execute, conn.execute, etc.
```

### `variable(pattern)`

Matches variable references.

```python
from codepathfinder import variable

# Exact match
variable("user_input")

# Wildcard patterns
variable("user_*") # Matches user_input, user_data, etc.
variable("*_id") # Matches user_id, post_id, etc.
```

## Dataflow Analysis

### `flows(from_sources, to_sinks, sanitized_by=None, propagates_through=None, scope="global")`

Tracks tainted data flow from sources to sinks for OWASP Top 10 vulnerability detection.

```python
from codepathfinder import flows, calls, propagates

# SQL Injection
flows(
from_sources=calls("request.GET", "request.POST"),
to_sinks=calls("execute", "executemany"),
sanitized_by=calls("quote_sql"),
propagates_through=[
propagates.assignment(),
propagates.function_args(),
],
scope="global"
)

# Command Injection
flows(
from_sources=calls("request.POST"),
to_sinks=calls("os.system", "subprocess.call"),
sanitized_by=calls("shlex.quote"),
propagates_through=[
propagates.assignment(),
propagates.function_args(),
propagates.function_returns(),
]
)

# Path Traversal
flows(
from_sources=calls("request.GET"),
to_sinks=calls("open", "os.path.join"),
sanitized_by=calls("os.path.abspath"),
propagates_through=[propagates.assignment()],
scope="local"
)
```
from codepathfinder import rule, flows, calls
from codepathfinder.presets import PropagationPresets

**Parameters:**
- `from_sources`: Source matcher(s) where taint originates (e.g., user input)
- `to_sinks`: Sink matcher(s) for dangerous functions
- `sanitized_by` (optional): Sanitizer matcher(s) that neutralize taint
- `propagates_through` (optional): List of propagation primitives (EXPLICIT!)
- `scope`: `"local"` (intra-procedural) or `"global"` (inter-procedural, default)

### Propagation Primitives

Propagation primitives define HOW taint flows through code:

```python
from codepathfinder import propagates

# Phase 1 (Available Now):
propagates.assignment() # x = tainted
propagates.function_args() # func(tainted)
propagates.function_returns() # return tainted
```

**Important:** Propagation is EXPLICIT - you must specify which primitives to enable. No defaults are applied.

## Rule Decorator

The `@rule` decorator marks functions as security rules with metadata.

```python
from codepathfinder import rule, calls

@rule(
id="sqli-001",
severity="critical",
cwe="CWE-89",
owasp="A03:2021"
)
@rule(id="sql-injection", severity="critical", cwe="CWE-89")
def detect_sql_injection():
"""Detects SQL injection vulnerabilities"""
return calls("execute", "executemany", "raw")
```

**Parameters:**
- `id` (str): Unique rule identifier
- `severity` (str): `critical` | `high` | `medium` | `low`
- `cwe` (str, optional): CWE identifier (e.g., "CWE-89")
- `owasp` (str, optional): OWASP category (e.g., "A03:2021")

The function docstring becomes the rule description.

## JSON IR Output

Rules serialize to JSON Intermediate Representation (IR) for the Go executor:

```python
from codepathfinder import rule, calls
import json

@rule(id="test", severity="high")
def my_rule():
return calls("eval")

# Serialize to JSON IR
ir = my_rule.execute()
print(json.dumps(ir, indent=2))
return flows(
from_sources=calls("request.GET", "request.POST"),
to_sinks=calls("execute", "executemany"),
sanitized_by=calls("quote_sql"),
propagates_through=PropagationPresets.standard(),
scope="global"
)
```

Output:
```json
{
"rule": {
"id": "test",
"name": "my_rule",
"severity": "high",
"cwe": null,
"owasp": null,
"description": ""
},
"matcher": {
"type": "call_matcher",
"patterns": ["eval"],
"wildcard": false,
"match_mode": "any"
}
}
```

## Development

```bash
# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest
## Features

# Format code
black codepathfinder/ tests/
- **Matchers**: `calls()`, `variable()` for pattern matching
- **Dataflow Analysis**: `flows()` for source-to-sink taint tracking
- **Propagation**: Explicit propagation primitives (assignment, function args, returns)
- **Logic Operators**: `And()`, `Or()`, `Not()` for complex rules
- **JSON IR**: Serializes to JSON for Go executor integration

# Lint
ruff check codepathfinder/ tests/
## Documentation

# Type check
mypy codepathfinder/
```
For detailed documentation, visit https://codepathfinder.dev/

## Requirements

Expand All @@ -213,4 +53,4 @@ mypy codepathfinder/

## License

MIT
AGPL-3.0 - GNU Affero General Public License v3
25 changes: 24 additions & 1 deletion python-dsl/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,30 @@ version = "1.0.0"
description = "Python DSL for code-pathfinder security patterns"
readme = "README.md"
requires-python = ">=3.8"
license = {text = "MIT"}
license = {text = "AGPL-3.0"}
authors = [{name = "code-pathfinder contributors"}]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Affero General Public License v3",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Security",
"Topic :: Software Development :: Testing",
]

[project.optional-dependencies]
dev = [
"pytest>=7.0.0",
"pytest-cov>=4.0.0",
"black>=23.0.0",
"mypy>=1.0.0",
"ruff>=0.1.0",
]

[tool.pytest.ini_options]
testpaths = ["tests"]
Expand Down
3 changes: 2 additions & 1 deletion python-dsl/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
url="https://github.com/shivasurya/code-pathfinder",
packages=find_packages(exclude=["tests", "tests.*"]),
python_requires=">=3.8",
license="AGPL-3.0",
install_requires=[
# No external dependencies (stdlib only!)
],
Expand All @@ -40,7 +41,7 @@
classifiers=[
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"License :: OSI Approved :: GNU Affero General Public License v3",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
Expand Down
Loading
Loading