# phptaint
Security-focused PHP lexer, parser, and taint analysis engine with configurable sink registries.
`phptaint` is designed for security tooling rather than full-fidelity PHP compilation. It parses the PHP constructs that matter for taint analysis, tracks flows from superglobals into sinks, supports framework presets, and now loads custom registry rules from TOML.
## Features
- PHP lexer with span tracking
- AST and parser for security-relevant PHP constructs
- Taint analysis across assignments, calls, methods, hooks, and user-defined functions
- Built-in registries for `php_core`, `wordpress`, and `laravel`
- TOML-backed custom sink and sanitizer registry loading
- Support for modern constructs including `match`, `enum`, and `readonly`
- Single-file and multi-file analysis
## Installation
```toml
[dependencies]
phptaint = "0.1"
```
## Quick Start
```rust
use phptaint::{analyze, TaintRegistry};
let findings = analyze(
"sample.php",
r#"<?php
$cmd = $_GET['cmd'];
eval($cmd);
"#,
&TaintRegistry::php_core(),
);
## Modern PHP Constructs
The parser intentionally supports a focused subset of modern PHP that commonly appears in real applications and plugins:
- `match` expressions
- `enum` declarations, including backed enums
- `readonly class` declarations and readonly property modifiers
- nullsafe calls, closures, arrow functions, hooks, and common control flow
Example:
```rust
use phptaint::{analyze, TaintRegistry};
let findings = analyze(
"match.php",
r#"<?php
$payload = match($kind) {
"cmd" => $_GET['cmd'],
default => "id",
};
eval($payload);
"#,
&TaintRegistry::php_core(),
);
## Built-In Registries
Use the built-in presets directly:
```rust
use phptaint::{analyze, TaintRegistry};
let source = r#"<?php
$url = $_GET['redirect'];
wp_redirect($url);
"#;
let findings = analyze("plugin.php", source, &TaintRegistry::wordpress());
## TOML Registry Configuration
Custom sinks and sanitizers can now be loaded from TOML with `RegistryFile`:
```rust
use phptaint::{analyze, RegistryFile};
let registry = RegistryFile::from_toml(
r#"
presets = ["php_core"]
sanitizers = ["safe_template"]
[[sinks]]
function = "render_template"
dangerous_args = [0]
category = "SSTI"
severity = "high"
[[method_sinks]]
object_pattern = "renderer"
method = "render"
dangerous_args = [0]
category = "SSTI"
severity = "critical"
"#,
"<inline>",
)?
.into_registry()?;
let findings = analyze(
"custom.php",
r#"<?php
$tpl = $_GET['tpl'];
render_template($tpl);
"#,
®istry,
);
```
## Multi-File Analysis
```rust
use phptaint::{analyze_multi, TaintRegistry};
let findings = analyze_multi(
&[
("a.php", "<?php function run_cmd($value) { exec($value); }"),
("b.php", "<?php $cmd = $_GET['cmd']; run_cmd($cmd);"),
],
&TaintRegistry::php_core(),
);
## Examples
Run the bundled examples:
```bash
cargo run --example basic
cargo run --example toml_registry
```
## Development
- `cargo fmt`
- `cargo check --all-targets`
- `cargo test`
## License
MIT