I’ve been watching your videos for a few weeks now and I am so happy I found your channel. Your videos are outstanding, and it is much easier for me to understand with the English accent :). Keep doing your thing CryptoCat, I look forward to your next video!
Well, the `debug` object normally has the `Debug` class as prototype, and that read-only `sanitize` property is implemented there. What you are doing here essentially equivalent to `Object.setPrototype(debug, {})` so afterwards `debug` has nothing to do with the `Debug` class anymore and hence no longer has that (inherited) read-only property that was in our way.
Great video! I had some fun experimenting with the browser. It turns out that "debug.sanitizer" is actually a call to the getter function stored in the prototype. As a result, when you overwrite it, you lose the ability to access the #sanitizer property of the object.
Aghh this comment go stuck in the the "held for review" section for a few days 😅 I'm still a little confused because normally when we do prototype pollution, e.g. {'__proto__':{'crypto':'cat'}} it would inject a property called "crypto" (with a value of "cat") into every object, but it wouldn't overwrite other properties that we didn't specify in the prototype pollution payload?
@@_CryptoCat Sorry, I misspoke. In this case, we are replacing the prototype of the Debug class with the object {crypto: "cat"}. By doing this, we lose the sanitizer get method that was in the legitimate prototype. Therefore, the call to debug.sanitizer returns undefined, which evaluates as false. The fact that properties are usually "added" rather than replaced, I believe, is because the object {crypto: "cat"} itself has a __proto__ that points to Object.prototype. When we replace this object to the __proto__ of another object, we are extending the prototype chain by adding an extra link, creating a chain like this: Victim_object -> {crypto:"cat"} -> Object.prototype. So we essentially retain every basic function of Object. In this challenge, however, the original prototype chain is Debug_object -> Debug.prototype -> Object.prototype. So when we replace Debug.prototype with {crypto: "cat"}, we permanently lose the get method.
@@_CryptoCatNo, that would happen only if you had some unsafe "set nested property by path" type of function that would take something like `a.b.c` and then attempt to set `obj.a.b.c` to something you control. (But `Object.assign` doesn't do that.) Then (and if the prototype of the target object was just `Object`) you could write properties into the `Object` prototype itself and this would affect all objects, but even then only if those other objects don't have their own keys with the same name. But in this case here you simply do `debug.__proto__ = {}`.
I wasn't aware of the payload generator. I'll definitely give it a try next time I came across a similar vulnerability. Have you attempted to uncover the vulnerability using DOM Invader instead? However, cool challenge 😎
Thanks! Good question 🤔 I didn't keep track really (was working on other web challs as well) but I did spend a few hours on this one (with some collaboration with team members) but I was doing the writeup as I went which slows me down quite a bit.
Just found you and pumped youre well spoken and easy to understand. Like everyone is saying super underrated channel bro keep it up!
Thanks mate, super appreciated 🥰
I’ve been watching your videos for a few weeks now and I am so happy I found your channel. Your videos are outstanding, and it is much easier for me to understand with the English accent :).
Keep doing your thing CryptoCat, I look forward to your next video!
Thank you so much! 💜
No, thank you!
@@RTCW-ET-MOVIES 🥰
Great stuff ❤
Thank you! 💜
You are the best bro❤
Awww thank you mate! 💜
You are number one in my cyber security learning since my first watched video on your channel!
Awwww love to hear that, thanks mate! 🥰
Most underrated security channel by far.
🙏🙏🙏
Agreed. The content is top notch.
awesome one dude.
Thank you! 💜
Great writeup
🙏🥰
Nicee keep explain about ctf ctf ❤
Thanks! Sure will 🥰
Well, the `debug` object normally has the `Debug` class as prototype, and that read-only `sanitize` property is implemented there. What you are doing here essentially equivalent to `Object.setPrototype(debug, {})` so afterwards `debug` has nothing to do with the `Debug` class anymore and hence no longer has that (inherited) read-only property that was in our way.
Great video! I had some fun experimenting with the browser. It turns out that "debug.sanitizer" is actually a call to the getter function stored in the prototype. As a result, when you overwrite it, you lose the ability to access the #sanitizer property of the object.
Aghh this comment go stuck in the the "held for review" section for a few days 😅 I'm still a little confused because normally when we do prototype pollution, e.g. {'__proto__':{'crypto':'cat'}} it would inject a property called "crypto" (with a value of "cat") into every object, but it wouldn't overwrite other properties that we didn't specify in the prototype pollution payload?
@@_CryptoCat Sorry, I misspoke. In this case, we are replacing the prototype of the Debug class with the object {crypto: "cat"}. By doing this, we lose the sanitizer get method that was in the legitimate prototype. Therefore, the call to debug.sanitizer returns undefined, which evaluates as false. The fact that properties are usually "added" rather than replaced, I believe, is because the object {crypto: "cat"} itself has a __proto__ that points to Object.prototype. When we replace this object to the __proto__ of another object, we are extending the prototype chain by adding an extra link, creating a chain like this: Victim_object -> {crypto:"cat"} -> Object.prototype. So we essentially retain every basic function of Object. In this challenge, however, the original prototype chain is Debug_object -> Debug.prototype -> Object.prototype. So when we replace Debug.prototype with {crypto: "cat"}, we permanently lose the get method.
@@_CryptoCatNo, that would happen only if you had some unsafe "set nested property by path" type of function that would take something like `a.b.c` and then attempt to set `obj.a.b.c` to something you control. (But `Object.assign` doesn't do that.) Then (and if the prototype of the target object was just `Object`) you could write properties into the `Object` prototype itself and this would affect all objects, but even then only if those other objects don't have their own keys with the same name. But in this case here you simply do `debug.__proto__ = {}`.
I wasn't aware of the payload generator. I'll definitely give it a try next time I came across a similar vulnerability. Have you attempted to uncover the vulnerability using DOM Invader instead? However, cool challenge 😎
I didn't try DOM Invader, that would of been a cool addition to the video.. next time! 🙂
This is an awesome explanation. Can I ask how long it took to figure it all out?
Thanks! Good question 🤔 I didn't keep track really (was working on other web challs as well) but I did spend a few hours on this one (with some collaboration with team members) but I was doing the writeup as I went which slows me down quite a bit.
u have telegram? i wanna talk to u