Skip to content

Commit 65019ba

Browse files
committed
Detect two Oracle E-Business Suite exposures, and let a rule try several known paths
Two curated detection rules for Oracle E-Business Suite, both read only, both firing only on proof against a control. The first is the self-registration exposure behind CVE-2022-21500: the iStore registration pages answering an unauthenticated visitor, which lets an outsider register an account over HTTP. It checks the four known registration paths and confirms the real registration page, not a soft 404, by the exact text the page carries. Oracle says 12.2 is affected and 12.1 is not, and the fix is in the remediation. The second is the jtfwrepo.xml repository file served to anyone, with the xml content type and a body carrying a password field or a user list: an internal configuration file that can disclose credentials and should never be reachable from outside. To support the first, a rule can now carry candidate_paths, a short list of known paths to try, firing on the first that confirms. It reuses the existing route machinery, so the engine, the scope gate and the safety contract are unchanged; a rule with no such list behaves exactly as before.
1 parent 9627011 commit 65019ba

3 files changed

Lines changed: 79 additions & 3 deletions

File tree

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"id": "access-control-oracle-ebs-self-registration-cve-2022-21500",
3+
"class": "access-control",
4+
"safety": "read",
5+
"severity_floor": "high",
6+
"title": "Oracle E-Business Suite self-registration is open (CVE-2022-21500)",
7+
"summary": "The iStore self-registration pages answer an unauthenticated visitor, the exposure behind CVE-2022-21500 in the Manage Proxies component. An outsider can register an account over HTTP and reach functions that should be behind a login. Oracle says 12.2 is affected and 12.1 is not.",
8+
"needs": [],
9+
"candidate_paths": [
10+
"/OA_HTML/ibeCAcpSSOReg.jsp",
11+
"/OA_HTML/ibeCRgpPrimaryCreate.jsp",
12+
"/OA_HTML/ibeCRgpIndividualUser.jsp",
13+
"/OA_HTML/ibeCRgpPartnerPriCreate.jsp"
14+
],
15+
"probe": [
16+
{
17+
"request": {
18+
"method": "GET",
19+
"path": "{route}"
20+
}
21+
}
22+
],
23+
"confirm": {
24+
"control": "A path that cannot exist, so the site's not found answer is known and the registration page is told apart from a soft 404.",
25+
"differential": "status == 200 and body_contains(\"Register as individual\") and body_contains(\"Registration\") and body_contains(\"ibeCZzpRuntimeIncl.jsp\") and body_differs(control)",
26+
"retest": 2
27+
},
28+
"reproduce": "curl -sk 'https://host/OA_HTML/ibeCAcpSSOReg.jsp' and look for the registration form: it returns HTTP 200 with 'Register as individual' and the page include 'ibeCZzpRuntimeIncl.jsp', so an unauthenticated visitor can self-register. Try the other paths too: /OA_HTML/ibeCRgpPrimaryCreate.jsp, /OA_HTML/ibeCRgpIndividualUser.jsp, /OA_HTML/ibeCRgpPartnerPriCreate.jsp.",
29+
"remediate": "Apply Oracle's CVE-2022-21500 fix. If iStore self-registration is not used, disable ibeCAcpSSOReg.jsp and remove the self-registration link from AppsLocalLogin.jsp, and deny the registration paths with the Allowed Resources framework. Oracle E-Business Suite 12.1 is not affected.",
30+
"references": [
31+
"https://www.oracle.com/security-alerts/alert-cve-2022-21500.html"
32+
],
33+
"mappings": {
34+
"cwe": "CWE-284",
35+
"owasp": "A01:2021"
36+
},
37+
"rulesets": [
38+
"oracle-ebs"
39+
]
40+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"id": "misconfiguration-oracle-ebs-credentials-jtfwrepo",
3+
"class": "misconfiguration",
4+
"safety": "read",
5+
"severity_floor": "high",
6+
"title": "Oracle E-Business Suite exposes jtfwrepo.xml",
7+
"summary": "The repository file /OA_HTML/jtfwrepo.xml is served to anyone, with the text/xml content type and a body carrying a password field or a user list. It is an internal configuration file that can disclose credentials, and it should never be reachable from outside.",
8+
"needs": [],
9+
"probe": [
10+
{
11+
"request": {
12+
"method": "GET",
13+
"path": "/OA_HTML/jtfwrepo.xml"
14+
}
15+
}
16+
],
17+
"confirm": {
18+
"control": "A path that cannot exist, so the site's not found answer is known and the exposed file is told apart from a soft 404.",
19+
"differential": "status == 200 and \"text/xml\" in header(\"content-type\") and (body_contains(\"password=\") or body_contains(\"<PUSR_LIST>\")) and body_differs(control)",
20+
"retest": 2
21+
},
22+
"reproduce": "curl -sk 'https://host/OA_HTML/jtfwrepo.xml' and check it returns HTTP 200 with a text/xml body that contains 'password=' or '<PUSR_LIST>'. That file is internal configuration and should not be reachable without authentication.",
23+
"remediate": "Block /OA_HTML/jtfwrepo.xml at the web tier and with the Oracle E-Business Suite Allowed Resources (URL Firewall) framework, so the repository file is not served to unauthenticated clients. Rotate any credential the file disclosed.",
24+
"references": [],
25+
"mappings": {
26+
"cwe": "CWE-200",
27+
"owasp": "A05:2021"
28+
},
29+
"rulesets": [
30+
"oracle-ebs"
31+
]
32+
}

‎app/core/dast_checks/engine.py‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,13 @@ def run_rule(spec: dict, ctx: dict) -> dict:
355355
allow_private=bool(ctx.get("allow_private")),
356356
headers=ctx.get("headers"))
357357

358-
# A rule with {route} in its probe is aimed at the discovered routes; a
359-
# fixed-path rule is run once, not repeated against every route.
360-
if _uses_route(spec):
358+
# A rule with {route} in its probe is aimed somewhere: at a fixed list the
359+
# rule itself carries (candidate_paths, for a check with several known paths
360+
# to try, firing on the first that confirms), or at the discovered routes.
361+
# A rule with no {route} is run once against its fixed path.
362+
if _uses_route(spec) and spec.get("candidate_paths"):
363+
routes = [str(p) for p in spec["candidate_paths"]][:MAX_ROUTES]
364+
elif _uses_route(spec):
361365
routes = list(ctx.get("code_routes") or [])[:MAX_ROUTES]
362366
else:
363367
routes = [""]

0 commit comments

Comments
 (0)