diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 64254ae0eb1..3e4f051cf5c 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -497,6 +497,7 @@ - [403 & 401 Bypasses](network-services-pentesting/pentesting-web/403-and-401-bypasses.md) - [AEM - Adobe Experience Cloud](network-services-pentesting/pentesting-web/aem-adobe-experience-cloud.md) - [Angular](network-services-pentesting/pentesting-web/angular.md) + - [Apache Tapestry](network-services-pentesting/pentesting-web/apache-tapestry.md) - [Apache](network-services-pentesting/pentesting-web/apache.md) - [Artifactory Hacking guide](network-services-pentesting/pentesting-web/artifactory-hacking-guide.md) - [Bolt CMS](network-services-pentesting/pentesting-web/bolt-cms.md) diff --git a/src/network-services-pentesting/pentesting-web/README.md b/src/network-services-pentesting/pentesting-web/README.md index c9e82824737..0dc9d79aa54 100644 --- a/src/network-services-pentesting/pentesting-web/README.md +++ b/src/network-services-pentesting/pentesting-web/README.md @@ -72,6 +72,7 @@ Some **tricks** for **finding vulnerabilities** in different well known **techno - [**AEM - Adobe Experience Cloud**](aem-adobe-experience-cloud.md) - [**Apache**](apache.md) +- [**Apache Tapestry**](apache-tapestry.md) - [**Artifactory**](artifactory-hacking-guide.md) - [**Buckets**](buckets/index.html) - [**CGI**](cgi.md) diff --git a/src/network-services-pentesting/pentesting-web/apache-tapestry.md b/src/network-services-pentesting/pentesting-web/apache-tapestry.md new file mode 100644 index 00000000000..b659a439386 --- /dev/null +++ b/src/network-services-pentesting/pentesting-web/apache-tapestry.md @@ -0,0 +1,46 @@ +# Apache Tapestry + +{{#include ../../banners/hacktricks-training.md}} + +Apache Tapestry applications can expose component actions through the `direct` engine service. In Tapestry 3, a normal direct request identifies the page to render and a component path; a **complex direct** request additionally identifies a different page that owns the component.[[1]](#references) + +## Complex-direct component authorization mismatch + +The framework activates the render page, resolves the component from the separately supplied component page, and then triggers that component. Therefore, applications must authorize both the requested action and the page that owns it; checking only the render page creates an object-level authorization bypass.[[1]](#references)[[3]](#references) + +A useful generalized request shape is:[[1]](#references)[[3]](#references) + +```http +POST /app?service=direct//// HTTP/1.1 +Host: target +``` + +To test this safely, capture a legitimate direct-component request and preserve its method, body, hidden form state, and component path. Then keep the restricted component page/action constant while substituting render pages that are reachable without a session, such as error, exception, login, landing, or home pages. Compare both the response and the server-side effect: an error response does not prove that the component was not triggered.[[1]](#references)[[3]](#references) + +PaperCut exposed this mismatch through requests such as the following. In that implementation, the first context segment was not security-sensitive and accepted values other than `1`; `Error` could be replaced with other public pages while the privileged component page remained unchanged.[[3]](#references) + +```http +POST /app?service=direct/1/Error/ConfigEditor/quickFindForm +POST /app?service=direct/1/Error/ConfigEditor/$Form +POST /app?service=direct/1/Error/UserList/$QuickFind.$Form +``` + +This belongs in an authorization test rather than only a [login-bypass](../../pentesting-web/login-bypass/README.md) test: the request may render a public page successfully while executing a component owned by an administrative page.[[3]](#references) + +## Turning exposed configuration components into execution + +After reaching a privileged configuration component, look for a complete server-side database execution primitive: attacker-controlled driver class, JDBC URL, query text, enable/disable state, and an ordinary workflow that opens the connection or evaluates the query. PaperCut's external identity lookup exposed exactly these controls; invoking a user/card search consumed the modified configuration.[[2]](#references)[[3]](#references) + +The reported chain used a bundled Derby driver and a `CALL` into `foreignViews` to make Derby open an H2 JDBC URL. H2 then processed an inline `INIT` statement that created a JavaScript-backed trigger; because Nashorn was present, the script could reach Java APIs and start an OS process. This illustrates a broader audit rule: enumerate **every JDBC driver already on the application classpath** and test whether one engine can bridge into another engine's initialization, alias, procedure, trigger, scripting, or class-loading features. See [H2 - Java SQL database](h2-java-sql-database.md) for H2 `INIT`, aliases, and scripted-trigger primitives.[[3]](#references) + +## Patch-bypass testing + +Do not validate a fix only with the public page used in the original proof of concept. Re-run the same restricted component request with every unauthenticated render page and with equivalent route encodings. A denylist for names such as `Error` and `Exception` remains bypassable if `Home` or another public page still reaches the component; the durable fix is to authorize the component action and its owning page independently of the page selected for rendering.[[2]](#references)[[3]](#references) + +## References + +- [1] [Apache Tapestry 3 `DirectService` source](https://github.com/apache/tapestry3/blob/trunk/tapestry-framework/src/org/apache/tapestry/engine/DirectService.java) +- [2] [PaperCut urgent security advisory (27 August 2026)](https://www.papercut.com/kb/Main/security-bulletin-27-aug-2026-urgent-security-advisory/) +- [3] [Rapid7: PaperCut NG/MF Critical Zero-Day Exploited in the Wild](https://rapid7.com/blog/post/etr-papercut-ng-mf-critical-zero-day-exploited-in-the-wild) + +{{#include ../../banners/hacktricks-training.md}}