fourisnotrandom 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fourisnotrandom-0.1.0/LICENSE +21 -0
- fourisnotrandom-0.1.0/PKG-INFO +122 -0
- fourisnotrandom-0.1.0/README.md +102 -0
- fourisnotrandom-0.1.0/pyproject.toml +37 -0
- fourisnotrandom-0.1.0/setup.cfg +4 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/__init__.py +3 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/__main__.py +6 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/checks/__init__.py +1 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/checks/apps.py +81 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/checks/emudhra.py +535 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/checks/gitlab.py +152 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/checks/litellm.py +315 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/checks/php.py +429 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/cli.py +312 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/config_loader.py +79 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/data/__init__.py +1 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/data/compromised_hashes.json +55 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/data/fixed_versions.yaml +75 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/data/php_apps.yaml +42 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/models.py +43 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/report.py +61 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/targets.py +67 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom/versioning.py +262 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom.egg-info/PKG-INFO +122 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom.egg-info/SOURCES.txt +34 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom.egg-info/dependency_links.txt +1 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom.egg-info/entry_points.txt +2 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom.egg-info/requires.txt +9 -0
- fourisnotrandom-0.1.0/src/fourisnotrandom.egg-info/top_level.txt +1 -0
- fourisnotrandom-0.1.0/tests/test_emudhra_match.py +52 -0
- fourisnotrandom-0.1.0/tests/test_gitlab_compare.py +68 -0
- fourisnotrandom-0.1.0/tests/test_known_cves.py +327 -0
- fourisnotrandom-0.1.0/tests/test_litellm_pin.py +22 -0
- fourisnotrandom-0.1.0/tests/test_php_compare.py +35 -0
- fourisnotrandom-0.1.0/tests/test_targets.py +25 -0
- fourisnotrandom-0.1.0/tests/test_versioning.py +46 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 FourIsNotRandom
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fourisnotrandom
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Detection-only CLI that fingerprints versions/config for known CVE exposure (no exploit payloads).
|
|
5
|
+
Author: FourIsNotRandom
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: cve,security,fingerprint,detection-only
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: typer>=0.12
|
|
12
|
+
Requires-Dist: rich>=13
|
|
13
|
+
Requires-Dist: PyYAML>=6
|
|
14
|
+
Requires-Dist: cryptography>=42
|
|
15
|
+
Requires-Dist: requests>=2.31
|
|
16
|
+
Requires-Dist: packaging>=23
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# FourIsNotRandom
|
|
22
|
+
|
|
23
|
+
Detection-only CLI (`fourisnotrandom`) that fingerprints software versions and TLS/CA configuration to report exposure to a small set of currently relevant advisories.
|
|
24
|
+
|
|
25
|
+
> **This tool performs read-only version/fingerprint checks only. It does not exploit, does not send attack payloads, and must only be run against systems you own or are authorized to assess.**
|
|
26
|
+
|
|
27
|
+
## What it checks
|
|
28
|
+
|
|
29
|
+
| Area | Advisories | Detection methods |
|
|
30
|
+
|------|------------|-------------------|
|
|
31
|
+
| PHP | CVE-2026-109618, CVE-2026-109619 | Local `php -v`/`php -i`, HTTP headers, Docker/FS manifests, webroot app stacks |
|
|
32
|
+
| eMudhra CA | CVE-2026-111943 / related distrust | TLS chain digests, PEM/keystore files, Docker CA bundles, Go + certifi versions |
|
|
33
|
+
| GitLab | CVE-2026-110264, CVE-2026-97229 | Public `/help` or `/api/v4/version` (read-only) |
|
|
34
|
+
| LiteLLM | Malicious `1.107.0` release | Exact pin in pip env / requirements / lockfiles / Docker |
|
|
35
|
+
|
|
36
|
+
No CIDR sweeps: every run requires an explicit host, URL, path, image name, or a targets file of discrete entries.
|
|
37
|
+
|
|
38
|
+
## Install
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
python -m pip install -U pip
|
|
42
|
+
pip install -e ".[dev]"
|
|
43
|
+
fourisnotrandom --help
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Auditing this tool's own dependencies
|
|
47
|
+
|
|
48
|
+
Run `pip-audit` against the pinned requirements file - **not** bare `pip-audit`:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip-audit -r requirements.txt
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
A bare `pip-audit` run audits your entire environment and will also flag the
|
|
55
|
+
venv's bootstrap `pip` package, which is unrelated to this tool's dependencies.
|
|
56
|
+
Use `pip-audit -r requirements.txt` so findings reflect only what this project
|
|
57
|
+
declares.
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# PHP
|
|
63
|
+
fourisnotrandom php --local
|
|
64
|
+
fourisnotrandom php --local --php-bin /usr/bin/php8.3
|
|
65
|
+
fourisnotrandom php --url https://example.com/
|
|
66
|
+
fourisnotrandom php --fs /var/www/html
|
|
67
|
+
|
|
68
|
+
# eMudhra / toolchains
|
|
69
|
+
fourisnotrandom emudhra --host example.com
|
|
70
|
+
fourisnotrandom emudhra --path /etc/ssl/certs
|
|
71
|
+
fourisnotrandom emudhra --docker my-image:tag
|
|
72
|
+
fourisnotrandom emudhra --toolchains
|
|
73
|
+
|
|
74
|
+
# GitLab (both CVSS 10.0 CVEs evaluated separately)
|
|
75
|
+
fourisnotrandom gitlab --url https://gitlab.example.com
|
|
76
|
+
|
|
77
|
+
# LiteLLM exact compromised pin
|
|
78
|
+
fourisnotrandom litellm --env
|
|
79
|
+
fourisnotrandom litellm --path .
|
|
80
|
+
fourisnotrandom litellm --docker ghcr.io/berriai/litellm:v1.107.0
|
|
81
|
+
|
|
82
|
+
# Explicit target list only (global flags before the subcommand)
|
|
83
|
+
fourisnotrandom --format json all --targets-file targets.txt
|
|
84
|
+
fourisnotrandom --format json emudhra toolchains
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Exit codes: `0` = no FAIL, `1` = at least one FAIL, `2` = tool/config error.
|
|
88
|
+
|
|
89
|
+
## Advisory data (editable)
|
|
90
|
+
|
|
91
|
+
Bundled under `src/fourisnotrandom/data/`:
|
|
92
|
+
|
|
93
|
+
| File | Contents | How to refresh |
|
|
94
|
+
|------|----------|----------------|
|
|
95
|
+
| `fixed_versions.yaml` | PHP floors, GitLab per-CVE floors, Go floors, certifi floor, LiteLLM pin | Edit YAML; or pass `--config PATH` |
|
|
96
|
+
| `compromised_hashes.json` | Compromised eMudhra intermediate digests | Replace file or `fourisnotrandom update-hashes --from PATH` |
|
|
97
|
+
| `php_apps.yaml` | CMS/webroot path fingerprints | Edit YAML |
|
|
98
|
+
|
|
99
|
+
### Data provenance
|
|
100
|
+
|
|
101
|
+
- **PHP floors**: PHP project security releases (8.2.35, 8.3.36, 8.4.27, 8.5.12). Branches ≤8.1 have no upstream fix.
|
|
102
|
+
- **GitLab**: Official critical patch notes for CVE-2026-110264 (Oct 21) and CVE-2026-97229 (Oct 12). Both are reported separately so an Oct-12-only patch does not look “fully covered.”
|
|
103
|
+
- **eMudhra hashes**: Certificate SHA-256 fingerprints from Cisco Talos “Compromised eMudhra intermediate certificates” (Oct 21, 2026), citing Mozilla Bugzilla 2083449. The scanner matches **either** full-cert SHA-256 **or** SPKI SHA-256 against the configured set (Talos publishes cert fingerprints; Go’s CVE-2026-111943 fix matches SPKI - dual match avoids assuming hash type after a refresh).
|
|
104
|
+
- **certifi**: Floor `2026.10.18` (first release blocking compromised roots). `2026.10.19` restores some legitimate emSign roots (stability), not a security boundary.
|
|
105
|
+
- **Go**: Fixed in 1.27.3 / 1.26.10 (CVE-2026-111943).
|
|
106
|
+
- **LiteLLM**: Exact malicious PyPI/Docker release `1.107.0` only.
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Refresh eMudhra hash list from a JSON file with the same schema
|
|
110
|
+
fourisnotrandom update-hashes --from ./my-hashes.json
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Safety
|
|
114
|
+
|
|
115
|
+
> **Read-only / authorized use only.** This tool fingerprints versions and TLS/CA
|
|
116
|
+
> material. It does not exploit, does not send attack payloads, and must only be
|
|
117
|
+
> run against systems you own or are authorized to assess.
|
|
118
|
+
|
|
119
|
+
- Fingerprints only: versions, headers, banners, cert digests, read-only `php.ini` values.
|
|
120
|
+
- Does **not** send session.upload_progress exploits, memory-corruption probes, or any PoC payloads.
|
|
121
|
+
- Does **not** scan networks you did not name explicitly.
|
|
122
|
+
- Rejects CIDR ranges and bare wildcards - every target must be an explicit host, URL, or path.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# FourIsNotRandom
|
|
2
|
+
|
|
3
|
+
Detection-only CLI (`fourisnotrandom`) that fingerprints software versions and TLS/CA configuration to report exposure to a small set of currently relevant advisories.
|
|
4
|
+
|
|
5
|
+
> **This tool performs read-only version/fingerprint checks only. It does not exploit, does not send attack payloads, and must only be run against systems you own or are authorized to assess.**
|
|
6
|
+
|
|
7
|
+
## What it checks
|
|
8
|
+
|
|
9
|
+
| Area | Advisories | Detection methods |
|
|
10
|
+
|------|------------|-------------------|
|
|
11
|
+
| PHP | CVE-2026-109618, CVE-2026-109619 | Local `php -v`/`php -i`, HTTP headers, Docker/FS manifests, webroot app stacks |
|
|
12
|
+
| eMudhra CA | CVE-2026-111943 / related distrust | TLS chain digests, PEM/keystore files, Docker CA bundles, Go + certifi versions |
|
|
13
|
+
| GitLab | CVE-2026-110264, CVE-2026-97229 | Public `/help` or `/api/v4/version` (read-only) |
|
|
14
|
+
| LiteLLM | Malicious `1.107.0` release | Exact pin in pip env / requirements / lockfiles / Docker |
|
|
15
|
+
|
|
16
|
+
No CIDR sweeps: every run requires an explicit host, URL, path, image name, or a targets file of discrete entries.
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
python -m pip install -U pip
|
|
22
|
+
pip install -e ".[dev]"
|
|
23
|
+
fourisnotrandom --help
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Auditing this tool's own dependencies
|
|
27
|
+
|
|
28
|
+
Run `pip-audit` against the pinned requirements file - **not** bare `pip-audit`:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip-audit -r requirements.txt
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
A bare `pip-audit` run audits your entire environment and will also flag the
|
|
35
|
+
venv's bootstrap `pip` package, which is unrelated to this tool's dependencies.
|
|
36
|
+
Use `pip-audit -r requirements.txt` so findings reflect only what this project
|
|
37
|
+
declares.
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# PHP
|
|
43
|
+
fourisnotrandom php --local
|
|
44
|
+
fourisnotrandom php --local --php-bin /usr/bin/php8.3
|
|
45
|
+
fourisnotrandom php --url https://example.com/
|
|
46
|
+
fourisnotrandom php --fs /var/www/html
|
|
47
|
+
|
|
48
|
+
# eMudhra / toolchains
|
|
49
|
+
fourisnotrandom emudhra --host example.com
|
|
50
|
+
fourisnotrandom emudhra --path /etc/ssl/certs
|
|
51
|
+
fourisnotrandom emudhra --docker my-image:tag
|
|
52
|
+
fourisnotrandom emudhra --toolchains
|
|
53
|
+
|
|
54
|
+
# GitLab (both CVSS 10.0 CVEs evaluated separately)
|
|
55
|
+
fourisnotrandom gitlab --url https://gitlab.example.com
|
|
56
|
+
|
|
57
|
+
# LiteLLM exact compromised pin
|
|
58
|
+
fourisnotrandom litellm --env
|
|
59
|
+
fourisnotrandom litellm --path .
|
|
60
|
+
fourisnotrandom litellm --docker ghcr.io/berriai/litellm:v1.107.0
|
|
61
|
+
|
|
62
|
+
# Explicit target list only (global flags before the subcommand)
|
|
63
|
+
fourisnotrandom --format json all --targets-file targets.txt
|
|
64
|
+
fourisnotrandom --format json emudhra toolchains
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Exit codes: `0` = no FAIL, `1` = at least one FAIL, `2` = tool/config error.
|
|
68
|
+
|
|
69
|
+
## Advisory data (editable)
|
|
70
|
+
|
|
71
|
+
Bundled under `src/fourisnotrandom/data/`:
|
|
72
|
+
|
|
73
|
+
| File | Contents | How to refresh |
|
|
74
|
+
|------|----------|----------------|
|
|
75
|
+
| `fixed_versions.yaml` | PHP floors, GitLab per-CVE floors, Go floors, certifi floor, LiteLLM pin | Edit YAML; or pass `--config PATH` |
|
|
76
|
+
| `compromised_hashes.json` | Compromised eMudhra intermediate digests | Replace file or `fourisnotrandom update-hashes --from PATH` |
|
|
77
|
+
| `php_apps.yaml` | CMS/webroot path fingerprints | Edit YAML |
|
|
78
|
+
|
|
79
|
+
### Data provenance
|
|
80
|
+
|
|
81
|
+
- **PHP floors**: PHP project security releases (8.2.35, 8.3.36, 8.4.27, 8.5.12). Branches ≤8.1 have no upstream fix.
|
|
82
|
+
- **GitLab**: Official critical patch notes for CVE-2026-110264 (Oct 21) and CVE-2026-97229 (Oct 12). Both are reported separately so an Oct-12-only patch does not look “fully covered.”
|
|
83
|
+
- **eMudhra hashes**: Certificate SHA-256 fingerprints from Cisco Talos “Compromised eMudhra intermediate certificates” (Oct 21, 2026), citing Mozilla Bugzilla 2083449. The scanner matches **either** full-cert SHA-256 **or** SPKI SHA-256 against the configured set (Talos publishes cert fingerprints; Go’s CVE-2026-111943 fix matches SPKI - dual match avoids assuming hash type after a refresh).
|
|
84
|
+
- **certifi**: Floor `2026.10.18` (first release blocking compromised roots). `2026.10.19` restores some legitimate emSign roots (stability), not a security boundary.
|
|
85
|
+
- **Go**: Fixed in 1.27.3 / 1.26.10 (CVE-2026-111943).
|
|
86
|
+
- **LiteLLM**: Exact malicious PyPI/Docker release `1.107.0` only.
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Refresh eMudhra hash list from a JSON file with the same schema
|
|
90
|
+
fourisnotrandom update-hashes --from ./my-hashes.json
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Safety
|
|
94
|
+
|
|
95
|
+
> **Read-only / authorized use only.** This tool fingerprints versions and TLS/CA
|
|
96
|
+
> material. It does not exploit, does not send attack payloads, and must only be
|
|
97
|
+
> run against systems you own or are authorized to assess.
|
|
98
|
+
|
|
99
|
+
- Fingerprints only: versions, headers, banners, cert digests, read-only `php.ini` values.
|
|
100
|
+
- Does **not** send session.upload_progress exploits, memory-corruption probes, or any PoC payloads.
|
|
101
|
+
- Does **not** scan networks you did not name explicitly.
|
|
102
|
+
- Rejects CIDR ranges and bare wildcards - every target must be an explicit host, URL, or path.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "fourisnotrandom"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Detection-only CLI that fingerprints versions/config for known CVE exposure (no exploit payloads)."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [{ name = "FourIsNotRandom" }]
|
|
13
|
+
keywords = ["cve", "security", "fingerprint", "detection-only"]
|
|
14
|
+
dependencies = [
|
|
15
|
+
"typer>=0.12",
|
|
16
|
+
"rich>=13",
|
|
17
|
+
"PyYAML>=6",
|
|
18
|
+
"cryptography>=42",
|
|
19
|
+
"requests>=2.31",
|
|
20
|
+
"packaging>=23",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.optional-dependencies]
|
|
24
|
+
dev = ["pytest>=8"]
|
|
25
|
+
|
|
26
|
+
[project.scripts]
|
|
27
|
+
fourisnotrandom = "fourisnotrandom.cli:app"
|
|
28
|
+
|
|
29
|
+
[tool.setuptools.packages.find]
|
|
30
|
+
where = ["src"]
|
|
31
|
+
|
|
32
|
+
[tool.setuptools.package-data]
|
|
33
|
+
fourisnotrandom = ["data/*.yaml", "data/*.json"]
|
|
34
|
+
|
|
35
|
+
[tool.pytest.ini_options]
|
|
36
|
+
testpaths = ["tests"]
|
|
37
|
+
pythonpath = ["src"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Detection-only check modules."""
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from fourisnotrandom.config_loader import load_php_apps
|
|
8
|
+
from fourisnotrandom.models import Finding, Status
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def detect_php_apps(
|
|
12
|
+
root: Path,
|
|
13
|
+
php_version: str | None = None,
|
|
14
|
+
php_status: str | None = None,
|
|
15
|
+
apps_config: dict[str, Any] | None = None,
|
|
16
|
+
) -> list[Finding]:
|
|
17
|
+
"""Detect common PHP application stacks under a webroot (read-only)."""
|
|
18
|
+
cfg = apps_config or load_php_apps()
|
|
19
|
+
findings: list[Finding] = []
|
|
20
|
+
root = Path(root)
|
|
21
|
+
|
|
22
|
+
for app in cfg.get("apps", []):
|
|
23
|
+
name = app.get("name", "unknown")
|
|
24
|
+
matched = False
|
|
25
|
+
version_hint = ""
|
|
26
|
+
for marker in app.get("markers", []):
|
|
27
|
+
rel = marker.get("path")
|
|
28
|
+
if not rel:
|
|
29
|
+
continue
|
|
30
|
+
path = root / rel
|
|
31
|
+
if not path.is_file():
|
|
32
|
+
continue
|
|
33
|
+
try:
|
|
34
|
+
text = path.read_text(encoding="utf-8", errors="ignore")
|
|
35
|
+
except OSError:
|
|
36
|
+
continue
|
|
37
|
+
contains = marker.get("contains")
|
|
38
|
+
if contains and contains not in text:
|
|
39
|
+
continue
|
|
40
|
+
pattern = marker.get("pattern")
|
|
41
|
+
if pattern:
|
|
42
|
+
m = re.search(pattern, text)
|
|
43
|
+
if not m:
|
|
44
|
+
continue
|
|
45
|
+
version_hint = m.group(1).strip() if m.lastindex else ""
|
|
46
|
+
matched = True
|
|
47
|
+
break
|
|
48
|
+
|
|
49
|
+
if not matched:
|
|
50
|
+
continue
|
|
51
|
+
|
|
52
|
+
if php_status == "FAIL":
|
|
53
|
+
status = Status.FAIL
|
|
54
|
+
remediation = (
|
|
55
|
+
f"{name} detected on vulnerable PHP {php_version or '?'}; "
|
|
56
|
+
"upgrade PHP (and review app compatibility)."
|
|
57
|
+
)
|
|
58
|
+
elif php_version:
|
|
59
|
+
status = Status.PASS if php_status == "PASS" else Status.UNKNOWN
|
|
60
|
+
remediation = (
|
|
61
|
+
f"{name} detected; confirm PHP {php_version} is on a fixed branch."
|
|
62
|
+
if status != Status.PASS
|
|
63
|
+
else f"{name} detected; PHP version appears fixed."
|
|
64
|
+
)
|
|
65
|
+
else:
|
|
66
|
+
status = Status.UNKNOWN
|
|
67
|
+
remediation = f"{name} detected; PHP version not determined - run a PHP check."
|
|
68
|
+
|
|
69
|
+
findings.append(
|
|
70
|
+
Finding(
|
|
71
|
+
status=status,
|
|
72
|
+
cve="CVE-2026-109618/CVE-2026-109619",
|
|
73
|
+
target=str(root),
|
|
74
|
+
installed=f"{name}" + (f" {version_hint}" if version_hint else ""),
|
|
75
|
+
fixed="PHP fixed branch (see php check)",
|
|
76
|
+
remediation=remediation,
|
|
77
|
+
detail="application_stack",
|
|
78
|
+
extra={"app": name, "app_version": version_hint, "php_version": php_version},
|
|
79
|
+
)
|
|
80
|
+
)
|
|
81
|
+
return findings
|