Skip to content

Commit 21edc05

Browse files
committed
Add Adobe AEM and Magento curated checks
Read only checks for two products in heavy use here, each confirmed against a control, matched on strings the real products return. Adobe Experience Manager: the default GET servlet serving the content repository as JSON to anyone, the QueryBuilder servlet answering an unauthenticated query of the whole repository, a developer console (CRXDE Lite, the package manager or the content explorer) reachable without a login, and the OSGi management console open without authentication. Each is a way an outsider reads or controls an AEM site, and the remediation points at the dispatcher checklist. The real world precedent table gained the AEM exposure class. Magento: the version endpoint disclosing the platform edition and version, which is the first thing an attacker uses to pick a matching exploit. All are plain GET requests that fetch, never change, and send no guessed credentials.
1 parent c428c90 commit 21edc05

6 files changed

Lines changed: 144 additions & 0 deletions
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"id": "misconfiguration-aem-content-disclosure",
3+
"class": "misconfiguration",
4+
"safety": "read",
5+
"severity_floor": "high",
6+
"title": "Adobe AEM leaks repository content (DefaultGetServlet)",
7+
"summary": "Adobe Experience Manager is serving its content repository as JSON to anyone, through the default GET servlet. An unauthenticated visitor can read internal pages, user and group nodes and configuration by adding a .json selector to a path, which is how large amounts of internal data get pulled from an AEM site.",
8+
"needs": [],
9+
"candidate_paths": [
10+
"/.json",
11+
"/.1.json",
12+
"/etc.json",
13+
"/var.json",
14+
"/apps.json",
15+
"/home.json",
16+
"/.children.json"
17+
],
18+
"probe": [
19+
{ "request": { "method": "GET", "path": "{route}" } }
20+
],
21+
"confirm": {
22+
"control": "A path that cannot exist, so the site's not found answer is known and the JSON content dump is told apart from a soft 404.",
23+
"differential": "status == 200 and body_contains(\"jcr:primaryType\") and body_differs(control)",
24+
"retest": 2
25+
},
26+
"reproduce": "curl -sk 'https://host/.json' (and /etc.json, /.1.json, /home.json) and check the response is JSON containing jcr:primaryType, which is a node of the AEM content repository. If it returns, the default GET servlet is exposing content to anyone.",
27+
"remediate": "Block these paths and selectors at the dispatcher so they return 404: the .json, .1.json and .children.json selectors on repository paths, and the obfuscated variants. Follow Adobe's AEM dispatcher security checklist.",
28+
"references": [],
29+
"mappings": { "cwe": "CWE-200", "owasp": "A05:2021" },
30+
"rulesets": ["aem"]
31+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"id": "misconfiguration-aem-dev-consoles-exposed",
3+
"class": "misconfiguration",
4+
"safety": "read",
5+
"severity_floor": "high",
6+
"title": "Adobe AEM developer consoles are exposed",
7+
"summary": "An AEM developer console is reachable without signing in: CRXDE Lite, the CRX Package Manager or the Content Explorer. These give a browser into the whole content repository and its packages, which an attacker uses to read and map everything the site holds.",
8+
"needs": [],
9+
"candidate_paths": [
10+
"/crx/de/index.jsp",
11+
"/crx/packmgr/index.jsp",
12+
"/crx/explorer/browser/index.jsp"
13+
],
14+
"probe": [
15+
{ "request": { "method": "GET", "path": "{route}" } }
16+
],
17+
"confirm": {
18+
"control": "A path that cannot exist, so the site's not found answer is known and the console page is told apart from a soft 404.",
19+
"differential": "status == 200 and (body_contains(\"CRXDE Lite\") or body_contains(\"CRX Package Manager\") or body_contains(\"Content Explorer\")) and body_differs(control)",
20+
"retest": 2
21+
},
22+
"reproduce": "curl -sk 'https://host/crx/de/index.jsp' (and /crx/packmgr/index.jsp) and check the page loads a console: CRXDE Lite, CRX Package Manager or Content Explorer in the body. If it does, the developer tools are reachable without authentication.",
23+
"remediate": "Block /crx, /system/console and the other developer paths at the dispatcher so they return 404 from the public site, and keep them to the author tier behind authentication. Follow Adobe's AEM dispatcher security checklist.",
24+
"references": [],
25+
"mappings": { "cwe": "CWE-284", "owasp": "A05:2021" },
26+
"rulesets": ["aem"]
27+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"id": "misconfiguration-aem-felix-console-exposed",
3+
"class": "misconfiguration",
4+
"safety": "read",
5+
"severity_floor": "high",
6+
"title": "Adobe AEM Felix console is exposed without authentication",
7+
"summary": "The AEM OSGi (Felix) management console answers without a login. It lists and controls the bundles the server runs, which is full administrative reach over the application and a path to code execution.",
8+
"needs": [],
9+
"probe": [
10+
{ "request": { "method": "GET", "path": "/system/console/bundles" } }
11+
],
12+
"confirm": {
13+
"control": "A path that cannot exist, so the site's not found answer is known and the console page is told apart from a soft 404.",
14+
"differential": "status == 200 and body_contains(\"Web Console - Bundles\") and body_differs(control)",
15+
"retest": 2
16+
},
17+
"reproduce": "curl -sk 'https://host/system/console/bundles' with no credentials and check the body contains 'Web Console - Bundles'. If it does, the OSGi management console is open to anyone.",
18+
"remediate": "Block /system/console at the dispatcher so it returns 404 from the public site, and never expose the OSGi console on an internet facing tier. Change the default admin password. Follow Adobe's AEM dispatcher security checklist.",
19+
"references": [],
20+
"mappings": { "cwe": "CWE-284", "owasp": "A05:2021" },
21+
"rulesets": ["aem"]
22+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"id": "misconfiguration-aem-querybuilder-exposed",
3+
"class": "misconfiguration",
4+
"safety": "read",
5+
"severity_floor": "high",
6+
"title": "Adobe AEM QueryBuilder servlet is exposed",
7+
"summary": "The AEM QueryBuilder JSON servlet answers an unauthenticated visitor, so anyone who can reach the site can query the whole content repository, including user and group nodes. It is a common way to pull internal content out of an AEM site and it bypasses many dispatcher filters.",
8+
"needs": [],
9+
"candidate_paths": [
10+
"/bin/querybuilder.json",
11+
"///bin///querybuilder.json",
12+
"/bin/querybuilder.json.1.json"
13+
],
14+
"probe": [
15+
{ "request": { "method": "GET", "path": "{route}" } }
16+
],
17+
"confirm": {
18+
"control": "A path that cannot exist, so the site's not found answer is known and the query result is told apart from a soft 404.",
19+
"differential": "status == 200 and body_contains(\"\\\"hits\\\"\") and body_differs(control)",
20+
"retest": 2
21+
},
22+
"reproduce": "curl -sk 'https://host/bin/querybuilder.json' and check the response is JSON with a hits array. If it answers, the QueryBuilder servlet is open and the whole repository can be queried, for example /bin/querybuilder.json?path=/home/users&type=rep:User.",
23+
"remediate": "Deny /bin/querybuilder* at the dispatcher so it returns 404, including the obfuscated and double-slash variants. Follow Adobe's AEM dispatcher security checklist.",
24+
"references": [],
25+
"mappings": { "cwe": "CWE-200", "owasp": "A05:2021" },
26+
"rulesets": ["aem"]
27+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"id": "misconfiguration-magento-version-disclosed",
3+
"class": "misconfiguration",
4+
"safety": "read",
5+
"severity_floor": "low",
6+
"title": "Magento discloses its version",
7+
"summary": "The Magento version endpoint returns the platform edition and version to anyone. On its own this is low, but it tells an attacker which version the store runs, which is the first thing they use to pick a matching exploit, so it matters most on a store that is behind on patches.",
8+
"needs": [],
9+
"probe": [
10+
{ "request": { "method": "GET", "path": "/magento_version" } }
11+
],
12+
"confirm": {
13+
"control": "A path that cannot exist, so the site's not found answer is known and the version line is told apart from a soft 404.",
14+
"differential": "status == 200 and body_contains(\"Magento/\") and body_differs(control)",
15+
"retest": 2
16+
},
17+
"reproduce": "curl -sk 'https://host/magento_version' and check the body is a line like 'Magento/2.4 (Community)'. If it returns, the store is disclosing its version.",
18+
"remediate": "Disable the version endpoint: php bin/magento module:disable Magento_Version, or block /magento_version at the web tier. Keep the platform patched.",
19+
"references": [],
20+
"mappings": { "cwe": "CWE-200", "owasp": "A05:2021" },
21+
"rulesets": ["magento"]
22+
}

‎app/core/dast_precedent.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,21 @@
158158
"web caches is a documented technique, described by security "
159159
"researchers and in OWASP guidance.",
160160
},
161+
{
162+
"key": "aem-exposure",
163+
"match": re.compile(r"\baem\b|adobe experience manager|querybuilder|"
164+
r"jcr:primarytype|crxde|defaultget|felix console|"
165+
r"/crx/|/system/console", re.I),
166+
"ref": "CWE-200; OWASP A05:2021",
167+
"abuse": "An attacker queries the content repository or opens a developer console "
168+
"with no login, reading internal pages, user and group lists and "
169+
"configuration, and from the OSGi console can reach code execution.",
170+
"precedent": "Misconfigured Adobe Experience Manager dispatchers have repeatedly "
171+
"exposed internal repository content to unauthenticated visitors; "
172+
"researchers have pulled megabytes of internal data from open "
173+
"QueryBuilder and default GET servlet endpoints, and Adobe has issued "
174+
"critical AEM patches.",
175+
},
161176
{
162177
"key": "ai-tool-exposure",
163178
"match": re.compile(r"open (self-)?registration|registrationenabled|librechat|"

0 commit comments

Comments
 (0)