You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SODCOV-000: one sentence saying how far the SoD result can be believed
This module emits up to ten separate findings about the trustworthiness of a
segregation result - coverage on two surfaces, whether a wildcard makes the
measurement unbounded, rules that can never fire, a supplied ruleset that is
broken or silently overriding ours. An auditor does not want ten. They want one
sentence they can put in a workpaper, and a reader made to assemble that
sentence themselves will assemble it wrongly or not at all.
On the sample estate it reads:
This segregation-of-duties result is UNBOUNDED - 2 stated limits: at least
one role grants every transaction, so the estate reaches more than was
measured and the percentages are a floor rather than a figure; the ruleset
names 0% of this estate's Fiori surface, so a conflict reachable only
through an app is outside what any result here can find.
FOUR VERDICTS
not measured the authorization export was not supplied, so no statement
about breadth is possible and a percentage would be invented
unbounded a wildcard grant means every figure is a floor
partial a surface is named too thinly to carry the result
usable no limit was found that would qualify it
The last one says so EXPLICITLY rather than staying silent. "We looked and found
no limit" is a different claim from "we did not look", and keeping those apart
is what this module is for.
TWO RULES, EACH PINNED BY A TEST
The verdict is the WEAKEST dimension, never an average. Averaging 93% of
transactions against 0% of Fiori produces a comfortable 47% that describes
neither surface, and a summary which buries its worst input is precisely the
failure the ten checks beneath it exist to report.
It is DERIVED from the findings already emitted, not recomputed. `derived_from`
names its sources. A summary that recalculates can disagree with its own detail,
and then the report contradicts itself in front of the reader least equipped to
tell which half to believe.
The limits are ordered worst-first, because the remediation says to work them in
order and the first is the one that decides what the report is worth.
THE GUARD FROM THE LAST COMMIT EARNED ITS KEEP IMMEDIATELY
Adding this check grew the catalogue from 790 to 791, and
tests/test_firing_reference.py failed because docs/CHECK_FIRING.md no longer
reconciled. That is the CI gate added one commit ago catching a real staleness
on the very next change, which is about the best validation it could get.
Regenerated: 704 of 791 proven to fire.
Full suite green: 4456 passed. Smoke run 409 findings. Nine new tests, a
knowledge-base entry, references at 446 literal / 791 total.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: data/finding_details.json
+5Lines changed: 5 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -2329,6 +2329,11 @@
2329
2329
"module": "s4_business_authz",
2330
2330
"risk": "On SAP BTP, application authorizations are packaged as role collections, and trust configuration can map a role collection to an IdP group. Mapping a role collection to the 'Default' group (or a wildcard / all-authenticated value) turns it into a BIRTHRIGHT assignment: every user who successfully authenticates through the corporate IdP receives that collection automatically, with no explicit provisioning. If the collection carries only genuinely universal, low-privilege access such as a basic launchpad viewer, this is acceptable; if it carries anything beyond baseline, the entire authenticated population is silently over-provisioned. Birthright grants are easy to overlook during recertification because they are not attached to individual users, so the access is invisible in per-user reviews yet fully effective at runtime. Attack scenario: an attacker who obtains any valid federated identity (a compromised SSO account, or an over-broad IdP that lets many people authenticate) immediately inherits whatever the default-mapped collection grants, potentially reaching applications, APIs, or data that should require explicit entitlement, and without any access request to trip an alert. The insider risk is parallel: any employee can reach the function without ever being formally granted it. Impact includes violation of least privilege and need-to-know, GDPR over-exposure if the collection reaches PII, and an audit finding that access is not individually authorized or recertifiable. A real incident looks like users exercising an app they were never explicitly provisioned for, traced back to a default-group mapping."
2331
2331
},
2332
+
"SODCOV-000": {
2333
+
"mitigation": "1. Quote the verdict, not the conflict count, when recording what this analysis covered. A conflict count on its own describes the ruleset rather than the estate, and is the figure most often carried into a report without the scope that makes it meaningful.\n2. Work the stated limits in the order given. They are ordered by how much each undermines the result, so the first is the one that decides what the rest of the report is worth.\n3. Where a limit cannot be closed before the deadline, record it as scope rather than treating the areas it affects as assessed. An unasked question and a good answer look identical on a page that does not distinguish them, and only one of them is evidence.\n4. Do not average the underlying measures to produce a friendlier number. Broad transaction coverage against a Fiori surface the ruleset cannot see gives a figure that describes neither surface.\n5. Re-run after closing any limit. The verdict is derived from the checks beneath it, so it moves on its own once the underlying measure does - it does not need editing.",
2334
+
"module": "ruleset_coverage",
2335
+
"risk": "A segregation-of-duties report is read as a statement about an estate, and it is only ever a statement about the part of that estate the ruleset could see. This finding is the one sentence that says which. Without it a reader has to assemble the qualification themselves from up to ten separate coverage findings - transaction and Fiori breadth, whether a wildcard grant makes the measurement unbounded, rules that can never fire because they name authorization objects this release does not define, a supplied ruleset that is broken or silently replacing rules - and a reader made to do that will either do it wrongly or not at all. The verdict is deliberately the weakest of the measures beneath it rather than an average. Averaging broad transaction coverage against a Fiori surface the ruleset does not name at all produces a comfortable middle number that describes neither, and a summary which buries its worst input is precisely the failure the checks beneath it exist to report. It is also derived from those findings rather than recalculated, so the summary and the detail cannot disagree - a report that contradicts itself does so in front of the person least equipped to tell which half to believe."
2336
+
},
2332
2337
"SODCOV-001": {
2333
2338
"mitigation": "1. Open the unseen-transaction list on this finding — it names every standard transaction granted somewhere in the estate that no rule refers to.\n2. Sort them into three piles with somebody who knows the business processes: irrelevant to segregation of duties (most display transactions), a genuine gap that belongs in the ruleset, or a transaction whose risk is already covered by a rule naming a different code for the same capability.\n3. Add the second pile to the ruleset, each with the authorization object, field and values that make the action meaningful rather than the transaction code alone.\n4. Re-run the scan and confirm the coverage figure moved.\n5. Record a decision for the first pile. Doing nothing is a legitimate answer; leaving it unexamined is not, and the point of publishing this number is to make the difference visible.",
<pclass="lede">If you read nothing else, read this. Everything after it is elaboration.</p>
690
690
691
691
<h4>The idea in three sentences</h4>
692
-
<p>Somebody takes a set of photographs of how the SAP system is currently configured — lists of users, roles, settings, connections, and so on — and saves them as ordinary files. MonitorRisk reads those files on a computer that has no connection to SAP at all, and applies <strong>790 checks</strong> written by people who know SAP well. It produces a report that says what is wrong, how bad it is, what to do about it, who is able to do it, and what it is worth in money.</p>
692
+
<p>Somebody takes a set of photographs of how the SAP system is currently configured — lists of users, roles, settings, connections, and so on — and saves them as ordinary files. MonitorRisk reads those files on a computer that has no connection to SAP at all, and applies <strong>791 checks</strong> written by people who know SAP well. It produces a report that says what is wrong, how bad it is, what to do about it, who is able to do it, and what it is worth in money.</p>
<pathclass="ln" d="M914 93 H 984" marker-end="url(#ar)"/>
@@ -729,7 +729,7 @@ <h4>The seven questions it answers</h4>
729
729
730
730
<divclass="tw"><table>
731
731
<tr><thclass="k" style="width:4%"></th><thstyle="width:26%">Question</th><th>How it is answered</th></tr>
732
-
<tr><tdclass="k">1</td><td><strong>What is wrong?</strong></td><td>790 checks across 36 subject areas produce a list of findings, each naming the specific accounts, roles, settings or connections involved.</td></tr>
732
+
<tr><tdclass="k">1</td><td><strong>What is wrong?</strong></td><td>791 checks across 36 subject areas produce a list of findings, each naming the specific accounts, roles, settings or connections involved.</td></tr>
733
733
<tr><tdclass="k">2</td><td><strong>How bad is each one?</strong></td><td>A severity from Critical to Low, assigned by the check itself according to what an attacker could achieve.</td></tr>
734
734
<tr><tdclass="k">3</td><td><strong>What should we do first?</strong></td><td>A priority from P1 to P4 that combines severity with whether the flaw is known to be exploited, how exposed it is, and how much privilege it confers.</td></tr>
735
735
<tr><tdclass="k">4</td><td><strong>What exactly do we do?</strong></td><td>A numbered remediation procedure naming the specific SAP transaction, parameter or table to change, how to verify it worked, and what to be careful of.</td></tr>
@@ -1175,7 +1175,7 @@ <h4>Route C — a source-code export</h4>
1175
1175
<p>When the customer supplies one, a further module unpacks it and analyses the code itself, applying <strong>136 rules</strong> for the classic weaknesses described in chapter 3, family 6.</p>
1176
1176
1177
1177
<h4>Why convergence matters more than it sounds</h4>
1178
-
<p>Because all three routes produce the same shape of information, none of the 790 checks contains any logic about provenance. There is no “if this came from the collector, be more careful” branch anywhere. Adding Route B required no changes to the checking logic at all, and required no new tests of the checks, because the checks could not tell the difference.</p>
1178
+
<p>Because all three routes produce the same shape of information, none of the 791 checks contains any logic about provenance. There is no “if this came from the collector, be more careful” branch anywhere. Adding Route B required no changes to the checking logic at all, and required no new tests of the checks, because the checks could not tell the difference.</p>
1179
1179
<p>This is a general principle worth naming, since it recurs later in the book: <strong>push variation to the edges</strong>. Let the outside of the system deal with the messy diversity of the real world, and let the middle see one clean, uniform thing.</p>
1180
1180
1181
1181
<divclass="call takeaway">
@@ -1374,7 +1374,7 @@ <h4>Line by line</h4>
1374
1374
</table></div>
1375
1375
1376
1376
<h4>Why 685 of these are hard</h4>
1377
-
<p>If one check is fifteen lines, 790 checks are not simply nine thousand lines of the same thing. The difficulty is elsewhere:</p>
1377
+
<p>If one check is fifteen lines, 791 checks are not simply nine thousand lines of the same thing. The difficulty is elsewhere:</p>
1378
1378
<ul>
1379
1379
<li><strong>Knowing what to check.</strong> Most of the value is the accumulated knowledge of which settings matter and why. A cryptic permission with a wildcard value can mean “may impersonate any user from a trusted system”. Knowing that is decades of SAP experience, not programming.</li>
1380
1380
<li><strong>Knowing when not to fire.</strong> A check that reports something harmless trains the reader to ignore it. The single most common cause of a security tool being abandoned is false alarms.</li>
@@ -1490,7 +1490,7 @@ <h4>What is deliberately not in the record</h4>
1490
1490
<p>The long explanation of why something is dangerous, and the step-by-step instructions for fixing it, are not stored in the finding. They live in a separate knowledge base, looked up by check identifier when a report is written (chapter <ahref="#ch20">20</a>). Two reasons:</p>
1491
1491
<ul>
1492
1492
<li>The same finding may appear five hundred times in one scan — once per affected role. Storing a page of narrative five hundred times would be wasteful and would make the record awkward to move around.</li>
1493
-
<li>Improving the guidance for 790 checks becomes an edit to a content file rather than a change to thirty programs, which means it can be done by the person who knows SAP best rather than the person who writes code best.</li>
1493
+
<li>Improving the guidance for 791 checks becomes an edit to a content file rather than a change to thirty programs, which means it can be done by the person who knows SAP best rather than the person who writes code best.</li>
1494
1494
</ul>
1495
1495
1496
1496
<divclass="call takeaway">
@@ -1620,7 +1620,7 @@ <h4>Relationships, not just values</h4>
1620
1620
<sectionclass="part" id="part5">
1621
1621
<divclass="pnum">Part five</div>
1622
1622
<h2class="parth">Making sense of the results</h2>
1623
-
<pclass="pintro">790 checks against a real estate can produce thousands of findings. An undifferentiated list of thousands of problems is not information; it is a way of guaranteeing that nothing gets fixed. This part is about turning the list into decisions.</p>
1623
+
<pclass="pintro">791 checks against a real estate can produce thousands of findings. An undifferentiated list of thousands of problems is not information; it is a way of guaranteeing that nothing gets fixed. This part is about turning the list into decisions.</p>
1624
1624
<olclass="plist">
1625
1625
<li><b>19</b><ahref="#ch19">What to fix first</a></li>
1626
1626
<li><b>20</b><ahref="#ch20">Telling people what to actually do</a></li>
<spanclass="k">One honest note about counting</span>
2586
-
<p>The headline “790 checks” needs a footnote. <strong>445</strong> check identifiers are written out individually in the source. A further <strong>345</strong> come from <strong>six families generated at run time</strong> from shipped rule lists — one check per Web Dispatcher rule (14), one per technical parameter (79), one per code rule (136), one per duty-separation risk (99), one per imported code family (10), one per conflicting-duty pair (7). Both numbers are true; stating both is more useful than picking whichever is larger.</p>
2586
+
<p>The headline “791 checks” needs a footnote. <strong>446</strong> check identifiers are written out individually in the source. A further <strong>345</strong> come from <strong>six families generated at run time</strong> from shipped rule lists — one check per Web Dispatcher rule (14), one per technical parameter (79), one per code rule (136), one per duty-separation risk (99), one per imported code family (10), one per conflicting-duty pair (7). Both numbers are true; stating both is more useful than picking whichever is larger.</p>
2587
2587
<p>These figures are derived from the code rather than typed here, and the test suite fails if this page and the source ever disagree.</p>
2588
2588
</div>
2589
2589
@@ -2714,7 +2714,7 @@ <h4>E.3 — Refusing to print a number</h4>
2714
2714
2715
2715
<pstyle="font-size:15px;color:var(--ink2);max-width:80ch"><strong>Provenance and caveat.</strong> This book was written from the repository’s documentation and its top-level program, at <ahref="https://github.com/Krishcalin/SAP-S4HANA-RISE-Security-Scanner">github.com/Krishcalin/SAP-S4HANA-RISE-Security-Scanner</a>. Module names, the command-line surface, the pipeline order, the corpus-split rule, the gate rules and the deployment-mode behaviour are taken from the source and documentation. Descriptions of the internal structure of individual inspectors, the exact shape of a finding record, and the illustrative code in Appendix E are reconstructions written to be faithful in substance rather than literal in syntax; verify against the source before quoting them. All diagrams are architectural rather than exhaustive.</p>
2716
2716
2717
-
<pstyle="font-size:15px;color:var(--ink2);max-width:80ch">The counts this document states — 790 checks, 445 written as literals, 345 generated at run time from 6 rule families, 38 modules, 136 custom-code rules, 27 duty-separation risks, 78 profile parameters and 135 logical sources — are derived from the code by <code>tests/test_architecture_doc.py</code>, which fails the build if this page and the source disagree. Edition 1.1 corrected three figures that had drifted from the source.</p>
2717
+
<pstyle="font-size:15px;color:var(--ink2);max-width:80ch">The counts this document states — 791 checks, 446 written as literals, 345 generated at run time from 6 rule families, 38 modules, 136 custom-code rules, 27 duty-separation risks, 78 profile parameters and 135 logical sources — are derived from the code by <code>tests/test_architecture_doc.py</code>, which fails the build if this page and the source disagree. Edition 1.1 corrected three figures that had drifted from the source.</p>
2718
2718
2719
2719
<pstyle="font-size:15px;color:var(--ink2)"><strong>Confidential.</strong> This document is not for publication. It describes the internal design, the current limitations and the forward direction of a commercial product; treat it as you would any other confidential product document.</p>
0 commit comments