attackmap-analyzer-php-web 0.2.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Matthew Davis and AttackMap Contributors
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,160 @@
1
+ Metadata-Version: 2.4
2
+ Name: attackmap-analyzer-php-web
3
+ Version: 0.2.0
4
+ Summary: Broad PHP web analyzer plugin for AttackMap
5
+ Author: AttackMap Contributors
6
+ Author-email: Matthew Davis <mlaify@mlaify.io>
7
+ Maintainer-email: Matthew Davis <mlaify@mlaify.io>
8
+ License-Expression: MIT
9
+ Project-URL: Homepage, https://github.com/mlaify/attackmap-analyzer-php-web
10
+ Project-URL: Repository, https://github.com/mlaify/attackmap-analyzer-php-web
11
+ Project-URL: Issues, https://github.com/mlaify/attackmap-analyzer-php-web/issues
12
+ Project-URL: Changelog, https://github.com/mlaify/attackmap-analyzer-php-web/blob/main/CHANGELOG.md
13
+ Project-URL: AttackMap core, https://github.com/mlaify/AttackMap
14
+ Keywords: security,static-analysis,appsec,defensive-security,attackmap,attackmap-plugin
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Intended Audience :: Information Technology
18
+ Classifier: Intended Audience :: System Administrators
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3 :: Only
25
+ Classifier: Topic :: Security
26
+ Classifier: Topic :: Software Development :: Quality Assurance
27
+ Classifier: Typing :: Typed
28
+ Requires-Python: >=3.11
29
+ Description-Content-Type: text/markdown
30
+ License-File: LICENSE
31
+ Requires-Dist: pydantic>=2.7.0
32
+ Provides-Extra: core
33
+ Requires-Dist: attackmap>=0.6.0; extra == "core"
34
+ Provides-Extra: dev
35
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
36
+ Requires-Dist: build>=1.2.0; extra == "dev"
37
+ Requires-Dist: attackmap>=0.6.0; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # attackmap-analyzer-php-web
41
+
42
+ > [!IMPORTANT]
43
+ > **Active development, slow pace.** AttackMap is under active development, but
44
+ > progress may be slow until more contributors or co-maintainers join. Help is
45
+ > very welcome with the core engine, an analyzer, the macOS app, or the docs —
46
+ > see [CONTRIBUTING.md](CONTRIBUTING.md) or open an issue on
47
+ > [mlaify/AttackMap](https://github.com/mlaify/AttackMap/issues) to say hello.
48
+ > Security reports are still welcome at [security@mlaify.io](mailto:security@mlaify.io).
49
+
50
+ Broad PHP web analyzer for [AttackMap](https://github.com/mlaify/AttackMap).
51
+
52
+ This repository is intentionally separate from AttackMap core. It focuses only on extracting structured signals from PHP repositories:
53
+
54
+ - routes
55
+ - outbound HTTP calls
56
+ - datastore hints
57
+ - auth hints
58
+ - secret and env usage
59
+
60
+ It does not render reports and does not own global severity policy.
61
+
62
+ ## Analyzer identity
63
+
64
+ - `name`: `php-web`
65
+ - `display_name`: `PHP Web Analyzer`
66
+ - `version`: `0.1.0`
67
+ - `experimental`: `true`
68
+ - `enabled_by_default`: `false`
69
+
70
+ ## Scope
71
+
72
+ This analyzer is broad and heuristic. It is meant to map common PHP web application surfaces before framework-specific analyzers (for example `php-laminas` or `omeka-s`) are added.
73
+
74
+ ## Detection strategy
75
+
76
+ `detect(repo_path)` uses lightweight signals:
77
+
78
+ - `composer.json` present, or
79
+ - at least one `.php` file outside `vendor/` (and the other shared skip dirs)
80
+
81
+ A `src/`, `app/` or `config/` directory on its own is not enough, since Python, Go and Java repos have those too.
82
+
83
+ ## Extraction strategy
84
+
85
+ `analyze(repo_path)` scans `.php` files and emits structured signals using regular-expression heuristics.
86
+
87
+ Route extraction currently includes patterns such as:
88
+
89
+ - Laravel `Route::get|post|put|patch|delete|options|head|any(...)`, array-first `Route::match(['get', 'post'], ...)`, and a scope chained before the verb (`Route::middleware('auth')->get(...)`). `Route::resource` / `apiResource` / `resources` / `apiResources` expand to their REST routes (7 / 5 actions; `update` is `PUT` and `PATCH`), honouring `->only()` / `->except()` / `->shallow()`, an `['only' => ...]` options array and nested `photos.comments` names.
90
+ - Laravel groups: `Route::prefix('admin')->middleware(...)->group(function () { ... })` and `Route::group(['prefix' => ..., 'middleware' => ...], fn)` join their prefixes onto the routes inside, at any nesting depth up to 32. `Route::controller(C::class)->group(...)` dispatches bare method names to `C`.
91
+ - Laravel route files take the prefix and middleware of the group that loads them: `->group(base_path('routes/admin.php'))`, `require base_path(...)` / `$this->loadRoutesFrom(__DIR__.'/...')` inside a group, and `withRouting(api: ... | [...], apiPrefix: ...)` in `bootstrap/app.php`. `routes/api.php` defaults to `/api` when nothing outside test code mounts it. A `require_once` that loops back to a file already being loaded is a no-op. A `config('file.key')` prefix is read from `config/file.php` (a literal or an `env()` default), and any other non-literal prefix becomes a `{prefix}` segment.
92
+ - `$app->get('/path', ...)` / `$app->map(['GET', 'POST'], '/path', ...)` Slim calls. The path must start with `/`, and the receiver must be `$app`, `$router`, `$route`, `$group` or `$r`, a variable assigned from `AppFactory::create()` / `new RouteCollector` / `new App`, or a parameter typed `RouteCollectorProxy` / `RouteCollector` / `App`. This keeps `$request->get('id')` and `$cache->get('k')` out. Slim `$app->group('/v1', ...)` and Lumen `$router->group(['prefix' => 'api'], ...)` prefixes are joined.
93
+ - Symfony `#[Route('/path', methods: ['GET'])]` (or `path:`) attributes, joined onto the class-level `#[Route('/prefix')]` (whose `methods` merge in). A class-level route is a route of its own only on a controller with no routed actions (`__invoke`).
94
+ - Symfony route config, loaded in the kernel's order (`config/routes/*.yaml` sorted, then `config/routes.yaml`; plus Symfony 2/3's `app/config/routing.yml`; other files only when imported): `path` / `methods` entries, and `resource` imports with a `prefix`, applied to attribute controllers under the imported directory (or `routing.controllers`, i.e. `src/`) or to an imported local route file. A later import of the same controllers or route file with the same `name_prefix` replaces the earlier one (Symfony keys routes by name), so each route is reported once per distinct name prefix, under the last import's prefix. A localized prefix map becomes a `{prefix}` segment. Localized path maps and `when@dev` / `when@test` blocks are skipped.
95
+ - config-style `"path" => "/..."`, only in files that also declare a `'routes'` / `'router'` key (so Laravel's `config/logging.php` paths aren't routes)
96
+
97
+ Brackets are matched in one string-, comment- and heredoc-aware pass per file, so a commented-out `Route::get(...)` is not a route and a `}` inside a string doesn't end a group.
98
+
99
+ Each route carries `auth`, `guards` and `guard_evidence` (AttackMap#256):
100
+
101
+ | State | When |
102
+ |---|---|
103
+ | `required` | Laravel `->middleware('auth'…)` on the route, an enclosing `Route::middleware([...])->group(...)` / `Route::group(['middleware' => ...], ...)`, or the controller's `$this->middleware('auth')` (honouring `->only()` / `->except()`); Slim `->add($authMiddleware)` / `->add(new JwtAuthentication(...))` on the route or an enclosing `->group(...)`; Symfony `#[IsGranted]` / `#[Security]` on the action or its class, or a matching `security.yaml` `access_control` rule |
104
+ | `anonymous` | Laravel `->withoutMiddleware('auth')` on the route or a group, or a controller `->except([...])` naming the action; Symfony `#[IsGranted('PUBLIC_ACCESS')]` or an `access_control` rule granting `PUBLIC_ACCESS` — when nothing else requires auth |
105
+ | `unknown` | anything else |
106
+
107
+ `access_control` is only applied to rules with literal `^/prefix` paths. A rule with `ips`, `host`, `allow_if` or a regex path stops resolution for the routes after it. Rules are matched against the full path (class and import prefixes joined); attribute routes under an import prefix that can't be read (a localized prefix map) are skipped. Laravel 11 `HasMiddleware::middleware()` controllers, Slim app-wide `$app->add(...)` and `can:` middleware aren't resolved.
108
+
109
+ Outbound calls currently include patterns such as:
110
+
111
+ - `curl_init("https://...")`
112
+ - `file_get_contents("https://...")`
113
+ - common HTTP client calls such as `->request(...)`, `->get(...)`, `->post(...)`
114
+
115
+ Datastore/auth/secret hints are similarly heuristic and intended as first-pass signals. Secret hints are env var names (`getenv`, `$_ENV`, `$_SERVER`) containing `SECRET`, `TOKEN`, `KEY`, `PASSWORD` or `PASSWD`. `DB_HOST`-style connection settings are not secrets. `jwt` needs a JWT library (`Firebase\JWT\JWT`, `JWT::decode/encode`, `Lcobucci\JWT`, `tymon/jwt-auth`), and `auth` needs the `Auth::` facade or a chained `auth()->…` helper.
116
+
117
+ ## Installation
118
+
119
+ ```bash
120
+ uv tool install attackmap --with attackmap-analyzer-php-web \
121
+ --index mlaify=https://pkg.mlaify.io/pypi/simple/ --index-strategy first-index
122
+ # or from source:
123
+ pip install git+https://github.com/mlaify/attackmap-analyzer-php-web.git
124
+ ```
125
+
126
+ For local development:
127
+
128
+ ```bash
129
+ pip install -e .[dev]
130
+ ```
131
+
132
+ ## Contract alignment with AttackMap core
133
+
134
+ This package targets the current AttackMap analyzer contract:
135
+
136
+ - analyzer exposes metadata via `metadata`
137
+ - analyzer implements `detect(repo_path)` and `analyze(repo_path)`
138
+ - `analyze` returns AttackMap-style structured scan data (`ScanResult` shape)
139
+
140
+ The package includes a small compatibility layer so tests can run even if AttackMap core is not installed.
141
+
142
+ ## Future core discovery (documented, not implemented here)
143
+
144
+ AttackMap core can discover this analyzer later via one of these options:
145
+
146
+ 1. entry points (preferred long-term)
147
+ 2. explicit configured analyzer list
148
+ 3. namespace/package scanning in `github.com/mlaify`
149
+
150
+ This repository does not implement core-side discovery logic.
151
+
152
+ ## Limitations
153
+
154
+ - regex-based extraction (not AST)
155
+ - limited config route parsing; the Symfony YAML/XML readers cover the shapes Symfony's docs and recipes use, not full YAML/XML
156
+ - Laravel route names (`->name()` / `'as'`), `Route::view` / `Route::redirect` / `Route::singleton`, and resource `->parameters([...])` renames aren't modelled
157
+ - no framework-specific deep parsing yet
158
+ - no dataflow or reachability modeling inside this analyzer
159
+
160
+ These are deliberate to keep this first external analyzer incremental and maintainable.
@@ -0,0 +1,121 @@
1
+ # attackmap-analyzer-php-web
2
+
3
+ > [!IMPORTANT]
4
+ > **Active development, slow pace.** AttackMap is under active development, but
5
+ > progress may be slow until more contributors or co-maintainers join. Help is
6
+ > very welcome with the core engine, an analyzer, the macOS app, or the docs —
7
+ > see [CONTRIBUTING.md](CONTRIBUTING.md) or open an issue on
8
+ > [mlaify/AttackMap](https://github.com/mlaify/AttackMap/issues) to say hello.
9
+ > Security reports are still welcome at [security@mlaify.io](mailto:security@mlaify.io).
10
+
11
+ Broad PHP web analyzer for [AttackMap](https://github.com/mlaify/AttackMap).
12
+
13
+ This repository is intentionally separate from AttackMap core. It focuses only on extracting structured signals from PHP repositories:
14
+
15
+ - routes
16
+ - outbound HTTP calls
17
+ - datastore hints
18
+ - auth hints
19
+ - secret and env usage
20
+
21
+ It does not render reports and does not own global severity policy.
22
+
23
+ ## Analyzer identity
24
+
25
+ - `name`: `php-web`
26
+ - `display_name`: `PHP Web Analyzer`
27
+ - `version`: `0.1.0`
28
+ - `experimental`: `true`
29
+ - `enabled_by_default`: `false`
30
+
31
+ ## Scope
32
+
33
+ This analyzer is broad and heuristic. It is meant to map common PHP web application surfaces before framework-specific analyzers (for example `php-laminas` or `omeka-s`) are added.
34
+
35
+ ## Detection strategy
36
+
37
+ `detect(repo_path)` uses lightweight signals:
38
+
39
+ - `composer.json` present, or
40
+ - at least one `.php` file outside `vendor/` (and the other shared skip dirs)
41
+
42
+ A `src/`, `app/` or `config/` directory on its own is not enough, since Python, Go and Java repos have those too.
43
+
44
+ ## Extraction strategy
45
+
46
+ `analyze(repo_path)` scans `.php` files and emits structured signals using regular-expression heuristics.
47
+
48
+ Route extraction currently includes patterns such as:
49
+
50
+ - Laravel `Route::get|post|put|patch|delete|options|head|any(...)`, array-first `Route::match(['get', 'post'], ...)`, and a scope chained before the verb (`Route::middleware('auth')->get(...)`). `Route::resource` / `apiResource` / `resources` / `apiResources` expand to their REST routes (7 / 5 actions; `update` is `PUT` and `PATCH`), honouring `->only()` / `->except()` / `->shallow()`, an `['only' => ...]` options array and nested `photos.comments` names.
51
+ - Laravel groups: `Route::prefix('admin')->middleware(...)->group(function () { ... })` and `Route::group(['prefix' => ..., 'middleware' => ...], fn)` join their prefixes onto the routes inside, at any nesting depth up to 32. `Route::controller(C::class)->group(...)` dispatches bare method names to `C`.
52
+ - Laravel route files take the prefix and middleware of the group that loads them: `->group(base_path('routes/admin.php'))`, `require base_path(...)` / `$this->loadRoutesFrom(__DIR__.'/...')` inside a group, and `withRouting(api: ... | [...], apiPrefix: ...)` in `bootstrap/app.php`. `routes/api.php` defaults to `/api` when nothing outside test code mounts it. A `require_once` that loops back to a file already being loaded is a no-op. A `config('file.key')` prefix is read from `config/file.php` (a literal or an `env()` default), and any other non-literal prefix becomes a `{prefix}` segment.
53
+ - `$app->get('/path', ...)` / `$app->map(['GET', 'POST'], '/path', ...)` Slim calls. The path must start with `/`, and the receiver must be `$app`, `$router`, `$route`, `$group` or `$r`, a variable assigned from `AppFactory::create()` / `new RouteCollector` / `new App`, or a parameter typed `RouteCollectorProxy` / `RouteCollector` / `App`. This keeps `$request->get('id')` and `$cache->get('k')` out. Slim `$app->group('/v1', ...)` and Lumen `$router->group(['prefix' => 'api'], ...)` prefixes are joined.
54
+ - Symfony `#[Route('/path', methods: ['GET'])]` (or `path:`) attributes, joined onto the class-level `#[Route('/prefix')]` (whose `methods` merge in). A class-level route is a route of its own only on a controller with no routed actions (`__invoke`).
55
+ - Symfony route config, loaded in the kernel's order (`config/routes/*.yaml` sorted, then `config/routes.yaml`; plus Symfony 2/3's `app/config/routing.yml`; other files only when imported): `path` / `methods` entries, and `resource` imports with a `prefix`, applied to attribute controllers under the imported directory (or `routing.controllers`, i.e. `src/`) or to an imported local route file. A later import of the same controllers or route file with the same `name_prefix` replaces the earlier one (Symfony keys routes by name), so each route is reported once per distinct name prefix, under the last import's prefix. A localized prefix map becomes a `{prefix}` segment. Localized path maps and `when@dev` / `when@test` blocks are skipped.
56
+ - config-style `"path" => "/..."`, only in files that also declare a `'routes'` / `'router'` key (so Laravel's `config/logging.php` paths aren't routes)
57
+
58
+ Brackets are matched in one string-, comment- and heredoc-aware pass per file, so a commented-out `Route::get(...)` is not a route and a `}` inside a string doesn't end a group.
59
+
60
+ Each route carries `auth`, `guards` and `guard_evidence` (AttackMap#256):
61
+
62
+ | State | When |
63
+ |---|---|
64
+ | `required` | Laravel `->middleware('auth'…)` on the route, an enclosing `Route::middleware([...])->group(...)` / `Route::group(['middleware' => ...], ...)`, or the controller's `$this->middleware('auth')` (honouring `->only()` / `->except()`); Slim `->add($authMiddleware)` / `->add(new JwtAuthentication(...))` on the route or an enclosing `->group(...)`; Symfony `#[IsGranted]` / `#[Security]` on the action or its class, or a matching `security.yaml` `access_control` rule |
65
+ | `anonymous` | Laravel `->withoutMiddleware('auth')` on the route or a group, or a controller `->except([...])` naming the action; Symfony `#[IsGranted('PUBLIC_ACCESS')]` or an `access_control` rule granting `PUBLIC_ACCESS` — when nothing else requires auth |
66
+ | `unknown` | anything else |
67
+
68
+ `access_control` is only applied to rules with literal `^/prefix` paths. A rule with `ips`, `host`, `allow_if` or a regex path stops resolution for the routes after it. Rules are matched against the full path (class and import prefixes joined); attribute routes under an import prefix that can't be read (a localized prefix map) are skipped. Laravel 11 `HasMiddleware::middleware()` controllers, Slim app-wide `$app->add(...)` and `can:` middleware aren't resolved.
69
+
70
+ Outbound calls currently include patterns such as:
71
+
72
+ - `curl_init("https://...")`
73
+ - `file_get_contents("https://...")`
74
+ - common HTTP client calls such as `->request(...)`, `->get(...)`, `->post(...)`
75
+
76
+ Datastore/auth/secret hints are similarly heuristic and intended as first-pass signals. Secret hints are env var names (`getenv`, `$_ENV`, `$_SERVER`) containing `SECRET`, `TOKEN`, `KEY`, `PASSWORD` or `PASSWD`. `DB_HOST`-style connection settings are not secrets. `jwt` needs a JWT library (`Firebase\JWT\JWT`, `JWT::decode/encode`, `Lcobucci\JWT`, `tymon/jwt-auth`), and `auth` needs the `Auth::` facade or a chained `auth()->…` helper.
77
+
78
+ ## Installation
79
+
80
+ ```bash
81
+ uv tool install attackmap --with attackmap-analyzer-php-web \
82
+ --index mlaify=https://pkg.mlaify.io/pypi/simple/ --index-strategy first-index
83
+ # or from source:
84
+ pip install git+https://github.com/mlaify/attackmap-analyzer-php-web.git
85
+ ```
86
+
87
+ For local development:
88
+
89
+ ```bash
90
+ pip install -e .[dev]
91
+ ```
92
+
93
+ ## Contract alignment with AttackMap core
94
+
95
+ This package targets the current AttackMap analyzer contract:
96
+
97
+ - analyzer exposes metadata via `metadata`
98
+ - analyzer implements `detect(repo_path)` and `analyze(repo_path)`
99
+ - `analyze` returns AttackMap-style structured scan data (`ScanResult` shape)
100
+
101
+ The package includes a small compatibility layer so tests can run even if AttackMap core is not installed.
102
+
103
+ ## Future core discovery (documented, not implemented here)
104
+
105
+ AttackMap core can discover this analyzer later via one of these options:
106
+
107
+ 1. entry points (preferred long-term)
108
+ 2. explicit configured analyzer list
109
+ 3. namespace/package scanning in `github.com/mlaify`
110
+
111
+ This repository does not implement core-side discovery logic.
112
+
113
+ ## Limitations
114
+
115
+ - regex-based extraction (not AST)
116
+ - limited config route parsing; the Symfony YAML/XML readers cover the shapes Symfony's docs and recipes use, not full YAML/XML
117
+ - Laravel route names (`->name()` / `'as'`), `Route::view` / `Route::redirect` / `Route::singleton`, and resource `->parameters([...])` renames aren't modelled
118
+ - no framework-specific deep parsing yet
119
+ - no dataflow or reachability modeling inside this analyzer
120
+
121
+ These are deliberate to keep this first external analyzer incremental and maintainable.
@@ -0,0 +1,74 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "attackmap-analyzer-php-web"
7
+ version = "0.2.0"
8
+ description = "Broad PHP web analyzer plugin for AttackMap"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [
14
+ {name = "Matthew Davis", email = "mlaify@mlaify.io"},
15
+ {name = "AttackMap Contributors"},
16
+ ]
17
+ maintainers = [
18
+ {name = "Matthew Davis", email = "mlaify@mlaify.io"},
19
+ ]
20
+ keywords = [
21
+ "security",
22
+ "static-analysis",
23
+ "appsec",
24
+ "defensive-security",
25
+ "attackmap",
26
+ "attackmap-plugin",
27
+ ]
28
+ classifiers = [
29
+ "Development Status :: 4 - Beta",
30
+ "Intended Audience :: Developers",
31
+ "Intended Audience :: Information Technology",
32
+ "Intended Audience :: System Administrators",
33
+ "Operating System :: OS Independent",
34
+ "Programming Language :: Python :: 3",
35
+ "Programming Language :: Python :: 3.11",
36
+ "Programming Language :: Python :: 3.12",
37
+ "Programming Language :: Python :: 3.13",
38
+ "Programming Language :: Python :: 3 :: Only",
39
+ "Topic :: Security",
40
+ "Topic :: Software Development :: Quality Assurance",
41
+ "Typing :: Typed",
42
+ ]
43
+ dependencies = [
44
+ "pydantic>=2.7.0",
45
+ ]
46
+
47
+ [project.optional-dependencies]
48
+ core = [
49
+ "attackmap>=0.6.0",
50
+ ]
51
+ dev = [
52
+ "pytest>=8.0.0",
53
+ "build>=1.2.0",
54
+ "attackmap>=0.6.0",
55
+ ]
56
+
57
+ [project.urls]
58
+ Homepage = "https://github.com/mlaify/attackmap-analyzer-php-web"
59
+ Repository = "https://github.com/mlaify/attackmap-analyzer-php-web"
60
+ Issues = "https://github.com/mlaify/attackmap-analyzer-php-web/issues"
61
+ Changelog = "https://github.com/mlaify/attackmap-analyzer-php-web/blob/main/CHANGELOG.md"
62
+ "AttackMap core" = "https://github.com/mlaify/AttackMap"
63
+
64
+ [project.entry-points."attackmap.analyzers"]
65
+ php_web = "attackmap_analyzer_php_web:PhpWebAnalyzer"
66
+
67
+ [tool.setuptools]
68
+ package-dir = {"" = "src"}
69
+
70
+ [tool.setuptools.packages.find]
71
+ where = ["src"]
72
+
73
+ [tool.pytest.ini_options]
74
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,4 @@
1
+ from .analyzer import PhpWebAnalyzer
2
+ from attackmap.sdk import AnalyzerMetadata
3
+
4
+ __all__ = ["AnalyzerMetadata", "PhpWebAnalyzer"]