Jorian @jorianwoltjer.com · 09/08/2026What started with a simple question on Discord, ended in *reviving an old XS-Leak technique* for probing status codes in background requests! Unravel the mystery with me in the latest @ctbbpodcast.bsky.social blog post: lab.ctbb.show/research/sol... 022
Jorian @jorianwoltjer.com · 03/07/2026This new HTML feature just shipped in Chrome 150, it's gonna be veeeeery interesting 👀 github.com/WICG/declara... 121
Jorian @jorianwoltjer.com · 02/06/2026Now that everybody's had a chance to solve it, here's a timelapse of my playtesting run of the JavaScript Crossword! SPOILER WARNING: Please try it yourself first in the post below, it's very satisfying to solve, I don't want you to miss out on that 😄 (1 second = 2 minutes) 052
Jorian @jorianwoltjer.com · 23/04/2026(2/2) After some wild ideas of leaking it, I found a different solution using the obscure "Variables" (curl.se/docs/manpage...) feature of curl. We can define and expand {{USERPROFILE}}, then finish with an 8.3 Shortname "StartM~1" to avoid issues with a space! The final payload: 060
Jorian @jorianwoltjer.com · 23/04/2026Cool exploit with @0x999.net: He found that \x7F breaks Chrome's "Copy as cURL (cmd)" command parsing in Windows Console Host. In combination with a ", it allowed you to add any arguments to curl. With -o writing files is easy, but we need the username for the startup path... (1/2) 161
Jorian @jorianwoltjer.com · 16/11/2025Really interesting technique from a local CTF. In gunicorn with --proxy-protocol --proxy-allow-from='*', the "Proxy Protocol" (github.com/haproxy/hapr...) allows you to spoof the source IP with a PROXY prefix like this! I feel like it might be useful as impact in Request Tunneling👀 130
Jorian @jorianwoltjer.com · 17/10/2025(5/5) For Client-Side Race Conditions based on network requests, you can slow down time by holding up the Connection Pool. Then slowly release them one by one, performing any actions you need in between with 100% consistency. 011
Jorian @jorianwoltjer.com · 17/10/2025(4/5) Form input history is restored on history.back() even if the HTML changed in the meantime. For inputs without a form, that means you can hijack it into your own form with a form= attribute as an exception. From there you could submit your form to leak it. 100
Jorian @jorianwoltjer.com · 17/10/2025(3/5) Script gadgets inside an <iframe srcdoc> that require URL parameters can be set using a <meta http-equiv="refresh"> redirect to about:srcdoc. It reloads the document with the new URL while keeping its content. 100
Jorian @jorianwoltjer.com · 17/10/2025(2/5) With a strict CSP, .click() gadgets can be very useful for things like: * Opening the attacker's website with <a target="_blank"> * Submitting a form for CSRF * Performing actions on the site to trigger other behavior 100
Jorian @jorianwoltjer.com · 18/09/2025AMAZING technique by @salvatoreabello, I've been inspired by the connection pool exploits he comes up with. Check out this crazy impact labeled as "working as intended": blog.babelo.xyz/posts/cross-... 063
Jorian @jorianwoltjer.com · 16/09/2025On our attacker's page, we load this in an iframe and can then access [0] to get a reference to our injected object. To read its name, we can set its location to *our* about:blank and then read the .name window property (set by the attribute)! 210
Jorian @jorianwoltjer.com · 16/09/2025While playing a challenge by Salvatore Abello, I found a pretty interesting way to exploit Dangling Markup with a strict CSP. All you need is an <iframe>, <object> or <embed> set to about:blank, with a dangling name= attribute. This vulnerable page should be iframable. 210
Jorian @jorianwoltjer.com · 13/09/2025Final exploit code: gist.github.com/JorianWoltje... Thanks Omid sharing this challenge! 010
Jorian @jorianwoltjer.com · 13/09/2025We first duplicate our page, then navigate the first tab to the target. From our 2nd tab, the iframe can now access `top.opener` to send a message to the target. Quickly after, the parent removes the iframe and the `event.source` becomes `null`. 100
Jorian @jorianwoltjer.com · 13/09/2025@omidxrz.bsky.social shared this nice postMessage() challenge some time ago. I'm a bit late, but worth trying if you haven't already :D Otherwise, my solution is below, it's a really fun technique that makes me re-evaluate all the .source checks I've seen before... 130
Jorian @jorianwoltjer.com · 30/06/2025Just found an interesting way to bypass some nonce-based CSPs and made a small XSS challenge with an exploitable scenario. See if you can find it before I tell! Source JS: gist.github.com/JorianWoltje... URL: greeting-chall.jorianwoltjer.com Found a solution? Please DM to avoid spoilers, thanks! 160
Jorian @jorianwoltjer.com · 13/06/2025Small tip for the JavaScript reverse engineers out there, Chrome has a `debug()` function which triggers a breakpoint whenever its first argument is called. It even works on built-in methods, no more wrapping stuff in proxies :D debug(DOMParser.prototype.parseFromString) 0111
Jorian @jorianwoltjer.com · 02/06/2025It uses the "Tagged Templates" syntax like t`...` and automatically escapes any interpreted variables, as well as supporting nesting/arrays. Here's an example showing its usage: 040
Jorian @jorianwoltjer.com · 21/05/2025This includes a fun trick with User Activation. It can be used to detect when actions like shortcuts and clicks happen inside cross-origin iframes: 041
Jorian @jorianwoltjer.com · 09/05/2025While collecting some HTML-Injection techniques, I thought of an interesting way to abuse existing <form>s when XSS isn't an option. You can inject <input>s with form= pointing to the form's id= to add params, and make a <button> with form= and formaction= to change its action. 140
Jorian @jorianwoltjer.com · 06/03/2025@renwax23.bsky.social made an interesting challenge (x.com/RenwaX23/sta...). Instead of right-click and open in new tab, I found you can also use drag-and-drop into a popup window to achieve the same effect! With CSS you can make it convincing like clickjacking: gist.github.com/JorianWoltje... 110
Jorian @jorianwoltjer.com · 03/03/2025Here's a way to exploit `eval(name)` on Firefox without user interaction: 110
Jorian @jorianwoltjer.com · 11/02/2025In the final payload, we just write "\n{}*{color:red}" as a comment on any blog post, then refer to it in `request.path` with `>;rel=stylesheet;` injected. This will cause the injected comment to be executed as CSS on the response page! 000
Jorian @jorianwoltjer.com · 11/02/2025The website had a comment feature on blog posts, which we can inject CSS code into. The parser is very lax and any broken statements can be closed with just a \n and {}. Then we can write arbitrary CSS to leak content on the response page using regular CSS Injection techniques. 100
Jorian @jorianwoltjer.com · 11/02/2025I recently found a pretty interesting attack on a friend's website where the `Link:` response header was automatically set to the requested path: 140
Jorian @jorianwoltjer.com · 11/12/2024I made an XSS challenge for Intigriti this month, good luck and have fun! x.com/intigriti/st... 030
Jorian @jorianwoltjer.com · 05/12/2024Apparently, navigating to a javascript: URL returning a string will write it as HTML to the DOM. This allows for an interesting XSS payload: x.com/icesfont2/st... 0122
Jorian @jorianwoltjer.com · 27/11/2024My challenge has been out for about a week with only one half-intended solution, so here's my solution! 111
Jorian @jorianwoltjer.com · 20/11/2024I've been closely following the awesome Mutation XSS research that's been coming out, and have found some tricks of my own. Below is a challenge from me to you. This code removes comments, dangerous text nodes and all attributes. Bypass the filter to achieve XSS. Good luck! 120