@zivis/appsec-pack 1.2.0
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.
- package/DISCLOSURE +27 -0
- package/LICENSE +201 -0
- package/NOTICE +14 -0
- package/TRADEMARK.md +40 -0
- package/dist/TEST.md +140 -0
- package/dist/manifest.json +125 -0
- package/dist/scopes/ai.md +41 -0
- package/dist/scopes/api.md +41 -0
- package/dist/scopes/architecture.md +38 -0
- package/dist/scopes/auth.md +44 -0
- package/dist/scopes/authorization.md +40 -0
- package/dist/scopes/business-logic.md +37 -0
- package/dist/scopes/data.md +40 -0
- package/dist/scopes/dependencies.md +46 -0
- package/dist/scopes/frontend.md +40 -0
- package/dist/scopes/infra.md +39 -0
- package/dist/scopes/input.md +39 -0
- package/dist/scopes/secrets.md +40 -0
- package/dist/scopes/session.md +41 -0
- package/dist/scopes/ssrf.md +38 -0
- package/dist/scopes/uploads.md +40 -0
- package/package.json +33 -0
package/DISCLOSURE
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
ZIVIS AppSec Testing Methodology — Dual-Use Disclosure
|
|
2
|
+
|
|
3
|
+
This package is a versioned, cryptographically-signed methodology guide
|
|
4
|
+
consumed by the `zivis` CLI (`zivis test`). It contains structured
|
|
5
|
+
instructions and checklists written for an AI coding agent — not runnable
|
|
6
|
+
exploit code — covering how to assess an application's security posture:
|
|
7
|
+
authentication, authorization, session management, input validation,
|
|
8
|
+
SSRF, secrets handling, dependency risk, file upload handling, and related
|
|
9
|
+
categories (see manifest.json for the full scope list).
|
|
10
|
+
|
|
11
|
+
Because this content describes techniques and checkpoints used during
|
|
12
|
+
penetration testing and vulnerability assessment, it is dual-use in npm's
|
|
13
|
+
sense: the same knowledge that lets a defender find and fix a flaw also
|
|
14
|
+
describes what an attacker would look for.
|
|
15
|
+
|
|
16
|
+
Intended legitimate use: guiding AI coding agents and human reviewers
|
|
17
|
+
through authorized, consensual security testing of applications the
|
|
18
|
+
tester owns or has permission to test, as part of the ZIVIS platform's
|
|
19
|
+
AppSec testing workflow (`zivis test`). It contains no working exploits,
|
|
20
|
+
no malware, and no tooling for gaining unauthorized access to any system.
|
|
21
|
+
It is prose methodology only: base guidance plus per-scope Markdown
|
|
22
|
+
overlays.
|
|
23
|
+
|
|
24
|
+
Every version of this package is signed (Ed25519) by ZIVIS's production
|
|
25
|
+
pack-signing key and verified by the `zivis` CLI before use; the signed
|
|
26
|
+
manifest and per-file content hashes ship alongside the content in
|
|
27
|
+
`dist/manifest.json`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for describing the origin of the Work and
|
|
141
|
+
reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright 2026 ZIVIS, Inc.
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
ZIVIS AppSec Testing Methodology (@zivis/appsec-pack)
|
|
2
|
+
Copyright 2026 ZIVIS, Inc.
|
|
3
|
+
|
|
4
|
+
This product is licensed under the Apache License, Version 2.0 (see the
|
|
5
|
+
accompanying LICENSE file). It is part of ZIVIS Community Edition: the
|
|
6
|
+
free, self-service methodology consumed by the `zivis` CLI (`zivis test`).
|
|
7
|
+
|
|
8
|
+
The Apache License, Version 2.0 does not grant any rights to use the
|
|
9
|
+
"ZIVIS" name, logo, or other trademarks of ZIVIS, Inc. See TRADEMARK.md
|
|
10
|
+
for details.
|
|
11
|
+
|
|
12
|
+
This NOTICE file is provided for informational purposes only, per
|
|
13
|
+
Section 4(d) of the Apache License, Version 2.0, and does not modify
|
|
14
|
+
the License.
|
package/TRADEMARK.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Trademark Notice
|
|
2
|
+
|
|
3
|
+
This package's content is licensed under the Apache License, Version 2.0
|
|
4
|
+
(see `LICENSE`). Like most open-source licenses, Apache-2.0 is a
|
|
5
|
+
copyright license — it does not grant any trademark rights. Section 6 of
|
|
6
|
+
the License states this explicitly:
|
|
7
|
+
|
|
8
|
+
> Trademarks. This License does not grant permission to use the trade
|
|
9
|
+
> names, trademarks, service marks, or product names of the Licensor,
|
|
10
|
+
> except as required for describing the origin of the Work and
|
|
11
|
+
> reproducing the content of the NOTICE file.
|
|
12
|
+
|
|
13
|
+
"ZIVIS", the ZIVIS logo, "Zivis Community Edition", and other ZIVIS
|
|
14
|
+
marks (collectively, the "Marks") are trademarks of ZIVIS, Inc. They are
|
|
15
|
+
**not** licensed under Apache-2.0 and are not part of the Work.
|
|
16
|
+
|
|
17
|
+
## What this means in practice
|
|
18
|
+
|
|
19
|
+
You may, without needing separate trademark permission:
|
|
20
|
+
|
|
21
|
+
- Use, copy, modify, and redistribute this package's content under the
|
|
22
|
+
terms of the Apache License, Version 2.0;
|
|
23
|
+
- State factually that your fork or redistribution is "based on" or
|
|
24
|
+
"derived from" ZIVIS's `@zivis/appsec-pack`;
|
|
25
|
+
- Reference the Marks nominatively to describe compatibility or origin
|
|
26
|
+
(e.g., "compatible with the ZIVIS CLI").
|
|
27
|
+
|
|
28
|
+
You may **not**, without separate written permission from ZIVIS, Inc.:
|
|
29
|
+
|
|
30
|
+
- Use the Marks to name, brand, or endorse a modified or redistributed
|
|
31
|
+
version of this package in a way that implies it is the official
|
|
32
|
+
ZIVIS package or is endorsed/certified by ZIVIS;
|
|
33
|
+
- Use the Marks in a way that could confuse users about whether they are
|
|
34
|
+
using ZIVIS's own published `@zivis/appsec-pack` versus a third-party
|
|
35
|
+
fork;
|
|
36
|
+
- Register the Marks, or confusingly similar names, as your own
|
|
37
|
+
trademark, package name, or domain.
|
|
38
|
+
|
|
39
|
+
This notice is informational and does not modify the License. Questions
|
|
40
|
+
about trademark use: hello@zivis.ai.
|
package/dist/TEST.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# ZIVIS AppSec Testing — Base Methodology
|
|
2
|
+
|
|
3
|
+
Zivis provides the method of inquiry; the coding agent provides repo
|
|
4
|
+
understanding, reasoning, tool selection, and execution. This file is the
|
|
5
|
+
base guidance that applies regardless of which scope (if any) was
|
|
6
|
+
requested — read it before any scope-specific overlay. Each scope overlay in
|
|
7
|
+
`scopes/` tells you *what* to probe and *how* to confirm it; this file tells
|
|
8
|
+
you *how to judge a lead*, *how to test without breaking anything*, and *what
|
|
9
|
+
a durable finding looks like*, so those rules aren't repeated verbatim in
|
|
10
|
+
every scope.
|
|
11
|
+
|
|
12
|
+
## How to use this pack
|
|
13
|
+
|
|
14
|
+
1. Understand the actual application before testing anything — read the
|
|
15
|
+
repository, identify what's actually present, and determine which of the
|
|
16
|
+
scopes below are applicable. Do not mechanically run every scope
|
|
17
|
+
regardless of relevance.
|
|
18
|
+
2. Prefer experimentally verifying a security assumption over concluding
|
|
19
|
+
from source inspection alone.
|
|
20
|
+
3. Distinguish scanner/tool output from confirmed findings — a tool flagging
|
|
21
|
+
something is a lead, not a finding.
|
|
22
|
+
4. Use established tools where they exist (Semgrep, ast-grep, Gitleaks,
|
|
23
|
+
OSV-Scanner, Trivy, ZAP) rather than re-deriving their coverage by hand.
|
|
24
|
+
5. Require evidence for anything reported as a material finding.
|
|
25
|
+
|
|
26
|
+
## No scope requested
|
|
27
|
+
|
|
28
|
+
Start with the architecture scope to build an inventory of what's actually
|
|
29
|
+
there, then run an adaptive review across whichever of this pack's other
|
|
30
|
+
scopes apply to the repository in front of you, guided by what you find as
|
|
31
|
+
you go.
|
|
32
|
+
|
|
33
|
+
## A scope was requested
|
|
34
|
+
|
|
35
|
+
Read this base file first, then the requested scope's overlay file. The
|
|
36
|
+
overlay narrows focus; it does not replace the base guidance above.
|
|
37
|
+
|
|
38
|
+
## Every tool hit is a lead, not a finding
|
|
39
|
+
|
|
40
|
+
A scanner, a grep match, or a suspicious-looking line is where an
|
|
41
|
+
investigation *starts*, not where it ends. The gap between "the tool flagged
|
|
42
|
+
it" and "this is real" is the whole job. Two failure modes to avoid:
|
|
43
|
+
|
|
44
|
+
- **Confirmation bias toward the scanner.** Calling something "a Critical"
|
|
45
|
+
before doing any reachability or reproduction work quietly re-labels the
|
|
46
|
+
tool's rating as *your* finding's severity. The tool rates a vulnerability
|
|
47
|
+
in isolation; you rate whether *this* code exercises it with input an
|
|
48
|
+
attacker actually controls.
|
|
49
|
+
- **Reading instead of testing.** A value that looks escaped in source can
|
|
50
|
+
still be exploitable depending on where it lands; a middleware that appears
|
|
51
|
+
present in source may run *after* the vulnerable code, or not on this route
|
|
52
|
+
at all. Where it is safe to do so, confirm behavior by exercising it, not
|
|
53
|
+
by inferring it from the code.
|
|
54
|
+
|
|
55
|
+
## Triage — the skepticism rubric
|
|
56
|
+
|
|
57
|
+
Before anything is recorded as a material finding, take the stance of a
|
|
58
|
+
skeptic whose job is to **refute** it. This is the same discipline a
|
|
59
|
+
professional reviewer applies; apply it to your own leads:
|
|
60
|
+
|
|
61
|
+
1. **Minimize false positives** — when in doubt, refute.
|
|
62
|
+
2. **A refusal, error, or empty response beats a scary keyword match.** A
|
|
63
|
+
payload that "worked" but returned a 403, a validation error, or an empty
|
|
64
|
+
body did not work.
|
|
65
|
+
3. **Require quoted evidence** — a real code excerpt or a request/response
|
|
66
|
+
pair, not an assertion that a flaw "would" exist.
|
|
67
|
+
4. **Real vs. hypothetical** — is it reachable with the access an attacker
|
|
68
|
+
actually has, or only from an authenticated admin / a local shell / an
|
|
69
|
+
internal network you assumed?
|
|
70
|
+
5. **Specificity** — does the evidence prove *this* flaw on *this* target,
|
|
71
|
+
or a generic pattern that happens to appear here?
|
|
72
|
+
6. **Distinguish by-design.** A publishable API key meant to be public, an
|
|
73
|
+
intentionally-public asset bucket, a rate-limited endpoint doing its job —
|
|
74
|
+
these are not findings. Say why, and move on.
|
|
75
|
+
|
|
76
|
+
**Record what you tried and couldn't confirm as `refuted`, don't silently
|
|
77
|
+
drop it.** A checked-and-clean result and an unchecked one must never read
|
|
78
|
+
the same. "I attempted X against Y and it was blocked by Z" is itself
|
|
79
|
+
durable, defensible output.
|
|
80
|
+
|
|
81
|
+
## The finding shape (durable + ZSAM-legible)
|
|
82
|
+
|
|
83
|
+
Emit every material finding in the canonical shape so auto-published output
|
|
84
|
+
stays machine-legible and comparable across runs:
|
|
85
|
+
|
|
86
|
+
- **title** — one line, the specific flaw (not the category).
|
|
87
|
+
- **scope** — the pack scope id this came from (`auth`, `ssrf`, …).
|
|
88
|
+
- **severity** — your rating *after* reachability triage, with the reasoning
|
|
89
|
+
the rating rests on; never the scanner's raw label passed through.
|
|
90
|
+
- **affected endpoint / component** — the concrete route, function, file, or
|
|
91
|
+
service, not "the app."
|
|
92
|
+
- **reproduction** — the minimal ordered steps that reproduce it.
|
|
93
|
+
- **evidence** — quoted code or a request/response pair, each anchored to a
|
|
94
|
+
**git SHA + path:line** so it can be re-checked against the exact tree.
|
|
95
|
+
- **remediation** — the specific change that closes it.
|
|
96
|
+
|
|
97
|
+
**Sanitized evidence only.** Strip real credentials, cookies, session
|
|
98
|
+
tokens, and personal data out of every quoted request/response before it is
|
|
99
|
+
recorded — the `redact` helper removes creds/cookies/tokens; use it rather
|
|
100
|
+
than pasting raw captures. Evidence proves the flaw; it must not itself
|
|
101
|
+
become a leak.
|
|
102
|
+
|
|
103
|
+
## Test safely — resilience checks, not attacks
|
|
104
|
+
|
|
105
|
+
This pack teaches *how to confirm a real issue safely*, not how to exploit
|
|
106
|
+
one. Across every scope:
|
|
107
|
+
|
|
108
|
+
- **Non-destructive by default.** Prove a weakness with the minimum action
|
|
109
|
+
that demonstrates it. Never delete, corrupt, or exfiltrate real data, and
|
|
110
|
+
never run a load/cost-exhaustion loop — proving an amplification exists
|
|
111
|
+
takes a couple of requests, not a flood.
|
|
112
|
+
- **Prove one, don't walk the table.** One reproducible instance of an IDOR,
|
|
113
|
+
an injection, or an SSRF proves the class. Enumerating every record or
|
|
114
|
+
chaining deeper is exploitation, not confirmation.
|
|
115
|
+
- **Only test what you own or are authorized to test**, and only in an
|
|
116
|
+
environment where a resilience check is safe to run.
|
|
117
|
+
|
|
118
|
+
## Where the paid tier begins
|
|
119
|
+
|
|
120
|
+
This is public community methodology. It stops at *confirming a real issue
|
|
121
|
+
safely and recording it well*. It deliberately ships **no** weaponized
|
|
122
|
+
tooling, and it does **not** include:
|
|
123
|
+
|
|
124
|
+
- deep exploit chains or weaponized payloads,
|
|
125
|
+
- independent third-party verification / adjudication and the signed
|
|
126
|
+
assurance mark that results from it.
|
|
127
|
+
|
|
128
|
+
Deep exploitation and independent verification are the professional (paid)
|
|
129
|
+
tier. When a lead clearly needs weaponization or an independent verdict to
|
|
130
|
+
land, record it as a confirmed-or-refuted finding here and note that the
|
|
131
|
+
deeper work belongs there.
|
|
132
|
+
|
|
133
|
+
## After a fix — retest, don't assume
|
|
134
|
+
|
|
135
|
+
A patch is not confirmation. Re-run the specific check that produced the
|
|
136
|
+
original finding — not just the file's test suite — against the fixed code,
|
|
137
|
+
and confirm the reproduction step that previously worked now fails. If the
|
|
138
|
+
fix was upstream (a dependency bump, a config change), confirm the new
|
|
139
|
+
version/config actually reached the environment under test, not just the
|
|
140
|
+
manifest declaring it.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": "1.0.0",
|
|
3
|
+
"pack_id": "appsec",
|
|
4
|
+
"pack_type": "appsec",
|
|
5
|
+
"version": "1.2.0",
|
|
6
|
+
"min_cli_version": "0.1.0-alpha.1",
|
|
7
|
+
"description": "ZIVIS AppSec testing methodology — base guidance plus targeted scopes.",
|
|
8
|
+
"built_at": "2026-08-27T20:23:54.096Z",
|
|
9
|
+
"base": {
|
|
10
|
+
"path": "TEST.md",
|
|
11
|
+
"sha256": "48ab72f5b5c830d0ecb93159b45049732a88e375195517a59fccf64aa17f94e9"
|
|
12
|
+
},
|
|
13
|
+
"scopes": [
|
|
14
|
+
{
|
|
15
|
+
"id": "architecture",
|
|
16
|
+
"label": "Architecture & Attack Surface",
|
|
17
|
+
"description": "Entry-point inventory, trust boundaries, and data flow across the application.",
|
|
18
|
+
"path": "scopes/architecture.md",
|
|
19
|
+
"sha256": "8981d8f7f3d277ba6319c1e7ec36c349141576abce2574ae79c3b8d3e303eddc"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "auth",
|
|
23
|
+
"label": "Authentication",
|
|
24
|
+
"description": "Login, session establishment, credential handling, MFA.",
|
|
25
|
+
"path": "scopes/auth.md",
|
|
26
|
+
"sha256": "6a59506cd28214842073c70383a481a5267f8a1643d1b564b7708a5179d97874"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "authorization",
|
|
30
|
+
"label": "Authorization",
|
|
31
|
+
"description": "Access control, object-level permissions, privilege boundaries.",
|
|
32
|
+
"path": "scopes/authorization.md",
|
|
33
|
+
"sha256": "3cf76877749f666eba67a09e67ad476ef93e570dc2cdd173f640c86b578d3091"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"id": "session",
|
|
37
|
+
"label": "Session Management",
|
|
38
|
+
"description": "Token lifecycle, invalidation, CSRF, and cookie security.",
|
|
39
|
+
"path": "scopes/session.md",
|
|
40
|
+
"sha256": "0677be2ea9ef9b5a217825c834eb288ff57510bde28d2f3343066c1a17136fba"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": "api",
|
|
44
|
+
"label": "API Security",
|
|
45
|
+
"description": "Endpoint-level security for REST/GraphQL/RPC surfaces.",
|
|
46
|
+
"path": "scopes/api.md",
|
|
47
|
+
"sha256": "a38c796aed3f754d105ed64bc8d84ce1fc0ee9c2b199d0ecdef46e8245cc6ad4"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"id": "input",
|
|
51
|
+
"label": "Input Validation",
|
|
52
|
+
"description": "Injection, deserialization, and untrusted-input handling.",
|
|
53
|
+
"path": "scopes/input.md",
|
|
54
|
+
"sha256": "f4c4d04960d49679dd7f8966d9b28d83bb0a2aae49e0634f956a060f91e61127"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "business-logic",
|
|
58
|
+
"label": "Business Logic",
|
|
59
|
+
"description": "Workflow bypass, race conditions, and abuse of legitimate features.",
|
|
60
|
+
"path": "scopes/business-logic.md",
|
|
61
|
+
"sha256": "c375b1cc36f8ede1f39a21b72271f9c8e40d4390513a87fc023c7402fa353845"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"id": "data",
|
|
65
|
+
"label": "Data Protection",
|
|
66
|
+
"description": "Sensitive-data exposure, encryption at rest/in transit.",
|
|
67
|
+
"path": "scopes/data.md",
|
|
68
|
+
"sha256": "294e1ad60edfeca61748d91924ab7c7fc747806ab192342e7219464af9752c8f"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"id": "secrets",
|
|
72
|
+
"label": "Secrets Management",
|
|
73
|
+
"description": "Credential/token storage, rotation, and leakage risk.",
|
|
74
|
+
"path": "scopes/secrets.md",
|
|
75
|
+
"sha256": "7dc99c9d847ca351daa2035ee2ffbf5f88385ec81cb877dba37467aab9979c86"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "dependencies",
|
|
79
|
+
"label": "Dependency Risk",
|
|
80
|
+
"description": "Vulnerable or malicious third-party dependencies.",
|
|
81
|
+
"path": "scopes/dependencies.md",
|
|
82
|
+
"sha256": "cf66b5df2daf6bc1a6d6498128bec0153d29397002e7b306bfd10efc5248f2a0"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "ssrf",
|
|
86
|
+
"label": "SSRF",
|
|
87
|
+
"description": "Server-side request forgery via user-influenced outbound requests.",
|
|
88
|
+
"path": "scopes/ssrf.md",
|
|
89
|
+
"sha256": "38ceb02a760de599cf8ac3245fbd22e428addc02acca1132ceb3dd2dd156d69e"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "uploads",
|
|
93
|
+
"label": "File Upload",
|
|
94
|
+
"description": "Upload handling, storage, and downstream processing risk.",
|
|
95
|
+
"path": "scopes/uploads.md",
|
|
96
|
+
"sha256": "8dd281dadfb357f2b1e2becdbe0c56225b91d615ad474848b649f425e80ddec1"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"id": "frontend",
|
|
100
|
+
"label": "Frontend Security",
|
|
101
|
+
"description": "Client-side/browser security (XSS, CSP, postMessage, etc).",
|
|
102
|
+
"path": "scopes/frontend.md",
|
|
103
|
+
"sha256": "12ebe94f037059c29249fe7407979e29081e5d6ebc6d152450e28185a17d86fc"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"id": "infra",
|
|
107
|
+
"label": "Infrastructure & IaC",
|
|
108
|
+
"description": "IaC misconfiguration, container hygiene, exposed management endpoints.",
|
|
109
|
+
"path": "scopes/infra.md",
|
|
110
|
+
"sha256": "ef414bd4033c9fd089a9e7b29f57a9eaecb07d32352305d580ffa82bea45b57a"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"id": "ai",
|
|
114
|
+
"label": "AI Surface Security",
|
|
115
|
+
"description": "LLM/agent-specific risks — prompt injection, tool misuse.",
|
|
116
|
+
"path": "scopes/ai.md",
|
|
117
|
+
"sha256": "388f41a43a185a7c522de3256e05f63f98e558dc621789bf0aa6bb960bc1d1fa"
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
"signature": {
|
|
121
|
+
"algorithm": "ed25519",
|
|
122
|
+
"key_id": "zivis-pack-prod-2026-08",
|
|
123
|
+
"signature": "P4h55DxlAw0jvVzmrH/pFxWWUpkwa6pDqO/uKRcO+UqF3Vm1vTV0UIeZPWRS+0NMoOXksrx1HXsqbZ10ND3qCA=="
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Scope: AI Surface Security
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record. Only applicable if the repository actually has an LLM/agent-enabled surface — confirm this first; this scope is easy to apply where it doesn't belong.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- Direct prompt injection — user input overriding the system prompt/policy; ignore-instructions, role-play framing, and encoding bypasses (base64, unicode/zero-width) that slip past naive input filters (LLM01, `AML.T0051.000`, CWE-77).
|
|
7
|
+
- Indirect / cross-domain injection — instructions arriving inside content the model *retrieves* (RAG chunks, uploaded docs, fetched pages, emails/records) rather than typed by the user (LLM01, `AML.T0051.001`). Highest-value class for agentic systems.
|
|
8
|
+
- System-prompt / IP extraction — the system prompt, tool schemas, and hidden instructions treated as an asset the owner meant to keep private (LLM07/LLM06, `AML.T0024`, CWE-200).
|
|
9
|
+
- Excessive agency — LLM output auto-driving a side effect (DB write, payment, email, webhook, a score that fans out) with no human gate (LLM08/LLM06-agency, `AML.T0043`, CWE-269).
|
|
10
|
+
- Insecure output handling — model output rendered/executed/stored unsanitized (markdown-image egress, HTML injection) (LLM05, CWE-79).
|
|
11
|
+
- Cross-tenant RAG leakage — does tenant A's query surface tenant B's documents (the AI form of BOLA)?
|
|
12
|
+
- Denial-of-wallet — an unauthenticated or amplifying endpoint that drives model spend (LLM10, CWE-770).
|
|
13
|
+
|
|
14
|
+
## Tools (leads, not findings)
|
|
15
|
+
- Build an **AI system card** first (models, data/RAG sources with trust levels, tools with side effects and autonomy, trust boundaries, guardrails) — the inventory that tells you which classes have a surface. This is the lead map, not a scanner.
|
|
16
|
+
- Grep for where untrusted content is concatenated into a prompt, where tool arguments come from model output unchecked, and where a side-effecting action lacks a human-approval gate.
|
|
17
|
+
- Small, categorized sets of well-known naive payloads as leads — every apparent "success" is a claim to confirm with the skepticism rubric (`../TEST.md`), not a finding on its own.
|
|
18
|
+
|
|
19
|
+
## How to confirm (prefer testing over reading)
|
|
20
|
+
- **Measure, don't anecdote.** Test each class as a fixed, categorized set of attempts and score every attempt pass/fail; report the success rate per class, not "we got one jailbreak." A number you can reproduce beats a single bypass.
|
|
21
|
+
- Judge success with the skepticism rubric (`../TEST.md`): a **refusal, error, or empty response is not a success even if it echoes a scary string**; require quoted model output (or the side-effect) as proof; real vs. hypothetical ("might leak if…" is not a leak).
|
|
22
|
+
- For excessive agency, enumerate every side-effecting action the system card lists and check each for a missing approval step — the question is "when tricked, what happens with no review."
|
|
23
|
+
- For denial-of-wallet, prove the amplification exists with a **couple** of requests and log the per-request cost estimate — never run a cost-exhaustion loop.
|
|
24
|
+
|
|
25
|
+
## Triage — lead vs. finding
|
|
26
|
+
- A material finding needs the reproducible payload, the quoted model output/side-effect proving the guardrail was crossed, and the affected surface — a single lucky bypass with no measured rate is weak; a per-class success rate over a known number of attempts is defensible.
|
|
27
|
+
- A guardrail that held (attack blocked, refusal returned) is a **refuted** attempt — record it; the block rate is itself the deliverable.
|
|
28
|
+
- Distinguish by-design: a model intentionally allowed to answer a benign category is not a jailbreak.
|
|
29
|
+
|
|
30
|
+
## What to record (durable + ZSAM-legible)
|
|
31
|
+
- Canonical finding shape: title, scope `ai`, severity, affected surface (endpoint/tool/RAG source), reproduction (the payload + class + difficulty), evidence (quoted output or the canary/side-effect), remediation. Carry the LLM/`AML.T*`/CWE ids.
|
|
32
|
+
- Sanitize transcripts with the `redact` helper — strip any real tenant data the model surfaced; quote only enough to prove the crossing.
|
|
33
|
+
|
|
34
|
+
## Frameworks
|
|
35
|
+
- OWASP **LLM Top 10** (LLM01 injection, LLM05 output handling, LLM06/07 disclosure, LLM08 excessive agency, LLM10 unbounded consumption); OWASP **Agentic (ASI)** where the surface is agentic.
|
|
36
|
+
- MITRE **ATLAS** `AML.T0051.000/.001`, `AML.T0024`, `AML.T0043`; compliance overlay: ISO 42001, NIST AI RMF, EU AI Act.
|
|
37
|
+
- CWE-77 (injection), CWE-200 (disclosure), CWE-269 (excessive agency), CWE-79 (output handling), CWE-770 (resource consumption).
|
|
38
|
+
|
|
39
|
+
## Not in this scope / not here
|
|
40
|
+
- Classic web/API flaws in the *service around* the model are the other scopes (`api`, `authorization`, `ssrf`, …); model-weight/hub supply-chain risk is `dependencies`.
|
|
41
|
+
- **No weaponized payload library, no deep exploit chains, and no side-effecting canary-callback exploitation here** — this overlay ships the *method* (what to probe, how to judge, how to score), not the payload dump. Deep agentic exploitation, side-effect/canary confirmation, and independent verification are the professional (paid) tier.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Scope: API Security
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- Endpoint inventory completeness — undocumented/shadow/legacy routes, debug endpoints, and version-skew endpoints still reachable (API9, WSTG-INFO-06).
|
|
7
|
+
- Consistent authorization across similar endpoints — the same object reachable via list vs. detail, v1 vs. v2, REST vs. GraphQL vs. RPC, all enforcing the same check (API1/API5).
|
|
8
|
+
- Mass-assignment / BOPLA — over-permissive request binding that lets a caller set fields they shouldn't (API3, CWE-915).
|
|
9
|
+
- Unrestricted resource consumption — missing rate limits, unbounded page sizes, expensive queries, and GraphQL query depth/complexity abuse (API4, CWE-770).
|
|
10
|
+
- Improper inventory / unsafe consumption of upstream APIs — trusting a third-party response without validation (API10, CWE-829).
|
|
11
|
+
- Spec drift — actual routed endpoints vs. the published OpenAPI/GraphQL schema; the gap is itself worth surfacing.
|
|
12
|
+
|
|
13
|
+
## Tools (leads, not findings)
|
|
14
|
+
- Enumerate routes from code (router registrations, resolver maps, RPC method tables) and diff against the published spec — drift is a lead.
|
|
15
|
+
- `semgrep --config p/owasp-top-ten` for handlers binding whole request bodies to models (mass-assignment) and endpoints with no rate-limit decorator.
|
|
16
|
+
- For GraphQL, introspect the schema (where enabled) and look for missing depth/complexity limits; for REST, a spec-diff against OpenAPI.
|
|
17
|
+
- `ZAP` (baseline / API scan mode) as a lead generator against a running instance — every alert is a lead, not a finding.
|
|
18
|
+
|
|
19
|
+
## How to confirm (prefer testing over reading)
|
|
20
|
+
- Hit a shadow/undocumented route directly and confirm it responds — presence in the router plus a live response beats "it looks orphaned."
|
|
21
|
+
- Mass-assignment: send an extra privileged field and confirm the server persists it (read the object back).
|
|
22
|
+
- Resource consumption: request an oversized page or a deeply-nested GraphQL query *once* and observe whether a limit engages — prove the amplification exists, don't run a flood (see `../TEST.md`).
|
|
23
|
+
- Authorization consistency: reach the same object through its second route as a lower-privileged identity and compare.
|
|
24
|
+
|
|
25
|
+
## Triage — lead vs. finding
|
|
26
|
+
- A material finding needs a reproducible request, the quoted response proving impact (persisted field, other-tenant data, unbounded result), and real reachability.
|
|
27
|
+
- A limit that correctly engages, or a shadow route that 401s, is a **refuted** result — record it, and record spec-drift explicitly even when no single route is exploitable.
|
|
28
|
+
- Distinguish by-design: a public read-only endpoint, or an intentionally high but bounded page size, is not a finding.
|
|
29
|
+
|
|
30
|
+
## What to record (durable + ZSAM-legible)
|
|
31
|
+
- Canonical finding shape: title, scope `api`, severity, affected endpoint (method + path + the offending parameter/field), reproduction, evidence with git SHA + path:line, remediation.
|
|
32
|
+
- Sanitize captured requests/responses with the `redact` helper before recording.
|
|
33
|
+
|
|
34
|
+
## Frameworks
|
|
35
|
+
- OWASP **API1–API10** (2023), esp. API3 BOPLA, API4 Resource Consumption, API9 Inventory, API10 Unsafe Consumption; OWASP Web **A04/A05**.
|
|
36
|
+
- OWASP ASVS V13 (API & Web Service); WSTG-INFO-06, WSTG-BUSL.
|
|
37
|
+
- CWE-915 (mass-assignment), CWE-770 (resource consumption), CWE-1059 (inventory), CWE-829 (unsafe consumption).
|
|
38
|
+
|
|
39
|
+
## Not in this scope / not here
|
|
40
|
+
- The object/function-level authorization *logic* is `authorization`; token/CSRF handling is `session`; injection into a sink is `input`; SSRF via an outbound call is `ssrf`. This scope is the endpoint surface and its consistency.
|
|
41
|
+
- No API fuzzing payload dumps or exploitation chains here. Confirm one instance; deep exploitation and independent verification are the professional (paid) tier.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Scope: Architecture & Attack Surface
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record. Run this scope first, even when a narrower scope was requested — the inventory it produces is what makes every other scope's findings meaningful.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- Entry-point inventory — every externally reachable surface: HTTP/REST routes, GraphQL/RPC/WebSocket, queue consumers, scheduled jobs, webhooks, CLI/admin commands (WSTG-INFO-06, API9).
|
|
7
|
+
- Trust boundaries — where the trust level changes: client↔API, API↔worker, service↔service, app↔database/cache, app↔third-party. Mark each boundary and what authenticates across it (ASVS 1.1).
|
|
8
|
+
- Data flows — how data actually moves between tiers, and where untrusted input first enters and where it lands in a sink.
|
|
9
|
+
- Authentication posture per surface — which entry points are unauthenticated by design, and whether that's intended (background workers and webhooks are a recurring gap).
|
|
10
|
+
- External / third-party integrations and the secrets that reach them.
|
|
11
|
+
- Drift — the real routed surface vs. any published API spec or architecture doc; docs drift from reality fastest and the gap is itself worth surfacing.
|
|
12
|
+
|
|
13
|
+
## Tools (leads, not findings)
|
|
14
|
+
- Grep/`ast-grep` the router and framework registration points to enumerate routes from code (e.g. decorators, `app.<verb>(...)`, resolver maps, job registrations) — build the inventory from the routed code itself, not from docs.
|
|
15
|
+
- `semgrep --config p/owasp-top-ten` for a first pass at obviously-unauthenticated handlers and dangerous sinks to seed the boundary map.
|
|
16
|
+
- Read CI/deploy config and `docker-compose`/k8s manifests to learn the real deploy topology (what is actually a live server vs. a static export) before assuming a surface exists.
|
|
17
|
+
|
|
18
|
+
## How to confirm (prefer testing over reading)
|
|
19
|
+
- For each surface you believe is unauthenticated, send an unauthenticated request and confirm it responds without credentials — presence in an "auth" middleware file does not prove the middleware runs on that route.
|
|
20
|
+
- Confirm a boundary is real by observing behavior across it (e.g. a worker consuming an unauthenticated queue message), not by trusting a diagram.
|
|
21
|
+
- Trace one representative untrusted-input path end to end (entry → transform → sink) to validate the flow map.
|
|
22
|
+
|
|
23
|
+
## Triage — lead vs. finding
|
|
24
|
+
- Most architecture output is *inventory*, not a finding — a documented entry point is a fact, not a vulnerability. Only escalate to a finding where a surface is reachable and lacks a control it should have (e.g. an unauthenticated state-changing route).
|
|
25
|
+
- A surface you expected but confirmed is *not* reachable in the real deploy topology is a **refuted** assumption worth recording — an unscanned surface and a confirmed-absent one must not read the same.
|
|
26
|
+
|
|
27
|
+
## What to record (durable + ZSAM-legible)
|
|
28
|
+
- Produce the inventory (entry points, trust boundaries, data flows) as the durable artifact other scopes build on.
|
|
29
|
+
- For any concrete gap, emit the canonical finding shape (title, scope `architecture`, severity, affected component, reproduction, evidence with git SHA + path:line, remediation). Sanitize evidence with the `redact` helper.
|
|
30
|
+
|
|
31
|
+
## Frameworks
|
|
32
|
+
- OWASP Web **A04** Insecure Design, **A05** Security Misconfiguration; OWASP API **API9** Improper Inventory Management.
|
|
33
|
+
- OWASP ASVS V1 (Architecture); WSTG-INFO (Information Gathering).
|
|
34
|
+
- CWE-1059 (incomplete inventory), CWE-1008 (architectural weakness).
|
|
35
|
+
|
|
36
|
+
## Not in this scope / not here
|
|
37
|
+
- Deep per-surface testing belongs to the specific scopes (`auth`, `authorization`, `api`, `input`, `ssrf`, …) — this scope points you at them.
|
|
38
|
+
- No exploitation here; this overlay maps the surface and hands leads to the narrower scopes. Deep exploitation and independent verification are the professional (paid) tier.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Scope: Authentication
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- Credential storage — passwords hashed with a memory-hard KDF (argon2id / bcrypt / scrypt), not fast/plain hashes or reversible encryption (ASVS 2.4, CWE-916).
|
|
7
|
+
- Credential comparison — constant-time verification for passwords, reset tokens, and API keys; no early-return `==` on secrets (ASVS 2.4.3).
|
|
8
|
+
- Authentication over a secure channel — credentials never sent in a URL/query, never over plain HTTP (WSTG-ATHN-01, ASVS 2.2).
|
|
9
|
+
- MFA / step-up — enforced server-side for the flows that claim it, not just offered in the UI (ASVS 2.8).
|
|
10
|
+
- Password reset & account recovery — reset tokens single-use, expiring, unguessable, and bound to the account (WSTG-ATHN-09, ASVS 2.5).
|
|
11
|
+
- Rate limiting / lockout on login, reset, and MFA endpoints — resistance to credential stuffing and brute force (WSTG-ATHN-03, ASVS 2.2.1).
|
|
12
|
+
- Username / account enumeration via differential responses or timing on login and reset (WSTG-ATHN-02).
|
|
13
|
+
- Default / weak credentials shipped in seeds, fixtures, or docs (WSTG-ATHN-01).
|
|
14
|
+
|
|
15
|
+
## Tools (leads, not findings)
|
|
16
|
+
- `semgrep --config p/secrets --config p/owasp-top-ten` to surface weak-hash calls, hardcoded credentials, and `Math.random()` used for tokens — every hit is a lead to trace to its call site.
|
|
17
|
+
- `ast-grep` for the specific comparison pattern (e.g. `password === $X` / `token == $Y`) to find non-constant-time checks.
|
|
18
|
+
- `gitleaks detect` to catch committed test credentials or seeded default logins.
|
|
19
|
+
- Manual review of the auth middleware order and the reset-token generator — tools rarely flag *missing* step-up or a guessable token seed.
|
|
20
|
+
|
|
21
|
+
## How to confirm (prefer testing over reading)
|
|
22
|
+
- Exercise the real login flow: submit N wrong passwords and confirm lockout/backoff actually engages (a resilience check — a few attempts, not a brute-force run).
|
|
23
|
+
- Test session fixation: capture the pre-login session identifier and confirm it is *rotated* on successful login, not reused.
|
|
24
|
+
- Test reset-token reuse: request a reset, use the token once, then attempt to reuse it and confirm it is rejected; confirm it also expires.
|
|
25
|
+
- Compare login responses for a known-good vs. unknown username for content/timing differences that leak account existence.
|
|
26
|
+
- For MFA, confirm the second factor is verified server-side by attempting to reach the post-MFA state without completing it.
|
|
27
|
+
|
|
28
|
+
## Triage — lead vs. finding
|
|
29
|
+
- A material finding needs a reproducible step, quoted evidence, and real impact — e.g. "reset token `…` accepted twice, second use returned 200 with a new session" beats "reset code path looks reusable."
|
|
30
|
+
- A blocked attempt (lockout engaged, token rejected on reuse, MFA enforced) is a **refuted** result — record it, don't drop it.
|
|
31
|
+
- Distinguish by-design: a deliberately public demo account, or a rate limit doing its job, is not a finding.
|
|
32
|
+
|
|
33
|
+
## What to record (durable + ZSAM-legible)
|
|
34
|
+
- Emit in the canonical finding shape (see `../TEST.md`): title, scope `auth`, severity (after triage), affected endpoint/component, reproduction, evidence with git SHA + path:line, remediation.
|
|
35
|
+
- Sanitize every captured request/response — the `redact` helper strips credentials, cookies, and tokens; never record a real password or live session token as evidence.
|
|
36
|
+
|
|
37
|
+
## Frameworks
|
|
38
|
+
- OWASP Web **A07** Identification & Authentication Failures; OWASP API **API2** Broken Authentication.
|
|
39
|
+
- OWASP ASVS V2 (Authentication); WSTG-ATHN-01…10.
|
|
40
|
+
- CWE-287 (auth), CWE-916 (weak hash), CWE-307 (missing brute-force protection), CWE-640 (weak recovery).
|
|
41
|
+
|
|
42
|
+
## Not in this scope / not here
|
|
43
|
+
- Post-authentication access control lives in `authorization`; token lifecycle, CSRF, and cookie attributes live in `session`.
|
|
44
|
+
- This overlay ships no credential-stuffing wordlists, no weaponized brute-force tooling, and no automated verifier. Deep exploitation of a confirmed auth weakness and independent verification of the result are the professional (paid) tier.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Scope: Authorization
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- Object-level access control (IDOR / BOLA) — can identity A read or mutate a resource owned by identity B by changing an id in the path, body, or query? (WSTG-ATHZ-04, API1, CWE-639).
|
|
7
|
+
- Function-level access control (BFLA) — are admin/privileged operations enforced server-side, or only hidden in the UI? (WSTG-ATHZ-02, API5, CWE-285).
|
|
8
|
+
- Tenant / org isolation — is every query scoped to the caller's tenant, or can a tenant id be swapped to reach another org's data?
|
|
9
|
+
- Property-level authorization (BOPLA / mass-assignment) — can a caller set fields they shouldn't (role, ownerId, isAdmin) via over-permissive request binding? (API3, CWE-915).
|
|
10
|
+
- Privilege escalation via parameter tampering or a missing server-side check on a state transition.
|
|
11
|
+
- Consistency — the same object reached through a second route (REST vs. GraphQL vs. RPC, list vs. detail) enforcing the *same* check.
|
|
12
|
+
|
|
13
|
+
## Tools (leads, not findings)
|
|
14
|
+
- `semgrep --config p/owasp-top-ten` to surface handlers that read an id from the request and query without an ownership/tenant predicate — a lead to confirm, since "missing check" is often invisible statically.
|
|
15
|
+
- `ast-grep` to find query builders that take a client-supplied id but omit the `where: { orgId }` / ownership clause.
|
|
16
|
+
- Grep the ORM/data layer for direct `findById(params.id)`-style lookups not wrapped by an authorization helper.
|
|
17
|
+
|
|
18
|
+
## How to confirm (prefer testing over reading)
|
|
19
|
+
- **Test as two distinct identities.** Provision a lower-privileged user (and ideally a second tenant), then attempt to read/modify the first identity's resource with the second identity's credentials. Missing checks are usually invisible from a single-identity walkthrough.
|
|
20
|
+
- Enumerate one id you don't own and confirm the response — a 200 with another user's data is the finding; a 403/404 is the control working.
|
|
21
|
+
- For mass-assignment, submit an extra privileged field (e.g. `"role":"admin"`) and confirm whether it is honored server-side.
|
|
22
|
+
- Prove one BOLA/BFLA instance; do not enumerate the whole table (see the non-destructive rule in `../TEST.md`).
|
|
23
|
+
|
|
24
|
+
## Triage — lead vs. finding
|
|
25
|
+
- A material finding needs a reproducible cross-identity step, the quoted response showing the other identity's data, and real impact — not "this handler looks like it lacks a check."
|
|
26
|
+
- A blocked cross-tenant attempt (403/404, empty scoped result) is a **refuted** result — record it.
|
|
27
|
+
- Distinguish by-design: a genuinely shared/public resource, or an admin acting within granted authority, is not a finding.
|
|
28
|
+
|
|
29
|
+
## What to record (durable + ZSAM-legible)
|
|
30
|
+
- Canonical finding shape: title, scope `authorization`, severity, affected endpoint (the exact route + id parameter), reproduction (the two identities and the swapped id), evidence with git SHA + path:line, remediation.
|
|
31
|
+
- Sanitize the captured cross-tenant response with the `redact` helper — do not record another tenant's real PII as evidence; quote only enough to prove the leak.
|
|
32
|
+
|
|
33
|
+
## Frameworks
|
|
34
|
+
- OWASP Web **A01** Broken Access Control; OWASP API **API1** BOLA, **API3** BOPLA, **API5** BFLA.
|
|
35
|
+
- OWASP ASVS V4 (Access Control); WSTG-ATHZ-01…04.
|
|
36
|
+
- CWE-284, CWE-639 (IDOR), CWE-862 (missing authorization), CWE-285 (improper authorization), CWE-915 (mass-assignment).
|
|
37
|
+
|
|
38
|
+
## Not in this scope / not here
|
|
39
|
+
- *Establishing* identity (login, MFA) is `auth`; token/session handling is `session`; the endpoint inventory that tells you which objects exist is `architecture`.
|
|
40
|
+
- No privilege-escalation exploit chains here — proving one cross-identity access is confirmation; chaining it into full account takeover is the professional (paid) tier, as is independent verification.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Scope: Business Logic
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- Workflow / state-machine bypass — skipping a required step (e.g. reaching order-complete without a payment callback, or a "verified" state without verification) (WSTG-BUSL-06, CWE-840).
|
|
7
|
+
- Race conditions on shared resources — coupon/credit reuse, double-spend, quota bypass via concurrent requests (WSTG-BUSL-, CWE-362/CWE-367 TOCTOU).
|
|
8
|
+
- Server-trusted value tampering — price, quantity, discount, or role passed from the client and trusted server-side (CWE-472).
|
|
9
|
+
- Abuse of a legitimate feature at unintended scale — mass account/coupon creation, referral/invite abuse, unbounded free-tier actions (API6, CWE-799).
|
|
10
|
+
- Negative/overflow quantities, replayed idempotent operations, and step-reordering.
|
|
11
|
+
|
|
12
|
+
## Tools (leads, not findings)
|
|
13
|
+
- Static tools do **not** find these — they require walking the actual multi-step flow. Use code reading only to *map* the state machine and the trust assumptions, then test the flow.
|
|
14
|
+
- A scripted concurrency harness (a handful of parallel requests) is a legitimate confirmation aid for a race — not a scanner, and rate-bounded per `../TEST.md`.
|
|
15
|
+
|
|
16
|
+
## How to confirm (prefer testing over reading)
|
|
17
|
+
- Walk the flow as a user would, then **replay, reorder, and race** the requests: submit the final step without the prerequisite; replay a one-time action; fire N concurrent requests against a single-use resource and check whether it was consumed more than once.
|
|
18
|
+
- Tamper a server-trusted value (price/quantity/role) in the request and confirm whether the server recomputes it or trusts the client value.
|
|
19
|
+
- For scale abuse, perform the action a few times to prove the missing limit — do not run it to actual exhaustion.
|
|
20
|
+
|
|
21
|
+
## Triage — lead vs. finding
|
|
22
|
+
- A material finding needs the reproducible ordered/raced steps and quoted evidence of the invariant broken (e.g. "coupon `X` applied twice, balance reflects double credit") — a hypothesis about the state machine is not a finding.
|
|
23
|
+
- A race that the server correctly serializes (idempotency key honored, single consumption) is a **refuted** result — record it.
|
|
24
|
+
- Distinguish by-design: an intentionally repeatable action, or a limit the app deliberately doesn't impose, is not a finding.
|
|
25
|
+
|
|
26
|
+
## What to record (durable + ZSAM-legible)
|
|
27
|
+
- Canonical finding shape: title, scope `business-logic`, severity, affected flow/endpoint sequence, reproduction (the exact request order/timing), evidence with git SHA + path:line, remediation (server-side recompute, idempotency, locking).
|
|
28
|
+
- Sanitize captured requests/responses with the `redact` helper.
|
|
29
|
+
|
|
30
|
+
## Frameworks
|
|
31
|
+
- OWASP Web **A04** Insecure Design; OWASP API **API6** Unrestricted Access to Sensitive Business Flows.
|
|
32
|
+
- OWASP ASVS V11 (Business Logic); WSTG-BUSL-01…09.
|
|
33
|
+
- CWE-840 (business-logic errors), CWE-362/CWE-367 (race/TOCTOU), CWE-472 (trusted client value), CWE-799 (improper control of interaction frequency).
|
|
34
|
+
|
|
35
|
+
## Not in this scope / not here
|
|
36
|
+
- Generic missing object-level authorization is `authorization`; injection into a sink is `input`; rate limiting as an API control is `api`. This scope is about abusing *intended* functionality.
|
|
37
|
+
- No exploit chains or automated abuse tooling here — proving one broken invariant is confirmation; weaponizing it and independently verifying it are the professional (paid) tier.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Scope: Data Protection
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- Sensitive data in logs and error responses — credentials, tokens, PII, or stack traces leaking to clients or logs (WSTG-ERRH, CWE-209/CWE-532).
|
|
7
|
+
- Overbroad API responses — endpoints returning more fields than the caller needs (internal ids, other-user data, password hashes) (API3, CWE-213).
|
|
8
|
+
- Encryption at rest for credentials and PII — sensitive columns/blobs stored plaintext or reversibly (CWE-311/CWE-312).
|
|
9
|
+
- Encryption in transit — TLS actually enforced (HSTS, no plaintext fallback), no mixed content, secrets never in URLs (WSTG-CRYP-01, CWE-319).
|
|
10
|
+
- Weak or misused cryptography — ECB mode, static IVs, MD5/SHA1 for integrity, home-rolled crypto (CWE-327).
|
|
11
|
+
- Data retention / exposure in caches, backups, and third-party sinks.
|
|
12
|
+
|
|
13
|
+
## Tools (leads, not findings)
|
|
14
|
+
- `gitleaks` and `semgrep --config p/secrets` to flag secrets and PII reaching logs — leads to a call site.
|
|
15
|
+
- `semgrep --config p/owasp-top-ten` for weak-crypto primitives (ECB, MD5, static IV) and verbose error handlers.
|
|
16
|
+
- A TLS checker (e.g. `testssl.sh`) against a running endpoint as a lead generator for transit config.
|
|
17
|
+
|
|
18
|
+
## How to confirm (prefer testing over reading)
|
|
19
|
+
- **Read the actual response body** an authenticated-but-unprivileged caller receives, not just the schema — over-fetching is the common gap between intended and actual exposure. Compare fields returned vs. fields the caller needs.
|
|
20
|
+
- Trigger an error path and inspect what the client actually gets (stack trace? internal ids? SQL?).
|
|
21
|
+
- Confirm at-rest encryption by reading how the sensitive column/blob is actually written (is it ciphertext, or plaintext with an "encrypted" name?).
|
|
22
|
+
- Confirm TLS enforcement by attempting a plain-HTTP request and checking for a redirect + HSTS, not by trusting config.
|
|
23
|
+
|
|
24
|
+
## Triage — lead vs. finding
|
|
25
|
+
- A material finding needs the quoted response/log showing the actual exposed data and its sensitivity — "the schema has a `ssn` field" is not exposure; "this endpoint returns `ssn` to a peer user" is.
|
|
26
|
+
- A response that is correctly minimized, or a column that is genuinely encrypted, is a **refuted** result — record it.
|
|
27
|
+
- Distinguish by-design: a field the caller is entitled to, or a deliberately public dataset, is not a finding.
|
|
28
|
+
|
|
29
|
+
## What to record (durable + ZSAM-legible)
|
|
30
|
+
- Canonical finding shape: title, scope `data`, severity, affected endpoint/store, reproduction, evidence with git SHA + path:line, remediation (field allow-list, encryption, TLS enforcement).
|
|
31
|
+
- **This scope handles sensitive data by nature** — the `redact` helper must strip the real PII/credentials from evidence; quote only enough (field names, a masked sample) to prove exposure, never the live data.
|
|
32
|
+
|
|
33
|
+
## Frameworks
|
|
34
|
+
- OWASP Web **A02** Cryptographic Failures, **A01** Broken Access Control (over-fetch), **A09** Logging Failures; OWASP API **API3** BOPLA.
|
|
35
|
+
- OWASP ASVS V6 (Stored Cryptography), V8 (Data Protection), V9 (Communications); WSTG-CRYP, WSTG-ERRH.
|
|
36
|
+
- CWE-311/CWE-312 (missing/cleartext encryption), CWE-319 (cleartext transit), CWE-327 (broken crypto), CWE-209/CWE-532 (info in errors/logs), CWE-213 (intended exposure).
|
|
37
|
+
|
|
38
|
+
## Not in this scope / not here
|
|
39
|
+
- Credential *storage hashing* specifics live in `auth`; secret *management/rotation* lives in `secrets`; the access-control decision behind over-fetch lives in `authorization`.
|
|
40
|
+
- No data-exfiltration tooling or chains here — proving one exposure is confirmation; walking the whole dataset or building an exfil chain is the professional (paid) tier, as is independent verification.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Scope: Dependency Risk
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record. The central discipline here is **reachability triage: prioritize by dependency-tree depth, not the scanner's CVSS label** — the two are uncorrelated in practice.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- Known-vulnerable dependencies (SCA) against the resolved lockfile, transitive included (A06, CWE-1104).
|
|
7
|
+
- **Reachability** of each CVE — is the vulnerable *function* actually imported, called, and fed attacker-controlled input on a live path? An unreachable CVE is Low/Informational, not Critical.
|
|
8
|
+
- Dependency confusion / substitution — an internal package name also claimable/resolvable on a public registry (A08, CWE-494, T1195.002).
|
|
9
|
+
- Typosquat and low-reputation packages — name similarity to a popular package, recent publish, single maintainer, tiny download count.
|
|
10
|
+
- Install-time script risk — `preinstall`/`postinstall`, `setup.py` execution running untrusted code.
|
|
11
|
+
- Unmaintained/abandoned packages in a sensitive code path.
|
|
12
|
+
|
|
13
|
+
## Tools (leads, not findings)
|
|
14
|
+
- `osv-scanner` and/or `trivy fs` against the **lockfile** (`package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `poetry.lock`, `go.sum`, `Gemfile.lock`) — resolved versions, not declared ranges.
|
|
15
|
+
- **Confirm the tool actually resolved the manifest before trusting a clean result.** A Python `requirements.txt` with only unpinned `>=` ranges and no lockfile can make trivy's pip parser silently skip the file (`Number of language-specific files num=0` in its log) — that "0 vulnerabilities" means *never scanned*, not *nothing found*. An unscanned target and a clean target must never read the same.
|
|
16
|
+
- `npm ls <pkg>` / `yarn why <pkg>` to resolve which direct dependency pulls a transitive package in.
|
|
17
|
+
|
|
18
|
+
## How to confirm (prefer testing over reading)
|
|
19
|
+
Reachability triage — prioritize by depth, not CVSS:
|
|
20
|
+
- **Build the worklist from the scanner output ∩ the manifest's direct deps.** Split into three buckets, traced in this order: (1) **direct + runtime** — trace every one regardless of severity; (2) **direct + dev/build-only** — fast-classify as "not shipped" unless it processes untrusted input at build time; (3) **transitive-only** — logged as an explicit, named coverage gap, *not traced this pass* and not silently dropped.
|
|
21
|
+
- **For each bucket-1 package:** grep the app's own source (not `node_modules`) for every import form — plain, subpath (`pkg/submodule`), and `require()`; read the actual call site; cross-reference the CVE's described mechanism against what the code invokes (a CVE in a lib's `v3` UUID function doesn't apply if the app only calls `v4()`); check whether attacker-controlled input reaches the call site and whether auth runs *before* the vulnerable code (middleware order matters).
|
|
22
|
+
- **Architecture gate:** a framework's server-side CVE is inert if the target is a static export with no live server; a Node-only code path is dead once bundled for the browser — confirm the deploy topology before tracing.
|
|
23
|
+
|
|
24
|
+
## Triage — lead vs. finding
|
|
25
|
+
Classify each CVE with a verdict (the label carries the reasoning, not a number):
|
|
26
|
+
- **Reachable-confirmed** — imported, called, attacker-reachable, no mitigating precondition. Candidate for its own finding.
|
|
27
|
+
- **Reachable-but-contingent** — called but gated (auth-gated route, needs a separate unconfirmed precondition, or the mechanism isn't on attacker input).
|
|
28
|
+
- **Not-imported** — in the manifest but never referenced (a dead dependency to remove).
|
|
29
|
+
- **Not-applicable** — the specific vulnerable function is never the one invoked.
|
|
30
|
+
- **Indeterminate — follow-up** — genuinely couldn't resolve (huge blast radius); say so and name it next, don't guess.
|
|
31
|
+
|
|
32
|
+
Depth-first exists to fight two failure modes: false priority (a Critical 6 hops deep in dev tooling ahead of a Medium on an unauthenticated runtime route) and confirmation bias (re-labeling the scanner's rating as *your* severity).
|
|
33
|
+
|
|
34
|
+
## What to record (durable + ZSAM-legible)
|
|
35
|
+
- Emit a **reachability worksheet** (one row per traced package: name, installed version, CVE ids + scanner severity, imported? with `file:line`, verdict, reasoning).
|
|
36
|
+
- For each Reachable-confirmed CVE, emit a canonical finding (title, scope `dependencies`, severity *after* triage, affected package + call site, reproduction, evidence with git SHA + path:line, remediation = the fixed version).
|
|
37
|
+
- **Name the untraced transitive bucket explicitly**, with how many carry the scanner's top severity — that gap is the evidence that severity and reachability are uncorrelated. Sanitize with the `redact` helper.
|
|
38
|
+
|
|
39
|
+
## Frameworks
|
|
40
|
+
- OWASP Web **A06** Vulnerable & Outdated Components, **A08** Software & Data Integrity Failures.
|
|
41
|
+
- OWASP ASVS V14 (Configuration); CWE-1104 (unmaintained components), CWE-494 (download without integrity check), CWE-1035.
|
|
42
|
+
- MITRE ATT&CK T1195 / T1195.002 (supply-chain compromise).
|
|
43
|
+
|
|
44
|
+
## Not in this scope / not here
|
|
45
|
+
- Secrets committed in dependency configs are `secrets`; IaC/container base-image scanning is `infra`; AI/model-supply-chain (poisoned weights, model-hub typosquats) is `ai`.
|
|
46
|
+
- No exploit development against a confirmed CVE, and no automated verifier. Weaponizing a reachable CVE and independently verifying the triage are the professional (paid) tier.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Scope: Frontend Security
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- Cross-site scripting — reflected, stored, and DOM-based, at every sink where untrusted data reaches HTML/JS (`innerHTML`, `dangerouslySetInnerHTML`, `document.write`, `eval`, template rendering) (WSTG-CLNT-01/02, A03, CWE-79).
|
|
7
|
+
- Content-Security-Policy strength and coverage — is there a CSP, and is it meaningfully restrictive (no `unsafe-inline`/`unsafe-eval`, no wildcard sources)? (CWE-1021).
|
|
8
|
+
- `postMessage` handling — origin validation on receive; not blindly trusting `event.data` (CWE-346).
|
|
9
|
+
- Client-side storage of sensitive data — tokens/PII in `localStorage`/`sessionStorage` where XSS can read them (CWE-522).
|
|
10
|
+
- Secrets/keys in the shipped bundle — anything in the JS bundle is public (see `secrets`).
|
|
11
|
+
- Clickjacking / framing controls, and open redirects driven by a client-controlled URL (CWE-601).
|
|
12
|
+
|
|
13
|
+
## Tools (leads, not findings)
|
|
14
|
+
- `semgrep --config p/react --config p/owasp-top-ten` for dangerous sinks (`dangerouslySetInnerHTML`, `innerHTML = userInput`, `eval`) — leads to a rendered context to confirm.
|
|
15
|
+
- Inspect the real response headers for `Content-Security-Policy`, `X-Frame-Options`, `Strict-Transport-Security` (a live check, not the config that *should* set them).
|
|
16
|
+
- Grep the built bundle for `localStorage.setItem(` on token-shaped values and for key-shaped strings.
|
|
17
|
+
|
|
18
|
+
## How to confirm (prefer testing over reading)
|
|
19
|
+
- **Test rendered output in a real browser context** where feasible — a value that looks escaped in source can still execute depending on where in the DOM it lands. Confirm XSS with a benign, non-persistent marker (e.g. a payload that triggers a harmless `console`/DOM change), not a credential-stealing payload.
|
|
20
|
+
- For DOM XSS, trace the source (URL/`postMessage`/storage) to the sink and confirm the sink executes it.
|
|
21
|
+
- For CSP, confirm the header is actually sent and whether it would block an inline script — a policy present but containing `unsafe-inline` is not protection.
|
|
22
|
+
- For `postMessage`, send a message from an unexpected origin and confirm whether the handler processes it.
|
|
23
|
+
|
|
24
|
+
## Triage — lead vs. finding
|
|
25
|
+
- A material finding needs the reproducible rendering + quoted evidence the marker executed (or the token is readable from JS) — a flagged sink fed only escaped/trusted data is **refuted**.
|
|
26
|
+
- A sink whose framework auto-escapes, or a CSP that correctly blocks the marker, is a **refuted** result — record it.
|
|
27
|
+
- Distinguish by-design: a publishable client key, or content the app intentionally renders as trusted HTML from a trusted source, is not a finding.
|
|
28
|
+
|
|
29
|
+
## What to record (durable + ZSAM-legible)
|
|
30
|
+
- Canonical finding shape: title, scope `frontend`, severity, affected component/route + the DOM sink, reproduction (the benign marker + steps), evidence with git SHA + path:line, remediation (encode on output, framework-safe rendering, tighten CSP, validate `postMessage` origin).
|
|
31
|
+
- Keep the marker benign and sanitize captures with the `redact` helper.
|
|
32
|
+
|
|
33
|
+
## Frameworks
|
|
34
|
+
- OWASP Web **A03** Injection (XSS), **A05** Security Misconfiguration (CSP/headers).
|
|
35
|
+
- OWASP ASVS V5 (Encoding/Output), V14 (Config); WSTG-CLNT-01…13.
|
|
36
|
+
- CWE-79 (XSS), CWE-1021 (framing/CSP), CWE-346 (origin validation), CWE-601 (open redirect), CWE-522 (client-side secret storage).
|
|
37
|
+
|
|
38
|
+
## Not in this scope / not here
|
|
39
|
+
- Server-side injection into non-browser sinks is `input`; secrets in the bundle overlap with `secrets`; the auth/session cookie flags that protect a token live in `session`.
|
|
40
|
+
- **No credential-stealing or persistent XSS payloads here** — confirmation stops at a benign marker proving the sink executes. Weaponizing XSS (session theft, chained exploitation) and independent verification are the professional (paid) tier.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Scope: Infrastructure & IaC
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record. Only applicable where the repository actually defines infrastructure — confirm IaC files, Dockerfiles, or k8s manifests exist before assuming a webapp repo owns its own infra.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- IaC misconfiguration (Terraform/CloudFormation/Pulumi/Bicep) — overly permissive security groups (`0.0.0.0/0` to sensitive ports), wildcard IAM policies, public storage buckets, disabled encryption at rest/in transit, public database endpoints (A05, CWE-16).
|
|
7
|
+
- Container hygiene — running as root, secrets baked into image layers, `latest`/unpinned or outdated base images, unnecessary packages (CWE-250/CWE-1104).
|
|
8
|
+
- Exposed management/debug/actuator endpoints reachable without authentication (Spring actuator, admin consoles, metrics, k8s dashboard) (CWE-215).
|
|
9
|
+
- Kubernetes posture — privileged/`hostPath` pods, missing network policies, over-broad RBAC, secrets as plain env.
|
|
10
|
+
- CI/CD pipeline security — secrets echoed in logs, unpinned third-party actions, over-privileged deploy credentials.
|
|
11
|
+
|
|
12
|
+
## Tools (leads, not findings)
|
|
13
|
+
- `checkov`, `tfsec`, or `trivy config` against the actual IaC files — the policy engines are the leads; don't re-derive their coverage by hand.
|
|
14
|
+
- `trivy image` / `hadolint` for Dockerfile and image-layer hygiene (root user, baked secrets, base-image age).
|
|
15
|
+
- `kube-score` / `trivy config` for k8s manifests.
|
|
16
|
+
- Grep CI workflow files for unpinned `uses:` actions and secrets printed to logs.
|
|
17
|
+
|
|
18
|
+
## How to confirm (prefer testing over reading)
|
|
19
|
+
- A scanner rule firing is a lead — confirm the resource is **actually deployed and reachable as configured**, not a commented-out example, a non-prod module, or overridden downstream. Read what the module actually instantiates.
|
|
20
|
+
- For an exposed management endpoint, confirm reachability without auth *only if it is in-scope and safe* (a single unauthenticated GET), rather than assuming from the manifest.
|
|
21
|
+
- Cross-check the deploy topology (which env this IaC targets) so a dev-only permissive rule isn't reported as a production exposure.
|
|
22
|
+
|
|
23
|
+
## Triage — lead vs. finding
|
|
24
|
+
- A material finding needs the specific resource + the misconfigured attribute quoted from the IaC (file + path:line) and evidence it applies to a real/production environment — a scanner hit on an example or disabled module is **refuted**.
|
|
25
|
+
- A rule that fires but is mitigated by a downstream override, or a management endpoint that is correctly authenticated, is a **refuted** result — record it.
|
|
26
|
+
- Distinguish by-design: an intentionally public asset bucket (static site), or a broad rule scoped to an isolated sandbox, is not a finding.
|
|
27
|
+
|
|
28
|
+
## What to record (durable + ZSAM-legible)
|
|
29
|
+
- Canonical finding shape: title, scope `infra`, severity, affected resource (the IaC block / image / manifest), reproduction (which scanner rule + the confirming read), evidence with git SHA + path:line, remediation (the specific config change).
|
|
30
|
+
- Sanitize any captured values (account ids, secrets in layers) with the `redact` helper.
|
|
31
|
+
|
|
32
|
+
## Frameworks
|
|
33
|
+
- OWASP Web **A05** Security Misconfiguration, **A02** Cryptographic Failures (encryption-at-rest); OWASP API **API8**.
|
|
34
|
+
- OWASP ASVS V14 (Configuration); CIS Benchmarks (Docker/Kubernetes/cloud) as the control reference.
|
|
35
|
+
- CWE-16 (misconfiguration), CWE-250 (unnecessary privilege), CWE-215 (exposed debug), CWE-1104 (outdated base image).
|
|
36
|
+
|
|
37
|
+
## Not in this scope / not here
|
|
38
|
+
- Dependency CVEs in application packages are `dependencies`; committed secrets are `secrets`; application-layer authorization is `authorization`. This scope is infrastructure/IaC/container/pipeline config.
|
|
39
|
+
- No cloud-account exploitation or live-infra pivoting here — confirm the misconfiguration and its reachability; exploiting it (assuming a role, pivoting) and independent verification are the professional (paid) tier.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Scope: Input Validation
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- SQL / NoSQL injection where user input reaches a query (raw SQL, string-built queries, unsafe ORM `$where`/operator injection) (WSTG-INPV-05/06, CWE-89/CWE-943).
|
|
7
|
+
- Command injection where input reaches a shell/subprocess (WSTG-INPV-12, CWE-78).
|
|
8
|
+
- Server-side template injection where input reaches a template renderer (WSTG-INPV-18, CWE-1336).
|
|
9
|
+
- Path traversal where input reaches the filesystem (`../` into read/write/include) (WSTG-ATHZ-01, CWE-22).
|
|
10
|
+
- Unsafe deserialization of untrusted input, and prototype pollution in JS (`__proto__`/`constructor` keys) (CWE-502/CWE-1321).
|
|
11
|
+
- LDAP / XPath / header / log injection at their respective sinks (CWE-90/CWE-643/CWE-117).
|
|
12
|
+
|
|
13
|
+
## Tools (leads, not findings)
|
|
14
|
+
- `semgrep --config p/owasp-top-ten --config p/command-injection` and language injection rulesets to flag sink calls (`exec`, raw query, `render(userInput)`) — leads to a call site, not findings.
|
|
15
|
+
- `ast-grep` to trace a specific tainted parameter from an entry point to a sink pattern.
|
|
16
|
+
- `CodeQL` taint queries where available give the strongest source→sink leads; still confirm reachability.
|
|
17
|
+
|
|
18
|
+
## How to confirm (prefer testing over reading)
|
|
19
|
+
- **Trace the actual data flow** from an untrusted entry point to the sink — the same sink is safe or unsafe depending on what sanitizes it upstream; don't pattern-match function names.
|
|
20
|
+
- Confirm with a **safe, benign probe**, not a weaponized payload: for SQL, a boolean/timing differential on an in-scope test record (e.g. a `' AND 1=1`/`' AND 1=2` behavior difference) rather than data extraction; for SSTI, a harmless arithmetic marker (`{{7*7}}` → `49`) rather than code execution; for path traversal, reading a known-innocuous in-scope file rather than `/etc/shadow`.
|
|
21
|
+
- Confirm parameterization actually applies at the call site (a parameterized query built by string concatenation is not parameterized).
|
|
22
|
+
|
|
23
|
+
## Triage — lead vs. finding
|
|
24
|
+
- A material finding needs a reproducible probe, the quoted differential/marker proving the sink is reached, and real attacker-controlled input — a flagged sink whose input is internal/generated is **refuted**.
|
|
25
|
+
- An input correctly rejected/escaped, or a sink fed only trusted data, is a **refuted** result — record it.
|
|
26
|
+
- Distinguish by-design: an allow-listed value, a query on a server-generated id, or an ORM call that is genuinely parameterized is not a finding.
|
|
27
|
+
|
|
28
|
+
## What to record (durable + ZSAM-legible)
|
|
29
|
+
- Canonical finding shape: title, scope `input`, severity, affected component (the exact sink + the parameter that reaches it), reproduction (the benign probe), evidence with git SHA + path:line, remediation (parameterize / escape / allow-list).
|
|
30
|
+
- Sanitize any captured request/response with the `redact` helper; keep the probe benign so the evidence is safe to store.
|
|
31
|
+
|
|
32
|
+
## Frameworks
|
|
33
|
+
- OWASP Web **A03** Injection, **A08** Software & Data Integrity (deserialization).
|
|
34
|
+
- OWASP ASVS V5 (Validation, Sanitization & Encoding); WSTG-INPV-01…19.
|
|
35
|
+
- CWE-89 (SQLi), CWE-943 (NoSQLi), CWE-78 (command), CWE-1336 (SSTI), CWE-22 (path traversal), CWE-502 (deserialization), CWE-1321 (prototype pollution).
|
|
36
|
+
|
|
37
|
+
## Not in this scope / not here
|
|
38
|
+
- XSS and other browser-rendered output injection is `frontend`; SSRF via a user-controlled outbound URL is `ssrf`; file-content handling on upload is `uploads`.
|
|
39
|
+
- **No weaponized payloads or exploit chains here** — confirmation stops at a benign marker proving the sink is reachable. Turning that into data exfiltration, RCE, or a full chain is the professional (paid) tier, as is independent verification.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Scope: Secrets Management
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- Hardcoded credentials/tokens in source, config, CI files, and container image layers (WSTG-ATHN-01, CWE-798).
|
|
7
|
+
- Secrets in git history — a rotated-but-still-committed secret is still exposed (CWE-540).
|
|
8
|
+
- Plaintext secrets in logs, error output, or client-visible responses (CWE-532).
|
|
9
|
+
- Over-broad-scoped or non-expiring tokens — a key with far more privilege/lifetime than the task needs (CWE-272 least-privilege).
|
|
10
|
+
- Secrets in the frontend bundle or public assets (see also `frontend`) — anything shipped to the browser is public.
|
|
11
|
+
- Install-time / build-time secret exposure (env echoed into logs, secrets baked into images).
|
|
12
|
+
|
|
13
|
+
## Tools (leads, not findings)
|
|
14
|
+
- `gitleaks detect --log-opts="--all"` across **full git history**, not just the working tree — history is where rotated secrets hide.
|
|
15
|
+
- `trufflehog` (filesystem/git mode) as a second detector with entropy + verification heuristics.
|
|
16
|
+
- `semgrep --config p/secrets` for provider-specific key shapes reaching code.
|
|
17
|
+
- Grep the built frontend bundle and public dirs for key-shaped strings.
|
|
18
|
+
|
|
19
|
+
## How to confirm (prefer testing over reading)
|
|
20
|
+
- Confirm a hit is a **real, live secret** and not a placeholder/example: check its format against the provider's key shape and whether it's obviously dummy (`xxxx`, `example`, `changeme`).
|
|
21
|
+
- **Do not authenticate with a discovered live secret to "prove" it** — that is exploitation and may be out of scope. Confirm validity by structure and context (where it's used, whether the surrounding config is real), and treat a plausibly-live secret as a finding requiring rotation.
|
|
22
|
+
- For git-history hits, confirm the commit and path so the exposure window is documented, even if the secret was later removed from HEAD.
|
|
23
|
+
|
|
24
|
+
## Triage — lead vs. finding
|
|
25
|
+
- A material finding needs the quoted (redacted) secret location — file/commit + path:line — and evidence it is a real credential, not a fixture or public key.
|
|
26
|
+
- A detector hit that is a documented example/placeholder, or a value that is public by design (a publishable client key), is a **refuted** result — record why.
|
|
27
|
+
- Distinguish by-design: a client-side key the vendor intends to be public is not a leaked secret; a private server key in the same file is.
|
|
28
|
+
|
|
29
|
+
## What to record (durable + ZSAM-legible)
|
|
30
|
+
- Canonical finding shape: title, scope `secrets`, severity, affected location (file/commit + path:line), reproduction (how it was found), evidence, remediation (**rotate first**, then remove from history and move to a secret manager).
|
|
31
|
+
- **Never record the raw secret.** The `redact` helper strips it — quote only a masked prefix/suffix sufficient to identify it. The finding must not become a second copy of the leak.
|
|
32
|
+
|
|
33
|
+
## Frameworks
|
|
34
|
+
- OWASP Web **A02** Cryptographic Failures, **A05** Security Misconfiguration; OWASP API **API8** Misconfiguration.
|
|
35
|
+
- OWASP ASVS V6 (Stored Cryptography), V2 (secret handling); WSTG-ATHN-01, WSTG-CONF.
|
|
36
|
+
- CWE-798 (hardcoded credentials), CWE-540 (secret in source), CWE-532 (secret in log), CWE-522 (insufficiently protected credentials).
|
|
37
|
+
|
|
38
|
+
## Not in this scope / not here
|
|
39
|
+
- Session-token *lifecycle* is `session`; dependency-supplied secrets and install-script risk overlap with `dependencies`; frontend-bundle exposure detail is `frontend`.
|
|
40
|
+
- No credential-validation-by-use or exploitation here — a discovered secret is confirmed by structure/context and rotated. Using it, and independent verification, are the professional (paid) tier.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Scope: Session Management
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- Token issuance & rotation — a new session identifier is issued on login and rotated on privilege change; no fixation-friendly reuse of a pre-auth id (WSTG-SESS-03, CWE-384).
|
|
7
|
+
- Server-side invalidation on logout — logout revokes the token server-side, not just clears the client cookie (WSTG-SESS-06, ASVS 3.3).
|
|
8
|
+
- Idle and absolute expiration — sessions time out, and an absolute lifetime caps a long-lived token (ASVS 3.3.1/3.3.2).
|
|
9
|
+
- Cookie attributes — `HttpOnly`, `Secure`, and an appropriate `SameSite` on session cookies (WSTG-SESS-02, CWE-1004/CWE-614).
|
|
10
|
+
- CSRF protection on state-changing requests — a token/double-submit/origin check, correctly enforced (WSTG-SESS-05, CWE-352).
|
|
11
|
+
- JWT handling where used — algorithm pinned (no `alg:none`, no HS/RS confusion), signature actually verified, expiry honored (API2, CWE-347).
|
|
12
|
+
- Concurrent-session and device-revocation behavior.
|
|
13
|
+
|
|
14
|
+
## Tools (leads, not findings)
|
|
15
|
+
- `semgrep --config p/owasp-top-ten` / `p/jwt` for cookies set without flags, JWT verify calls that skip signature/algorithm checks, and missing CSRF middleware — each is a lead to confirm behaviorally.
|
|
16
|
+
- Inspect real `Set-Cookie` headers from a live response (curl/browser devtools) rather than trusting the config that *should* set them.
|
|
17
|
+
- Decode a live JWT (header/claims only) to read the `alg` and expiry — never record the token itself.
|
|
18
|
+
|
|
19
|
+
## How to confirm (prefer testing over reading)
|
|
20
|
+
- **Replay after logout:** capture a session token, log out, then replay the token and confirm it is now rejected. A 200 after logout is the finding.
|
|
21
|
+
- **CSRF:** submit a state-changing request without the expected CSRF token/header (and from an off-origin referer) and confirm it is refused.
|
|
22
|
+
- **Fixation:** set a session id before login, authenticate, and confirm the id changed.
|
|
23
|
+
- **JWT:** attempt an obviously-tampered token (flipped claim, stripped signature) against a protected route and confirm rejection — a resilience check, not forging a valid admin token.
|
|
24
|
+
|
|
25
|
+
## Triage — lead vs. finding
|
|
26
|
+
- A material finding needs the reproducible replay/CSRF/fixation step plus the quoted before/after response — "middleware present" is not evidence of correct enforcement, and "middleware absent in one file" is not proof of absence on the route.
|
|
27
|
+
- A token correctly rejected after logout, or a CSRF request correctly refused, is a **refuted** result — record it.
|
|
28
|
+
- Distinguish by-design: a stateless API using short-lived bearer tokens with no server-side logout may be intentional — judge against the app's model, not a cookie-session assumption.
|
|
29
|
+
|
|
30
|
+
## What to record (durable + ZSAM-legible)
|
|
31
|
+
- Canonical finding shape: title, scope `session`, severity, affected endpoint, reproduction, evidence with git SHA + path:line (and the sanitized `Set-Cookie`/response), remediation.
|
|
32
|
+
- The `redact` helper strips the actual cookie/token values — quote the *attributes* and status codes, never the live secret.
|
|
33
|
+
|
|
34
|
+
## Frameworks
|
|
35
|
+
- OWASP Web **A07** Identification & Authentication Failures, **A05** Security Misconfiguration (CSRF); OWASP API **API2** Broken Authentication.
|
|
36
|
+
- OWASP ASVS V3 (Session Management); WSTG-SESS-01…09.
|
|
37
|
+
- CWE-384 (fixation), CWE-613 (expiration), CWE-352 (CSRF), CWE-1004/CWE-614 (cookie flags), CWE-347 (JWT signature).
|
|
38
|
+
|
|
39
|
+
## Not in this scope / not here
|
|
40
|
+
- Verifying credentials and MFA is `auth`; deciding what an authenticated session may *access* is `authorization`.
|
|
41
|
+
- No session-hijacking exploit chains or token-forgery tooling here — a rejected-tampered-token check is confirmation; forging a valid privileged token is the professional (paid) tier, as is independent verification.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Scope: SSRF
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- Any server-side outbound request whose target (host, path, or query) is influenced by user input — webhooks, URL fetchers, link/image preview generators, PDF/HTML renderers, import-from-URL, and service-to-service calls reachable from a user parameter (WSTG-INPV-19, A10/API7, CWE-918).
|
|
7
|
+
- Reachability of internal-only targets — cloud instance-metadata endpoints (`169.254.169.254` and equivalents), internal hostnames, `localhost`, and private CIDR ranges from the affected code path.
|
|
8
|
+
- Filter-bypass surface — allow/deny lists defeated by redirects, DNS rebinding, alternate encodings (decimal/hex IP, `[::]`, `0.0.0.0`), and userinfo tricks (`@`).
|
|
9
|
+
- Blind SSRF — no response returned to the user, but the outbound request still fires.
|
|
10
|
+
|
|
11
|
+
## Tools (leads, not findings)
|
|
12
|
+
- `semgrep --config p/owasp-top-ten` for HTTP-client calls whose URL argument derives from request input — a lead to the call site.
|
|
13
|
+
- `ast-grep` to trace a user-controlled URL parameter to a `fetch`/`axios`/`requests`/`http` sink.
|
|
14
|
+
- A **canary/collaborator endpoint you control** (e.g. an OOB HTTP listener) to catch outbound requests during confirmation — the SSRF analogue of a canary.
|
|
15
|
+
|
|
16
|
+
## How to confirm (prefer testing over reading)
|
|
17
|
+
- Confirm the outbound request actually fires by pointing the user-controlled URL at a **canary you control** and observing the hit — a fired callback is unambiguous proof; a string that merely *looks* like a URL is not. This proves reachability without touching any real internal service.
|
|
18
|
+
- Check whether the code path can reach an internal target *in principle* (no egress allow-list, no host validation before the request) — but **prove it with your canary, don't walk internal services or read metadata credentials**.
|
|
19
|
+
- For blind SSRF, the canary hit is the whole confirmation.
|
|
20
|
+
- Test one obvious filter bypass (a redirect to your canary) to show the allow-list is defeatable — a resilience check, not an internal pivot.
|
|
21
|
+
|
|
22
|
+
## Triage — lead vs. finding
|
|
23
|
+
- A material finding needs the canary-callback evidence (or an equivalent proven outbound) plus the user-controlled parameter that drove it — "there is a URL parameter" is not SSRF.
|
|
24
|
+
- A request correctly blocked by an egress allow-list or host validation is a **refuted** result — record it.
|
|
25
|
+
- Distinguish by-design: a fetcher restricted to a fixed allow-list of external hosts, doing exactly that, is not a finding.
|
|
26
|
+
|
|
27
|
+
## What to record (durable + ZSAM-legible)
|
|
28
|
+
- Canonical finding shape: title, scope `ssrf`, severity, affected endpoint + the URL parameter, reproduction (the canary URL and the observed hit), evidence with git SHA + path:line, remediation (egress allow-list, block internal ranges/metadata, resolve-and-validate before request).
|
|
29
|
+
- Use *your own* canary token as evidence; the `redact` helper strips anything sensitive that came back — never record real internal responses or metadata credentials.
|
|
30
|
+
|
|
31
|
+
## Frameworks
|
|
32
|
+
- OWASP Web **A10** SSRF; OWASP API **API7** SSRF.
|
|
33
|
+
- OWASP ASVS V12 (Files & Resources / SSRF); WSTG-INPV-19.
|
|
34
|
+
- CWE-918 (SSRF); MITRE ATT&CK T1090.
|
|
35
|
+
|
|
36
|
+
## Not in this scope / not here
|
|
37
|
+
- Generic injection into non-network sinks is `input`; outbound calls to third-party APIs whose *responses* are unsafely trusted is closer to `api` (API10). This scope is user-influenced *outbound request targets*.
|
|
38
|
+
- **Prove the callback, don't walk internal services.** Pivoting from a confirmed SSRF into the internal network, or reading cloud-metadata credentials, is real exploitation — the professional (paid) tier, as is independent verification.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Scope: File Upload
|
|
2
|
+
|
|
3
|
+
Narrow by design — read `../TEST.md` first for the guidance that applies across every scope. This overlay tells you *what* to probe, *which* tools give you leads, *how* to confirm a real issue, and *what* to record.
|
|
4
|
+
|
|
5
|
+
## What to test (OWASP-mapped)
|
|
6
|
+
- File-type validation — declared extension/MIME vs. actual content; is validation server-side and content-based, or client-side/extension-only? (WSTG-BUSL-09, CWE-434).
|
|
7
|
+
- Storage location relative to the web root — is an uploaded file directly servable/executable from a public path? (CWE-434/CWE-668).
|
|
8
|
+
- Filename handling — path traversal (`../`), overwrite of existing files, null-byte/encoding tricks, and unsanitized names reaching the filesystem (CWE-22).
|
|
9
|
+
- Downstream processing of uploaded content — image/document/archive parsers (ImageMagick, PDF, zip), thumbnailing, and any parser that could be fed a malicious file (CWE-434 → parser CVEs).
|
|
10
|
+
- Size/quantity limits — unbounded uploads (resource exhaustion), and zip-bomb/decompression amplification (CWE-409).
|
|
11
|
+
- SVG/HTML upload leading to stored XSS when served inline (see `frontend`).
|
|
12
|
+
|
|
13
|
+
## Tools (leads, not findings)
|
|
14
|
+
- `semgrep --config p/owasp-top-ten` for upload handlers that trust `req.file.mimetype`/the client-supplied name, or write into a web-served directory — leads to confirm.
|
|
15
|
+
- Grep the storage layer for how the destination path and filename are constructed from the upload.
|
|
16
|
+
- A known-benign polyglot/mismatched-type test file to exercise validation (a harmless file whose extension and content disagree).
|
|
17
|
+
|
|
18
|
+
## How to confirm (prefer testing over reading)
|
|
19
|
+
- **Verify enforcement server-side**, not in the client form: upload a file whose declared type doesn't match its real content and observe what the server does with it.
|
|
20
|
+
- Confirm where the file lands and whether it's reachable — request the stored file back; a file executed or served inline from the web root is the impact, not the upload itself.
|
|
21
|
+
- Test a traversal filename (`../` in the name) and confirm whether it escapes the intended directory — a resilience check on a scratch path, never overwriting real files.
|
|
22
|
+
- Keep every test file benign (a marker image/text), not a webshell or exploit — you are confirming the *gap*, not planting a payload.
|
|
23
|
+
|
|
24
|
+
## Triage — lead vs. finding
|
|
25
|
+
- A material finding needs the reproducible upload + the quoted evidence of impact (file served from web root, traversal escaped, parser fed a mismatched type) — "there is an upload endpoint" is not a finding.
|
|
26
|
+
- Validation that correctly rejects the mismatched/traversal file is a **refuted** result — record it.
|
|
27
|
+
- Distinguish by-design: an upload that is validated, stored outside the web root, and served through a controlled handler is working as intended.
|
|
28
|
+
|
|
29
|
+
## What to record (durable + ZSAM-legible)
|
|
30
|
+
- Canonical finding shape: title, scope `uploads`, severity, affected endpoint + storage path, reproduction (the test file + steps), evidence with git SHA + path:line, remediation (content-type validation, randomized names, storage outside web root, disable inline serving).
|
|
31
|
+
- Sanitize with the `redact` helper; keep the uploaded test artifact benign so the evidence is safe.
|
|
32
|
+
|
|
33
|
+
## Frameworks
|
|
34
|
+
- OWASP Web **A04** Insecure Design, **A03** Injection (via processed content); OWASP API **API6**.
|
|
35
|
+
- OWASP ASVS V12 (Files & Resources); WSTG-BUSL-09.
|
|
36
|
+
- CWE-434 (unrestricted upload), CWE-22 (path traversal), CWE-668 (exposure to wrong sphere), CWE-409 (decompression bomb).
|
|
37
|
+
|
|
38
|
+
## Not in this scope / not here
|
|
39
|
+
- Stored-XSS from served content is `frontend`; path traversal in non-upload sinks is `input`; the parser library's own CVE reachability is `dependencies`.
|
|
40
|
+
- **No webshells or weaponized upload payloads here** — confirmation stops at a benign mismatched/traversal file proving the gap. Turning it into code execution, and independent verification, are the professional (paid) tier.
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zivis/appsec-pack",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "ZIVIS AppSec testing methodology — public self-service pack consumed by `zivis test`. See methodology-packs/appsec/pack.yaml for the authoring source.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://zivis.ai",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/zivisai/zivis-platform.git",
|
|
10
|
+
"directory": "methodology-packs/appsec"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"DISCLOSURE",
|
|
15
|
+
"LICENSE",
|
|
16
|
+
"NOTICE",
|
|
17
|
+
"TRADEMARK.md"
|
|
18
|
+
],
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"contentPolicy": {
|
|
23
|
+
"class": "dual-use"
|
|
24
|
+
},
|
|
25
|
+
"zivisPack": {
|
|
26
|
+
"packId": "appsec",
|
|
27
|
+
"packType": "appsec",
|
|
28
|
+
"minCliVersion": "0.1.0-alpha.1"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "pnpm --filter @zivis/cli run build:methodology-pack -- --pack=appsec"
|
|
32
|
+
}
|
|
33
|
+
}
|