Episode 69: In this episode of Critical Thinking - Bug Bounty Podcast we’re joined by Johan Carlsson to hear about some updates on his bug hunting journey. We deep-dive a CSP bypass he found in GitHub, a critical he found in GitLab's pipeline, and also talk through his approach to using script gadgets and adapting to highly CSP'd environments. Then we talk about his transition to full-time bug hunting, including the goals he’s set, the successes and challenges, and his current focus on specific bug types like ReDoS and OAuth, and the serendipitous nature of bug hunting.
Follow us on twitter at: @ctbbpodcast
We're new to this podcasting thing, so feel free to send us any feedback here: info@criticalthinkingpodcast.io
Shoutout to YTCracker for the awesome intro music!
------ Links ------
Follow your hosts Rhynorater & Teknogeek on twitter:
https://twitter.com/0xteknogeek
https://twitter.com/rhynorater
------ Ways to Support CTBBPodcast ------
Hop on the CTBB Discord at https://ctbb.show/discord!
We also do Discord subs at $25, $10, and $5 - premium subscribers get access to private masterclasses, exploits, tools, scripts, un-redacted bug reports, etc.
Sign up for Caido using the referral code CTBBPODCAST for a 10% discount.
Nuclei 3.2 Release: https://nux.gg/podcast
Today’s Guest:
Resources
Github CSP Bypass
https://gist.github.com/joaxcar/6e5a0a34127704f4ea9449f6ce3369fc
CSP Validator
Cross Window Forgery
https://www.paulosyibelo.com/2024/02/cross-window-forgery-web-attack-vector.html
Gitlab Crit
https://gist.github.com/joaxcar/9419b2df8778f26e9b02a741a8ec12f8
Timestamps
(00:00:00) Introduction
(00:09:34) Github CSP Bypass
(00:38:48) Script Gadgets and growth through Gitlab
(00:53:53) Gitlab pipeline bug
(01:12:32) Full-time Bug Bounty
Justin Gardner (@rhynorater) (00:01.052)
Yo, Johann, welcome to the pod, man.
Johan Carlsson (00:03.598)
Thank you. Happy to be here.
Justin Gardner (@rhynorater) (00:05.116)
Very excited to have you on. So the reason we invited you on this time right now, well there's a couple reasons really. One, you have been pretty public with your journey into full-time bug bounty, which is cool, and I wanted to kind of interview you and sort of debrief that and see how that's been going. And also man, you just have the craziest bugs I've ever seen on the client side. It's really inspiring to see. And so I'm hoping we can debrief some of those things.
But let's go ahead and start at the very beginning, a very good place to start, and just give me a little intro into your career path that landed you at Full-Time Buck Bounty.
Johan Carlsson (00:47.466)
Yeah, sure. So hi, thanks for having me. So my name is Johan Karlsson. So I live in Sweden and my career path sort of began like a long time ago. Like I'm a bit older than the average bounty hunter, I guess, turning 37 now. And so I was one of those kids like doing computers like all the time in the late 90s, early 2000.
Justin Gardner (@rhynorater) (01:05.609)
Mm.
Johan Carlsson (01:16.486)
playing games and doing all that stuff and like I thought that I would end up like a game developer I guess and I went to do high school doing programming and networking and stuff like that, but then after High school I decided to quit computers Like I decided to not touch them at all and I stuck to that for about eight years or something doing art studies instead and painting and drawing and
Justin Gardner (@rhynorater) (01:43.747)
Was that like a technophobia decision? What was that? Or you just...
Johan Carlsson (01:47.45)
I was sort of trying to be rebellious, I guess, to my friends and... Like everyone just... I mean, everyone started doing like... We started like a collective, I guess you call that. Like we moved in a bunch of friends in an apartment after high school and just people did like whatever. But most of them just continued on with the technical path. And I decided to go down this like artistic route instead.
Justin Gardner (@rhynorater) (01:52.304)
Okay, gotcha, gotcha. Solid.
Justin Gardner (@rhynorater) (02:02.038)
Mm-hmm.
Justin Gardner (@rhynorater) (02:10.953)
Mm-hmm.
Johan Carlsson (02:16.806)
But then, so like eight years later when I got my first kid, or like maybe ten years later. But yeah, I kind of figured out that I had to earn some money because I didn't really do it with the arts. Unfortunate. Yeah, yeah, yeah. Definitely. Yeah, yeah, exactly. And they had already spent, so they were way ahead of me then.
Justin Gardner (@rhynorater) (02:33.298)
That's the tricky part with art, isn't it?
Joel Margolis (teknogeek) (02:36.372)
About all your friends who went to the computer row were kind of laughing then.
Justin Gardner (@rhynorater) (02:39.257)
Yeah, right.
Justin Gardner (@rhynorater) (02:44.287)
Oh man.
Johan Carlsson (02:44.598)
already in like these really good positions in tech companies and stuff. But yes, I actually pretty like I got a job at Stockholms University at like the language department taking care of their like IT stuff and there I got to like play with like doing like bash scripting and stuff just to take care of this like two rooms of computers and then I kind of got the feeling again
that this is pretty fun and I'm also like pretty good at it. And then maybe like I should do it because it's like way easier to get the money that way. So then I actually took a bachelor degree in computer science. So that was like I started 2018 doing that. So 2021 during Covid I was done with that and I got my first job as
Justin Gardner (@rhynorater) (03:14.987)
Mmm.
Justin Gardner (@rhynorater) (03:32.637)
Mm.
Johan Carlsson (03:41.706)
So I was educated as just like an engineer to be able to do like whatever, but I ended up in this as often happened, you get like a job and they say like, can you do, you know, react? And I was like, yeah, sure. Yeah. It was actually sort of like that. So I got that job and I, so, and then I kind of got stuck in that. I switched jobs after a year.
Joel Margolis (teknogeek) (03:56.626)
Sure, of course. It starts Googling how to write React.
Justin Gardner (@rhynorater) (03:57.604)
Give me a week.
Justin Gardner (@rhynorater) (04:03.24)
That's great.
Johan Carlsson (04:10.306)
to where I am now when I'm not doing full-time bug bounties. So I've been doing front-end work, web dev stuff for three years. I started bug bounties at the same time as I started working. They are interconnected.
Justin Gardner (@rhynorater) (04:30.522)
It was interesting to see because you listed in this doc when we were kinda getting like all the info we need to know about you, you listed a bachelor's thesis which mentioned GitLab, which I thought was hilarious because I was like, man, this guy's like writing a thesis on GitLab. Exactly, exactly. So.
Johan Carlsson (04:39.475)
Yeah.
Joel Margolis (teknogeek) (04:47.07)
It's no wonder that he always hacks on it, right?
Johan Carlsson (04:50.063)
And I also like, I kind of got stuck on GitLab. So it's a, I've been doing like, I didn't even know that bug bounty existed before I started that like thesis project. And since then I just been like, keep keeping at them. I guess.
Justin Gardner (@rhynorater) (04:54.248)
Mm.
Justin Gardner (@rhynorater) (05:01.811)
Mmm.
Justin Gardner (@rhynorater) (05:05.544)
Dude, it's great when you've originally, you know, uncovered Bug Bounty and your eyes just kind of open up to that world. It's like, I just, I so clearly remember as well, my first experience with Bug Bounty, just being at this class that I was teaching actually. And Tommy DeVos just kind of bust into this classroom at my school and it's just like, hey, Bug Bounty. And I'm like, who are you? You know, and I'm like, and I'm, who are you, but also.
Johan Carlsson (05:12.3)
Uh...
Johan Carlsson (05:32.684)
Yeah.
Justin Gardner (@rhynorater) (05:35.484)
That's very interesting. Um, so. Mm-hmm. Oh, cool.
Johan Carlsson (05:38.47)
Yeah, I mean, I had a similar experience because I was doing this like ethical hacking course that I could apply for when doing so that was the last year of my bachelor in computer science. You could like pick some courses and I picked an ethical hacking course. And during that course, which was more like a CTF thing, like you had to capture flags in a virtual environment. That kind of hacking, like scanning and mapping things and finding flags.
Justin Gardner (@rhynorater) (06:06.152)
Mm-hmm.
Johan Carlsson (06:08.154)
But you could get like additional points in the course if you found bugs In bug bounties. So that was my first and I went to hacker one so actually I could see like when I signed up I just signed up and I got so like Kind of like scared for the whole concept like how could I ever like find something here like this seems so foreign to me So I
Justin Gardner (@rhynorater) (06:15.417)
No way.
Justin Gardner (@rhynorater) (06:19.944)
Mm-hmm.
Justin Gardner (@rhynorater) (06:29.939)
Yeah.
Joel Margolis (teknogeek) (06:30.782)
That's really interesting. So did your professor, your professor must have known what bug bounty was or whoever was running the course? No, I didn't.
Johan Carlsson (06:35.282)
Yeah. And he was actually, so he was then later my thesis guidance or whatever, what you call it. Advisor. Yeah. So he actually, he was part of like picking a target and stuff like that. So he knew what it was. Definitely.
Justin Gardner (@rhynorater) (06:43.108)
Yeah, I have no idea. Joel. Yeah, that's right. Advisor. Mm.
Joel Margolis (teknogeek) (06:45.866)
Mm-hmm. Yeah, your thesis, your advisor, whatever. Yeah.
Justin Gardner (@rhynorater) (06:57.812)
Hmm. So you said you get extra points for this. So what you're saying, Johan, is you've tanked an exam, and then you're like, how do I pass this class? And he goes like, all right, gotta find a bug. I've backed myself into a corner now. My back's against the wall, help me! So, no, that's awesome, man. That's a cool path, and I love always hearing the ways so many people end up into Bug Bounty and get to where we're at.
Johan Carlsson (07:03.734)
Hahaha
Joel Margolis (teknogeek) (07:09.263)
Searching for extra credit.
Johan Carlsson (07:12.03)
hahahaha
Justin Gardner (@rhynorater) (07:26.096)
So I wanna come back around to some of your experiences now that you're a full-time hunter, but first let's jump into some of these bugs, man, because I was reading through this, some of the bugs that you wanted to talk about on this pod, and whew, they are awesome. Really, like, very cool. And this first one is a CSP bypass, I guess taking an HTML injection and exploiting it in a really CSP-dense environment. So you wanna talk a little bit about that one?
Johan Carlsson (07:55.806)
Yeah. Uh, so, and this is really like my, this is where I really like thrive when I get to do this. And like, first of all, like I, uh, it's my, the perfect situation for me as well, because I didn't really, I didn't find the bug, uh, myself, like the injection points, I was contacted by Sudi, I guess, like Sudi. Yeah. I will not try to pronounce, uh, people's names here, but.
Justin Gardner (@rhynorater) (08:02.268)
Yeah, I can tell.
Justin Gardner (@rhynorater) (08:15.452)
Mm.
Johan Carlsson (08:25.466)
And the bug, yeah. So, so, so this guy, like Ross eight seven six. Yeah. He found like an injection in where you could just like, uh, in an input field in GitHub, you could enter something and you got like an error message back. And that rendered like whatever you put there, just rendered straight back. So it was like completely unfiltered, uh, injection. And I guess they could have just like.
Justin Gardner (@rhynorater) (08:25.82)
Welcome to my world. Ha ha ha.
Joel Margolis (teknogeek) (08:26.97)
Yeah, yeah, us either.
Johan Carlsson (08:54.374)
And they did just report that and they would probably have fixed it and done everything. But you always want to like gain that like last step. So yeah.
Justin Gardner (@rhynorater) (09:03.236)
Especially you. I'm reading these reports and I'm seeing like oh, okay. He got to the last step. Oh, no That's not the last step. There's another oh, he's going he keeps on going all right. Yeah
Joel Margolis (teknogeek) (09:09.306)
Yeah, yeah. One more.
Johan Carlsson (09:12.766)
Yeah, so I was really happy because I know that they contacted some more people and I was the only one who actually figured out how to bypass this. So on GitHub they have this CSP that the script source is just one domain, so there's nothing else. There's no nonsense or anything. So either you have to find something on that domain or you're kind of screwed. And they actually...
Justin Gardner (@rhynorater) (09:19.976)
Feels good, man.
Johan Carlsson (09:39.034)
are one of the ones that actually also had like this form action thing that I always nag about like trying to figure out because people miss it all the time.
Justin Gardner (@rhynorater) (09:47.772)
Yeah, talk to me about that because I had, Joel and I were kind of prepping for this pod that we were talking about. It's like, man, I really have rarely ever seen this. So this is like a CSP directive that allows you to control where a form is being submitted to inside of that environment, right? Wow.
Johan Carlsson (10:05.26)
Yeah.
Exactly. And so the strange thing is that that's not a fetch based request. And that means that it's not covered by default source. So it's one of the exceptions to default source. So even if you put default source in there, it will not cover form action.
Justin Gardner (@rhynorater) (10:14.321)
Mm-hmm.
Justin Gardner (@rhynorater) (10:19.697)
Mmm.
Justin Gardner (@rhynorater) (10:27.292)
Wow. So default source is only for, is that only for fetch-based stuff? Or is there, hmm.
Johan Carlsson (10:33.618)
Yeah, it's like it's only for fetch based stuff, but fetch based is like a really wide term. So it's it covers more than you. It's not just like someone using the fetch framework. There's a lot of stuff.
Justin Gardner (@rhynorater) (10:40.465)
Yeah.
Justin Gardner (@rhynorater) (10:45.56)
Is that a descriptive term or is that a technical term in like the? Okay. Wow.
Johan Carlsson (10:49.542)
It's a technical term in the specification of JavaScript or web stuff.
Justin Gardner (@rhynorater) (10:54.14)
Wow, and how does that differentiate from ConnectSource? And is ConnectSource, is that gonna be different from, is that also gonna be fetch-based or is that?
Johan Carlsson (11:05.362)
I think it will actually get blocked as well. Uh, I think it's only like four, like really strange things that are, uh, not covered by this default source. Uh, and the form action is like the only, like the only thing that you can actually exploit in my experience. Um, but it's so people often miss that. And it's also like on, if you go to this regular, like CSP evaluator that everyone is using from Google, that one will not tell you about.
Justin Gardner (@rhynorater) (11:08.85)
Mm, okay.
Justin Gardner (@rhynorater) (11:16.25)
Okay, gotcha.
Justin Gardner (@rhynorater) (11:22.077)
Mm.
Justin Gardner (@rhynorater) (11:31.794)
Mm-hmm.
Johan Carlsson (11:35.626)
the lack of form action. And I had a discussion on Twitter with this guy from Google about that. And they had their reasons. That validator is only for cross-site scripting-ish things. It's not supposed to tell you everything about CSP because people are using this in all these different ways. But I still think that it should have a mention of this as well. Yeah, yeah, exactly.
Joel Margolis (teknogeek) (12:00.686)
Yeah, it is called the CSP Evaluator, not the XSS CSP Evaluator.
Johan Carlsson (12:03.958)
But if you read in the description it says something about like try to have like a safe CSP for like injections or whatever. Yeah, I don't know.
Justin Gardner (@rhynorater) (12:04.403)
Yeah.
Joel Margolis (teknogeek) (12:12.434)
I feel like I can already hear Bebix in the background, like writing a critical thinking version of this that looks at everything.
Johan Carlsson (12:15.274)
Ha ha
Justin Gardner (@rhynorater) (12:19.002)
Yes. Dude, dude, this is a little bit of a tangent, but Bebex is like really like on top of deving in this community, man. Like he's building the CVSS advisor, the SSRF sheriff, a bunch of Kaido stuff. It's like, anyway, shout out to our boy Bebex.
Johan Carlsson (12:37.182)
Yeah, and I know that there is like one other CSP evaluator that I have been using, and that might actually catch this. I haven't really, but I usually just go for this one as well, because it's easier, and then I just look for it if it's missing.
Justin Gardner (@rhynorater) (12:42.802)
Mmm.
Justin Gardner (@rhynorater) (12:48.756)
Well, it's important too because that's kind of the go-to route, right? If you can't get scripts execution, you're going to be submitting forms and trying for CSURFS or you're going to be doing autofill password exfiltration. So I think it's a really nice directive to have in place.
Johan Carlsson (12:55.511)
Yeah.
Johan Carlsson (13:05.411)
Yeah, exactly.
Johan Carlsson (13:10.718)
Yeah, definitely.
Joel Margolis (teknogeek) (13:11.09)
So there's this one called cspvalidator.org. This might be the other one you're thinking of. And it looks like it does have some stuff mentioned about the form action clause. So potentially, I don't know. I haven't tested it to see what it does. But potentially, this might also be. I'm not sure if this is just for validation or if this looks for the issues that you get.
Justin Gardner (@rhynorater) (13:15.293)
Check that out.
Justin Gardner (@rhynorater) (13:24.916)
Interesting. Check this out.
Justin Gardner (@rhynorater) (13:32.148)
This one could be better.
Joel Margolis (teknogeek) (13:38.97)
surfaced with the Google CSP validator, but that could also be an option. I'm not sure. But definitely worth it. If you find a link to that, let us know. We'll put it in the description.
Johan Carlsson (13:44.53)
Yeah, I mean, yeah, I will try to find it. But it's definitely like one, it's my go-to thing as well. Like if I cannot do anything else, I try to do a form and like try to argue that you can do like auto-fill bugs. Some programs accept that, some doesn't really care, but it's still like a valid exploitation path, I think, that you can create like a form field, even like hidden or whatever.
in a page and it will get auto filled and maybe even auto submitted and whatever and you steal credentials and stuff. So I think it's valid.
Justin Gardner (@rhynorater) (14:19.524)
Yeah, absolutely a valid method, in my opinion.
Joel Margolis (teknogeek) (14:23.262)
I also didn't know this, but the CSP evaluator itself is actually open source on GitHub. So if you want to extend it, if you want to extend it and just add that functionality.
Johan Carlsson (14:27.974)
Yeah, yeah, yeah. But they don't want it, they don't want it.
Justin Gardner (@rhynorater) (14:29.024)
Alright, alright Joel.
Justin Gardner (@rhynorater) (14:35.44)
Do you see how we sniped, we got Joel on a path, and now Joel has gone to a different CSP, and now Joel's looking at the code of the CSP evaluator during... Technogeek.io slash CSP evaluator, let's go. Okay, I'm sorry, Yohan, back to, so we've grilled you on CSP enough now, yeah, go ahead.
Joel Margolis (teknogeek) (14:35.822)
It's there.
Johan Carlsson (14:42.038)
hahahaha
Joel Margolis (teknogeek) (14:45.37)
By the end of this episode, I'm going to have a CSP value written.
Johan Carlsson (14:55.292)
Now, so, yeah, so, that's one of the things that I wanted to do because I could inject like arbitrary HTML, right? So there was like a form in the page. So the other thing that I usually think about then is to like just form hijacking. So you could do like add these like input elements and you on the input element, you say like form action.
Justin Gardner (@rhynorater) (15:04.669)
Mm-hmm.
Johan Carlsson (15:20.798)
and form so you can like change the actions and targets and stuff off the form and you could potentially then if you can do that you usually can steal like CSRF tokens because you can change the target of the or the action of the form and you can submit it and you get the CSRF and maybe you can like escalate from that. So the first.
Justin Gardner (@rhynorater) (15:30.673)
Mm-hmm.
Joel Margolis (teknogeek) (15:40.974)
It's interesting. So it's on the input element itself, right? Like the, that are within the form.
Johan Carlsson (15:44.958)
Yeah, so it can be outside of the form because you can also put like a form, you can point it to which form you're, uh, is going to use.
Joel Margolis (teknogeek) (15:52.282)
Okay, so does it take over the entire form or does it just take over those specific elements?
Johan Carlsson (15:58.57)
It takes over whatever you use. So you can, it will add itself to the form. So everything that's already in the form will still be there, but you can change the action and you can change the target and you can change some other stuff. But then, so the problem then was that I couldn't like exfiltrate it anyhow, because it was quite strict like form action. I think that you could actually hit some other endpoints with it. I don't remember, but.
Joel Margolis (teknogeek) (16:03.537)
Okay.
Joel Margolis (teknogeek) (16:11.134)
Cool.
Justin Gardner (@rhynorater) (16:12.096)
Hmm. Yeah, very cool technique.
Johan Carlsson (16:26.91)
What I ended up trying to do was to actually change the form action to like an internal to just hijack the form to like target some internal API So just doing like a client side Attack instead so like changing it then you can also add like all of these new like input fields That will also be so you could fill it with data that this API route would need then So I was really happy with that and I fired it off and nothing happened
and I was like super confused and then I... So this was the only time and the first time I've encountered this that they had like CSRF protection per form. So like each a form, they fetch the form and it has a CSRF token but it's only valid for that path that it's created for. And this is some like Ruby on Rails thing.
Justin Gardner (@rhynorater) (17:10.056)
Crazy dude.
Joel Margolis (teknogeek) (17:16.786)
Do you, did you experiment to see if, did you experiment to see if it was like deeper than that? So like, for example, on a page that has two forms, you couldn't swap one CSRF from one form to another form on the same page or is it?
Johan Carlsson (17:28.594)
No, it's actually... I think it actually gets back to the final bypass later, that it's actually used this hotwire stuff, because it fetches the forms as a building block and puts it in the page. And somewhere in the back end of this Rails thing, you can enable this CSRF by perform thing, and it creates this protection for your whole page, sort of.
So that's some sort of feature in Rails. I haven't looked too deep into it. I just Googled it and figured out like, okay, so this will not work then. Yeah. But so that will lead into the actual bypass, which is like when I was like researching this, I saw that everything was nested in this like weird elements that I haven't never seen before like turbo frames. So like, and I searched in the page for it and there was like a lot of turbo frame mentions everywhere.
Justin Gardner (@rhynorater) (18:01.14)
That's super frustrating.
Johan Carlsson (18:24.034)
So I started googling for that and found that this is part of a kind of new addition, like a new framework to Rails, which is called Hotwire. I don't know if it's usable outside of Rails as well, but it's sort of like Ruby on Rails version of what you talked about last week, then the HTMLX thing. So it's like HTML over the wire, which is...
Justin Gardner (@rhynorater) (18:37.052)
Mm.
Justin Gardner (@rhynorater) (18:46.517)
Oh geez.
Johan Carlsson (18:51.09)
If you look into it, it's actually a concept that exists in all the big frameworks. So Laravel has its own that is called LiveWire or something. And Phoenix LiveView, which is based on, yeah, whatever you call that, Elixir. Right. And so there are a lot of these and most like, so these ones are actually tied to a specific framework and that makes them a bit harder.
Justin Gardner (@rhynorater) (19:08.924)
Mm-mm.
Johan Carlsson (19:20.13)
to exploit like htmx is just a javascript library and these are like Framework libraries that also have like a small javascript piece that you can hook into
Justin Gardner (@rhynorater) (19:31.08)
back-end component and a front-end component.
Johan Carlsson (19:33.006)
Yeah, exactly. And so now my kids turned up here for a short while in the background, so we'll see if they annoy you too much.
Justin Gardner (@rhynorater) (19:45.064)
That's fine. No, if you want to, I think we can, we'll do a cut here at 1950. Kids arrive. Okay.
Johan Carlsson (19:58.638)
Ha ha ha.
Justin Gardner (@rhynorater) (20:02.74)
I'm going to highlight this in green for Richard so that he sees it. Actually not like that. I'm going to do the.
Okay, cool. Yeah, dude, so. Okay, all right, we'll give him a second. Yeah, dude, it's ISO. Looks like you have a little bit of a similar setup. I don't know, there might be a door there, but my office is technically, there's a washer machine right here. I don't know if you can see it, but I try to keep it just out of frame. There's a washer machine right here, so it's our laundry room, and it doesn't have a door.
Johan Carlsson (20:14.114)
Oh yeah, it sounds like they're moving already.
Johan Carlsson (20:33.026)
Yeah.
Johan Carlsson (20:38.155)
Yeah.
Justin Gardner (@rhynorater) (20:41.304)
over there. So I have no door to my office from the rest of our house and I've been like
Johan Carlsson (20:42.478)
No. It's actually the same for me, like I'm supposed to have a wall here, but I don't. Like I haven't built it yet, so it's just open downstairs.
Justin Gardner (@rhynorater) (20:48.068)
Yeah. Same, same. Yeah, dude, I gotta get that done, man, because it's like, and I've been trying to contact contractors and stuff, but the frame, which you can kinda see, I'll try to put my, yeah, it's like right here, this frame, is like just like an inch smaller than the normal door size. So you have to have like a custom built door, and I'm like, ugh, this is so annoying. But I'll find someone to do it eventually, it's fine.
Johan Carlsson (21:08.974)
Mm-hmm. Ha ha.
Johan Carlsson (21:12.29)
Ha ha ha.
Justin Gardner (@rhynorater) (21:17.904)
All right, so the kiddos, did the kiddos move along? Okay. All right, so kiddos have moved along. Let's get back to the story. So you found this, you got a, let me summarize to this point, you've got a sort of self-access test of sorts where you put some text into a input field, an error gets generated that reflects that exact text back. Now you've got HTML injection here, and you're trying to exploit via C-Serve, send form submissions.
Johan Carlsson (21:18.252)
Oh yeah, so, yeah, they're gone. Already gone.
Justin Gardner (@rhynorater) (21:47.484)
But the CSRF protection is in place, which restricts it directly to the route. So now we've got to figure out some way around.
Johan Carlsson (21:55.442)
Yeah. And so I can also add that the other two guys already had this like drag and drop POC at this time. So the way to exploit this was actually you kind of like you are on the attacker page and you drag some image to somewhere and you drop it and it kind of closes itself and it drops in. So it's a bit like you have to do a lot of like user interaction. But I still think that this is like you encounter this everywhere,
Justin Gardner (@rhynorater) (22:19.496)
Hmm.
Johan Carlsson (22:25.486)
Proton has their own like What you call this like cap chatting That works exactly like that. You have to drag like a small puzzle piece to some player and like so users are really like They are used nowadays to do these kinds of actions. So I think it's a valid. Yeah. Yeah but yeah, so back to the The hot wire stuff so I was googling this. Yeah
Justin Gardner (@rhynorater) (22:35.988)
That's true. That's a great point.
Justin Gardner (@rhynorater) (22:44.412)
without even thinking about it.
Justin Gardner (@rhynorater) (22:51.16)
And actually, let me, I'm sorry, let me interrupt and get one clarifying factor there. So when you set an image, the way you're doing that is you're taking the text that you want to insert, you're putting that in the alt tag of the image and then you're dragging it on there. Is that what populates it or is it something else?
Johan Carlsson (23:05.054)
No, it's just the JavaScript. So the person thinks that they are dragging an image, but when you click it, there's like an JavaScript event that listens for that. And it fills your clipboard or like, yeah, it keeps, yeah, your drag thing, it fills it with this payload. And when you release it, it will fill this form field.
Justin Gardner (@rhynorater) (23:21.544)
Your drag, okay. Interesting, okay.
Justin Gardner (@rhynorater) (23:30.088)
Very nice, okay, that makes sense.
Johan Carlsson (23:32.106)
Yeah. And so... Yeah, so I found this Hotwire stuff that I hadn't seen before. And it seemed pretty simple. Like, there's like three parts to it, which one of them is not really interesting for this, which is like this event-based thing that is... It cannot cause XSS on itself, because the events are only made in a connection to the backend. So it's a...
It's not the same as HTMLX there. But the other two... Yeah.
Joel Margolis (teknogeek) (24:05.563)
Okay, random question really quick. When you're discovering this and you're going down this rabbit hole, is this through source code analysis or is this from more of a black box perspective?
Johan Carlsson (24:15.602)
I just, I found these tags in GitHub, like in the page source, or like the DOM, and they confused me because they were like, they're not regular elements, so they must mean something. So that was my thinking. So when I started Googling it, I just found this, the documentation essentially, where they described that there existed like two concepts, like a...
Johan Carlsson (24:42.39)
What was the name of them again? I forgot. Yeah, the turbo frame and the turbo stream. So the turbo frame is quite similar to the HTML thing that they are, you have a turbo frame with an ID in your DOM, in your page. And then you make like you tell this framework to make a request to the backend and it gets HTML back. And in that response, it will look for another turbo frame that matches the ID.
Joel Margolis (teknogeek) (24:44.254)
or the turbo, yeah.
Justin Gardner (@rhynorater) (24:44.29)
What?
Justin Gardner (@rhynorater) (24:48.373)
Mm.
Johan Carlsson (25:10.634)
and it will just swap the content in your DOM with the content from this response. So the response can contain like a lot of other stuff, but it will find the turbo frame in the response and it will just swap it in place without the page reload or something.
Justin Gardner (@rhynorater) (25:25.96)
Well, it's interesting that it also works in an environment where you've got just an inner HTML sync. Because I would have thought that they would be doing that processing on the result of a fetch request or in some other way. But it seems like using this, yeah. Hmm.
Johan Carlsson (25:41.362)
Yeah, so it's actually, it has like an observer. And this is something that I've used. Rails also have this concept of like UJS, like UJS things that are like, it's reacting. They have like observers that looking at the DOM all the time, like, and when there's changes, they react to this. And this is something that you can often use for just like script gadgets, because it will trigger even if there's new content added to the page.
Justin Gardner (@rhynorater) (26:02.228)
That's cool.
Johan Carlsson (26:10.358)
So this is what happens now, like if you add one of these frames and it's empty, the system will make the fetch to like get this content for you and just replace it. So that's when I realized that I could get like another form, like a more dangerous one. So I picked the one where you can add like an SSH key to your account because that's like...
Justin Gardner (@rhynorater) (26:32.372)
Hehehehehehehehehehe
Joel Margolis (teknogeek) (26:33.982)
Pretty good one.
Johan Carlsson (26:34.91)
Yeah, and then you don't need to, because you can still not exfiltrate the response. Like even if I could create like an access token or whatever, I cannot get to that token because I will not see the response because it's still just HTML, there's no JavaScript. But that, when I add like an SSH key, I can actually get access to the account because I have the secret key, I just add the public thing. So that's, yeah, that's really good. A good attack vector.
Justin Gardner (@rhynorater) (26:57.896)
Perfect.
Johan Carlsson (27:03.886)
And so I could add that form. So that was all nice. But then that form is added like empty. And that's where these turbo streams come in. Because the difference between turbo frames and turbo streams is that when you add a turbo stream, you add the selector and you add like a template, an HTML template. And when that appears in the DOM, it will look at the target that you have specified like a CSS selector.
Joel Margolis (teknogeek) (27:04.446)
That's awesome.
Johan Carlsson (27:33.578)
and it will replace that element that you hit with the template that you added. So that's, so in that way you could actually like, so I first, my idea was that I first catch, like I pulled down the correct form and then I start adding it with like these turbo streams that kind of replaces content in the form with my SSH key and like whatever I need to have it.
Justin Gardner (@rhynorater) (27:38.836)
You've gotta be kidding me.
Johan Carlsson (28:02.691)
put my data on the victim's account.
Justin Gardner (@rhynorater) (28:05.052)
Wow, okay, so now we've dragged the image into this sort of text box or whatever, it's not an image or it's actually text from the JS. We've triggered the HTML injection, then we're using these turbo frame, turbo stream gadgets to dynamically construct a arbitrary frame with the correct.
Johan Carlsson (28:15.201)
Yeah.
Justin Gardner (@rhynorater) (28:32.796)
CSRF token and I guess the CSRF token gets loaded. Oh. Wow.
Johan Carlsson (28:36.339)
Yeah, that gets loaded with the turbo frame. So that's by design, just coming with the form that you're fetching.
Justin Gardner (@rhynorater) (28:42.704)
And that's a part of that sort of client side, server side collaboration that we were kind of talking about with this HTML over the wire. Very cool. Okay, so how do we get it all the way? Are they just gonna press submit now or?
Johan Carlsson (28:46.963)
Yeah. Exactly.
Johan Carlsson (28:53.982)
Yeah, so there was actually like one problem with the turbo streams is that they will execute as soon as they appear in the DOM and that's true for the turbo frames as well. But the turbo frame takes a while to load because it has to fetch this data, right? So I couldn't actually have the frames and the streams at the same time.
Justin Gardner (@rhynorater) (29:06.769)
Mm-hmm.
Johan Carlsson (29:17.174)
So there I actually had to use like an older, like a gadget that was present in GitLab, GitHub, where they have this older thing that is called like data replace with, which is a data attribute from this Rails, the legacy code sort of, like before Turbo. And there you can do like, if you click a button, it will replace itself with whatever you have in the data attribute.
So then I had to put the turbo streams. Yeah, so I had to put the turbo streams inside of this on click thing. So you had to click a button to actually fill the form and then you had to click another button to submit it. So it was at this point it was like a two click thing. Because I had all of these gadgets. But you had to drag it and then you had to click anywhere on the page because I could fill the page with these buttons. You had to click anywhere like two times. So that's not.
Joel Margolis (teknogeek) (29:49.814)
Useful functionality.
Justin Gardner (@rhynorater) (30:05.929)
Mmm.
Justin Gardner (@rhynorater) (30:12.116)
Mm-hmm.
Johan Carlsson (30:17.25)
It's not a perfect POC, but it shows that you can do something. So we reported that, but I wasn't really happy with it, so I kept on digging. At that time I actually reached out to William Bauling, Vax. Yeah, yeah. I knew that he had done some work on GitHub previously.
Justin Gardner (@rhynorater) (30:19.484)
Yeah. Right?
Justin Gardner (@rhynorater) (30:26.556)
How did I know? How did I?
Justin Gardner (@rhynorater) (30:34.657)
Mmm, Vax, another great guy to bring on the scene here. Okay.
Johan Carlsson (30:44.59)
And he was kind enough to share like this really strange click gadget with me Which is code that they now they have it still on github where you can you sort of you add the fragment and This code will try to find an element which has that fragment as an href attribute And it will click that element for you. So it's like a click gadget So if you so whenever there's
Justin Gardner (@rhynorater) (31:13.072)
In the hash, so you put something in the hash, and then if it's, is this taking advantage of that sort of auto focus feature where you like, oh really, wow. Okay.
Johan Carlsson (31:14.93)
Yeah.
Johan Carlsson (31:22.814)
Now it's just custom, it's just listening for on hash change. And when it changes, it will take whatever you put in the hash and it will look for something in the DOM that has this exact value as their href, which is kind of strange. Like I don't, I don't really know what they use it for, but I guess it's used for actually clicking links. Uh, but I could also put like an href on a button. Like there's nothing stopping you from that if there's, if there's no sanitization.
Justin Gardner (@rhynorater) (31:37.948)
Wow, that's crazy, yeah.
Johan Carlsson (31:52.374)
So I could actually make it click buttons for me. So that was sort of the last thing. So now the final exploitation is that you end up with this attacker page, you do the drag and drop. And then while you're dragging, there's a small window opening that you don't really see. And that window is like, has this connection, like an opener connection to the page or a parent.
Justin Gardner (@rhynorater) (31:56.459)
Hahaha dude that's clutch
Joel Margolis (teknogeek) (31:59.746)
So interesting.
Johan Carlsson (32:20.574)
actually you open it so it's a parent and you can that one is also attacker controlled so it cannot get the content of github but you can do i actually think that this is quite a kind of strange behavior from browsers because if you do if you go to the exact you do like a location equal something new it will load that new page like you're allowed to do that cross origin but if you go to the exact same
domain, but you just add the change to fragment, it will not fetch the page again. It will do just like a hash change. So in a way that's like, yeah. So it's sort of like a cross origin connection. If you have like a
Justin Gardner (@rhynorater) (32:58.74)
Cross origin to.
Justin Gardner (@rhynorater) (33:02.96)
Okay, let me, yeah, absolutely, let me pause that there and just reiterate that for the listeners. So if you guys are listening while you're doing dishes or doing some task or something, listen to this part, okay? So what he's saying is it's possible for you to do, if I understand correctly, Johan, so correct me if I'm wrong, but a window.open, and if you know the full path of the page, you can specify a hash on that URL, it will not refresh the page.
and it will just trigger a hash change on there, which allows you to not refresh the page, but also affect some event to be triggered cross origin on that page. Is that accurate? Such a cool gadget, man.
Johan Carlsson (33:40.638)
Yeah, exactly. Yeah, that's a really strange behavior actually. I think it should just like always force a refresh if you're from a different domain. Because you could also use it for that sort of what you talked about, like highlighting. But now, OK, that you cannot actually do cross origins. So that's already safe. But yeah.
Justin Gardner (@rhynorater) (34:01.18)
Mm-hmm. Yeah, it used to be, Yusef abused, I think, this exact same functionality in exactly scroll fragment-based behaviors there. But this is different. One of the things that I really like about what you just specified is it's, you have to know the full path, which you could, theoretically, if you opened it, it's very, very reasonable. And then,
Johan Carlsson (34:08.694)
to cause like scroll behaviors and stuff like that.
Justin Gardner (@rhynorater) (34:27.196)
But if you were not to know the full path and you just did window.open hashtag whatever, target equals whatever frame, then that would not because that would be opening up relative to the other, the page where it came from, right? Is that accurate? Yeah, so very odd, very odd behavior from the browsers here.
Johan Carlsson (34:36.811)
No, exactly.
Johan Carlsson (34:40.618)
Yeah, exactly. So you have to specify the full thing. Yeah.
So that was the final piece that we needed to make it a zero click after the drag and drop. Because now I could make the two button clicks. Like the click to inject the turbo streams and then the click to submit the form could be done through this hash change events. So I just had to change the hash twice.
Justin Gardner (@rhynorater) (35:01.176)
Mm-hmm. Mm.
Justin Gardner (@rhynorater) (35:10.144)
by chaining those again. So drag and drop triggers the HTML injection, injects the form, triggers the hash change as well, and that hash change clicks a button which injects more and another click gadget, and then that changes the hash again and finally clicks on the thing which will actually submit the form.
Johan Carlsson (35:19.126)
Yeah.
Johan Carlsson (35:23.936)
Yeah.
Johan Carlsson (35:28.204)
Yeah, exactly. So I was really happy with that one. And it's...
Justin Gardner (@rhynorater) (35:29.92)
Oh my gosh, Yohan!
Justin Gardner (@rhynorater) (35:35.657)
Dude.
Joel Margolis (teknogeek) (35:35.738)
I wonder if this is how people feel when I talk about mobile bugs.
Justin Gardner (@rhynorater) (35:38.276)
Yeah, like it's amazing, man. You know, I love client-side stuff as well, and just seeing this is just spectacular. So I'm gonna actually, hold on, let me see if I can find, I haven't pulled this guy out in a while, but is it doing it? Is it playing?
Joel Margolis (teknogeek) (35:57.618)
Nothing happened. That was a fail.
Johan Carlsson (35:58.683)
Ha ha
Justin Gardner (@rhynorater) (36:01.18)
You know, I, oh, hold on, no, change it to live. Hold on, hold on, hold on.
Justin Gardner (@rhynorater) (36:07.864)
You guys hearing it? OK, all right. If not, Richard, overlay a little clapping thing for me, please, because I tried to use the Riverside built-in media thing. But well done, Johan. That's amazing. Mm.
Johan Carlsson (36:09.079)
Yeah, yeah, yeah.
Johan Carlsson (36:20.258)
But then, like in the end, I know that I saw someone ask something about this on the Discord, like if this was worth it for Ross876, like in the beginning, and I actually think that he didn't... Like, we split this, and it still didn't really push it high enough to become... Like, they... Yeah, maybe we shouldn't leave out like the final piece from GitHub, which is that you...
Justin Gardner (@rhynorater) (36:31.112)
Ha ha!
Justin Gardner (@rhynorater) (36:47.549)
Mm.
Johan Carlsson (36:49.39)
To perform these kind of actions, you have to be in like, pseudo mode, which if you have been using GitHub, you know that if you try to do like, anything that is like, change a name of a repo or something, you will be asked to like, put in your password, and then you're in pseudo mode for like, four hours after that. So you have to be in that mode for this to work, sort of. So that's also part of the, you kind of have to target people at the right time if you were to like, exploit it, like, send.
Justin Gardner (@rhynorater) (36:54.271)
Ah.
Johan Carlsson (37:19.274)
send the link at some time in the working day or whatever.
Justin Gardner (@rhynorater) (37:22.116)
Interesting. Okay, couple questions here, okay? One, so normally when you see this drag and drop behavior, you're doing this into an iframe. And in this scenario, I checked the CSP on GitHub. It's no frame ancestors, of course. If they're taking CSP seriously, they're not gonna let their page get iframed into any random page. So this was all done via window open, sort of, what's the name of that research that came into the cool?
Johan Carlsson (37:34.719)
Mm.
Justin Gardner (@rhynorater) (37:50.644)
cool research tab in like cross-window forgery attack sort of situation, right?
Johan Carlsson (37:55.838)
Yeah, sort of. We're actually navigating. So when you're about to release it, you have actually, you kind of just switch it out for the github's normal page. So there's one of those flows in the paper you mentioned, the one when you kind of just close the window or switch or whatever.
Justin Gardner (@rhynorater) (38:03.22)
Mm.
Justin Gardner (@rhynorater) (38:10.513)
Mmm.
Justin Gardner (@rhynorater) (38:15.217)
Mm.
Justin Gardner (@rhynorater) (38:20.104)
Yeah, I'll link that down below. That's Cross-Window Forgery by Paulos Yebelo. There we go with the names again. But yeah, so you're able to switch the page and drop the text into the page.
Johan Carlsson (38:24.075)
Yeah.
Johan Carlsson (38:32.295)
So, yeah, so I really, I agree with GitHub here to put it like, they put it on medium somewhere and I think that's fine. I just had a really good time with the CSP bypass. For me, it didn't really matter. And I think we at least doubled the bounty from it.
Justin Gardner (@rhynorater) (38:48.264)
Feels great.
Justin Gardner (@rhynorater) (38:51.876)
Excellent. Yeah, and mediums on GitHub aren't anything to scoff at, either. I mean, GitHub pays very well. So that's amazing to see. OK, so that was one of the questions was, OK, you're doing this sort of cross window. So that's pretty cool. And the other thing that I wanted to kind of bring up and highlight here is this whole concept. So we talk about gadgets on the pod a lot, right? One of the things that we haven't talked about quite as much is this whole concept of a script
Johan Carlsson (38:56.711)
I don't know. It's a... Yeah.
Justin Gardner (@rhynorater) (39:21.068)
script gadget within the page in these high CSP environments. How can we convert HTML injection into something a little bit more functional using these pieces of script that already exist on the page? Reading through a couple of your other pieces of work and this as well, it's become clear to me that this is one of your...
This is your jam. And this is, in my mind, you're one of the most, foremost experts on this specific sort of gadget of sorts. So I want you to give us a little bit of insight into how exactly this, how you discover these sort of events. And obviously you can look at like hash changes and stuff like that. So anytime we're trying to explain anything in these sort of environments, it's always great to like go to global listeners, open your dev tool, go to global listeners, look at the hash change.
Johan Carlsson (39:48.911)
Yeah, yeah, yeah.
Justin Gardner (@rhynorater) (40:17.092)
event and kind of see what code is going to be running on hash change. But looking at the writeup you passed along to me as well, there's like, you know, there are events happening when there's a specific class of object being added to the DOM and like sorts of things like that are just way out there. So how are you finding these in the first place in order to construct this like beautiful chain?
Johan Carlsson (40:32.191)
Yeah.
Johan Carlsson (40:40.646)
It's, I think probably it's quite funny because when I started, like I was looking into, so when I did my thesis way back, the GitLab thing, we were, one of the things that we did then was that we downloaded like all the disclosed reports from GitLab into a spreadsheet, me and my thesis partner. So when we started, we read like, and at that time I didn't know anything about this, like security or like.
Justin Gardner (@rhynorater) (41:09.094)
Mm.
Johan Carlsson (41:10.666)
But we read all of these reports, one after another, and some things stood out. And you sort of realized that at that time at least, like William Wax, he was the main antagonist on GitLab. He was crushing it with RCEs and stuff at that time on XSSs. So I just studied his works. And from where I... Yes, I... Yeah.
Justin Gardner (@rhynorater) (41:21.232)
Mm-hmm.
Justin Gardner (@rhynorater) (41:24.719)
Yeah.
Justin Gardner (@rhynorater) (41:34.536)
Classic move. Highly recommend that to anyone who has the time. Yep.
Joel Margolis (teknogeek) (41:39.718)
Mimicry is the sincerest form of flattery, right?
Johan Carlsson (41:40.23)
from Yeah, and we're from where I was coming from I was like, okay So this is how you do it like you have to find these Gadgets and you have to do all of this and like because I was starting I found my first Cross-site scripting like by super accident just after I had been doing this research like the thesis paper for three months Like trying putting payloads everywhere and stuff like that didn't find anything
Justin Gardner (@rhynorater) (41:41.812)
That's true, that's true.
Johan Carlsson (42:06.762)
And then the summer came and I was done with school and everything and I had passed and everything was fine. And I just got this feeling. I was at my parents having some summer vacation and I just thought like, okay, I'm going to just go in and try this. I had this one injection point that I wanted to do something. You could name like a default repository thing. And so when someone creates a project and it shows you some instructions like
Justin Gardner (@rhynorater) (42:10.92)
Mm.
Johan Carlsson (42:35.562)
run these commands to create an empty repository or whatever. Uh, and I know that I, you could put something in there and I just went there and just added a super basic, like script alert thing, and then it popped. And I was like, what? I mean, I was like, I ha I'm no, it can't be that easy. And also like, I know that I tested this like just a couple of weeks back. And after all of this happened and later I looked and the code change was just like two weeks old.
Justin Gardner (@rhynorater) (42:51.813)
Can't be this easy.
Johan Carlsson (43:05.362)
So it was like super just like by this accident that I went there like, and they actually changed the code between me first testing it and then testing it again. But, but, and then I stumbled. So that popped on my local thing. And then I went to GitLab.com and I was like, yeah, I'm going to get this like super awesome high paying bug now. And nothing happened.
Joel Margolis (teknogeek) (43:15.39)
wild.
Justin Gardner (@rhynorater) (43:16.276)
It's crazy, man.
Johan Carlsson (43:29.406)
And that was my first encounter with the CSP. Like I had never heard about it before. I just opened the console and it said like CSP blocked. I was like, what? Yeah. So then I went and just saw and so some people had already used some of these gadgets before on GitLab and then I found some of my own as well.
Justin Gardner (@rhynorater) (43:29.754)
Oh no.
Justin Gardner (@rhynorater) (43:39.016)
Dun dun dun. From that day on, Johan was triggered anytime he saw a CSP.
Johan Carlsson (43:58.502)
just by essentially like reading the source code and like grepping for these kinds of behaviors where it's like looking for. I kind of went from the sink, like I found places where it did like fetch requests. I have a few reports where I can do like this client side attacks where I could create some element and it will be replaced by some form that I can control the path.
And then I can just make like one put request to the API. But with that one request, you can make yourself an admin if it's like an admin who clicks the link or.
Justin Gardner (@rhynorater) (44:34.772)
So it seems to me, just from hearing that explanation and looking at your Hacker One history and that sort of thing, that you're just, this is a function of you being sort of growing as a hacker in a highly CSP'd environment. Because I think most people don't start off at GitLab and don't start off at some of these other more hardened targets that have these CSPs in place. So we're all used to, oh wait,
the HTML's reflecting, boom, XSS, you know, game over. But because you kind of grew as a hacker in this highly CSP'd environment, there's always that extra step for you and it forced you to adapt. And these adaptations look like these script gadgets and these sort of far out ways to get around CSP.
Johan Carlsson (45:08.722)
Yeah
Johan Carlsson (45:26.874)
And you kind of, you can see that they are also like shared between in GitLab. You can see even the non-disclosed reports. You can often see them in their like issue tracker later. And you can see like these. So I, in the beginning, I used some of Vax, like CSP bypasses, and then I found some of my own and then I've also seen like other people use mine and you get like proud, like, yeah, way to go. Like, uh, and now they're, they actually like.
Justin Gardner (@rhynorater) (45:37.795)
Mm-hmm.
Justin Gardner (@rhynorater) (45:51.616)
Hahaha
Joel Margolis (teknogeek) (45:53.228)
Hehehe
Justin Gardner (@rhynorater) (45:54.248)
That's great.
Johan Carlsson (45:56.326)
Just a couple of weeks ago they killed one of the absolutely the best ones That was like because what you want You want something that also can pass dom purify, right? And still work as a script gadget after dom purify and they had like this one That I know like a lot of people have used it like it I think that vax found it like three years ago and they have never like came around to It was just like
Justin Gardner (@rhynorater) (46:00.958)
No!
Justin Gardner (@rhynorater) (46:08.194)
Mm-hmm.
Justin Gardner (@rhynorater) (46:21.116)
Build the details, come on, let's go!
Johan Carlsson (46:24.722)
Like, quite the same kind of functionality. Like, you put a... They think, at least, like in the code, they thought that they were targeting a form. So they were looking for forms. And that a form that had like one class and classes are like, you can put that through dump your file, it's fine.
Justin Gardner (@rhynorater) (46:45.032)
Wow, I thought it was gonna be a data attribute. I'm not gonna lie, but it was a class. Okay, interesting.
Johan Carlsson (46:48.606)
Yeah, it was a class. So this was like a custom code that looked for this class on the form they called it, but you could actually put this class on anything. But then it looked for an input element in this form. So the input element actually needed to be an input element, but the form could be anything. And input elements are fine and forms as well by default, but GitLab is actually stripping forms, but...
Justin Gardner (@rhynorater) (46:57.132)
Mmmmm
Justin Gardner (@rhynorater) (47:06.729)
And you can get those through DOM Purify?
Justin Gardner (@rhynorater) (47:12.232)
Mm-hmm.
Johan Carlsson (47:15.89)
So that was the good part about this gadget because it didn't have V-form. It could be a div or whatever. And then it would look at this input element and for some reason it would take like the title, which is also fine through DOM Purify and do some sort of like replacement, putting it in the DOM, like whatever you put there. So then you could add like a, some, something that popped and it would also then be valid because it was coming through with like the nonce.
Justin Gardner (@rhynorater) (47:20.82)
That's awesome.
Johan Carlsson (47:45.838)
through the CSP, right? And like inheriting the nonce value.
Justin Gardner (@rhynorater) (47:47.28)
Ah, doesn't that need to be like, in some cases it's unsafe eval, but like strict dynamic or something like that? Yeah, okay, but that's what their CSP has strict dynamic.
Johan Carlsson (47:56.411)
strict dynamic, yeah. So it will actually like inherit... Yeah. So they have nones and strict dynamic. So it's fine to add stuff with like a script gadget that then adds a script to the page.
Justin Gardner (@rhynorater) (48:10.76)
Wow dude, that's awesome. And these gadgets are so complex. And actually I've got a situation, I don't know. I don't know, did Monke reach out to you recently with a CSP bypass that he needs on a very highly CSP'd environment or no? Okay, because I've been banging my head up against this for a little. So after this episode, I'm gonna show that to you and see if we can get a bypass.
Johan Carlsson (48:29.329)
I don't think so, no.
Johan Carlsson (48:33.122)
Ha ha
Justin Gardner (@rhynorater) (48:38.392)
Yeah, okay, so that makes a lot of sense. You're, let me just, mm. Mm.
Johan Carlsson (48:41.686)
But it also like it also it takes a lot of time. So it's not really something you can do if you're just like skimming through programs like jumping around like finding one of these. So when I found some of my own where I could just like inject this like one click stuff and I got it through dome purify, then I know that if I can just find like one because you could have like an injection that is like full. But then you can also have these ones that are actually sanitized.
So those are like easier to find because they make that mistake more often than just getting by. Don't be right.
Justin Gardner (@rhynorater) (49:19.956)
So with these, how do we identify these? Are you literally just grepping through the source code looking for any sort of dot whatever, clearly a class CSS selector, an ID CSS selector that's put into place and then trying to figure out if they're binding any functions to these sort of classes existing, or is it just reading through the whole thing? And how are you identifying these? Is there some trick to this?
Johan Carlsson (49:41.869)
Yeah.
Johan Carlsson (49:46.602)
Now I've been doing it like all the different ways, like putting a break point at the beginning of the JavaScript just to see if it adds something. But then also just like looking at all the places where it's actually using like CSS selectors to get elements and to see if. And for, yeah, usually they have some sort of like main functionality that's kind of like kick starts.
Justin Gardner (@rhynorater) (50:05.352)
Mm.
Johan Carlsson (50:17.144)
whatever all the other JS on the page is gonna do and you can kind of see there if they're like trying to initialize some stuff.
Justin Gardner (@rhynorater) (50:26.26)
This reminds me of a bug that I found that is, of course, HackerOne, my two weeks is up right now in the middle of this pod, so now I've gotta like, somehow it's always in the middle of the pod when I'm trying to get into my bugs to talk about something. But the only thing I've ever found that is remotely similar to this is essentially what you just mentioned, which was hijacking selectors for your...
Johan Carlsson (50:35.836)
Classic.
Joel Margolis (teknogeek) (50:35.986)
It's always on Mondays.
Johan Carlsson (50:40.374)
Yeah.
Justin Gardner (@rhynorater) (50:54.744)
your purposes. So I remember in this one scenario, I believe it was a WAF based scenario where I could only get through like on click or something like that and it was on an element that you couldn't click on or something. And I was able to like name it a specific ID and add a specific ID to the element and then later down it would say like click this ID, like this ID or whatever, dot click and it would hijack it and pop the XSS and I was like...
Johan Carlsson (51:20.514)
Ehh... Hehehehe...
Justin Gardner (@rhynorater) (51:21.724)
I am a legend, you know, like, and then, you know, Johan rolls up in here with like this 16 step chain. No, so just to summarize this for the listeners as well, like I mentioned before, this is a really great example of how a hacker adapts in a different environment, right? Most of us, like I mentioned before, are not really exposed to hyper-CSPed environments, and as we continue to...
Johan Carlsson (51:28.384)
Ha ha.
Justin Gardner (@rhynorater) (51:50.388)
move that direction in the industry where CSP becomes more widely accepted and more, you know, just as time passes and it gets a part of everything as default, we're going to have to adapt in this way. And so it's really helpful for us to look at examples like Yohan and how he's adapted already over time to bypass these because we're going to be doing a lot of gadget searching like this in the future. So I'm going to go ahead and start studying up on all this and try to be ready for that shift in the industry.
Johan Carlsson (52:13.135)
Yeah.
Justin Gardner (@rhynorater) (52:19.8)
a great thing for the community that a lot of your reports are disclosed on GitLab and then you're doing interviews like this where we can kind of talk through the mentality because otherwise trying to get good examples on how to find these gadgets and that sort of thing would be really tricky. Not going to lie though, I'm a little sad. There's not like some, yeah, just go to the console and run this and it lists every single listener for this specific thing.
Johan Carlsson (52:36.112)
Yeah.
Johan Carlsson (52:44.31)
Hehehehehehe
Johan Carlsson (52:49.83)
I mean, I think if, if I were, I, so this is probably one of my problems as that I have with my, like when I do my hunting is that I'm very unstructured and on like I, there's probably like some really good ways if you could like sit down and just figure out what to grab for or whatever, but I'm, I really don't do that. So I'm just like reading it again and again and just coming back to the source code and
Justin Gardner (@rhynorater) (52:50.115)
But.
Justin Gardner (@rhynorater) (53:01.544)
Mm.
Justin Gardner (@rhynorater) (53:11.316)
Mm.
Justin Gardner (@rhynorater) (53:14.492)
You know...
Johan Carlsson (53:19.707)
And yeah.
Justin Gardner (@rhynorater) (53:21.052)
Hey man, that approach always, you know, that approach works well in the beginning when we're sort of developing this mentality and it gets you through the first, you know, however many. I'll shout out Matan Bear here, because I know he also does a bunch of really interesting client-side stuff, and he's shown me some things that you can put into the dev console that will list a bunch of really useful listeners and that sort of thing, so.
Johan Carlsson (53:44.235)
Hmm.
Justin Gardner (@rhynorater) (53:47.048)
I don't have permission to disclose it yet, but I know he's listening to this episode. So Matan, go ahead and figure out a way to do this. List all of these CSS selectors or whatever in the source code and then we can sort of find some more gadgets like this, because it's really, really interesting stuff here. All right, so that was, shit, Johan, that was the first bug. We haven't done anything yet. Tell you what, let's move.
Johan Carlsson (54:08.598)
Hehehehe
Joel Margolis (teknogeek) (54:11.603)
off.
Justin Gardner (@rhynorater) (54:16.228)
Let's move a little bit. I see why your reports are so long. That was one of the things we were going to talk about later on in your full-time bug bounty struggles or whatever. But I'm starting to see why this is happening. Tell you what, let's go into this pipeline bug, and let's keep this one a little bit more brief so that we can get access to some of the other goodies that lay on the other side of the technical content this time around, OK?
Johan Carlsson (54:35.054)
Mm-hmm. Yeah.
Johan Carlsson (54:43.742)
Yeah. And I mean, so this is more the pipeline. This is actually my, it's my only critical finding on the GitLab. So I'm also really proud of it. Like it was one of my, one of my things on my to-do list to finally find like one critical after spending, I guess I had spent two years when I found it or something like that. And it's, it's kind of represents the other part of my, my hunting.
Justin Gardner (@rhynorater) (54:51.909)
Mmm.
Justin Gardner (@rhynorater) (54:55.282)
Awesome.
Justin Gardner (@rhynorater) (55:05.01)
Mm.
Johan Carlsson (55:13.11)
which is not based on like technical things in the browser or like knowledge about HTML or whatever. It's like a just business logic application bug. So, and it's also, it showcases like how I kind of work in GitLab. So I saw this report.
Justin Gardner (@rhynorater) (55:28.743)
Mm, mm.
Johan Carlsson (55:37.462)
I have seen a lot of reports like reading through when people have been able to like trigger pipelines in GitLab as other users. And I have read them and they have always been like a medium impact. And I have been like researching like there must be something you can do with this that it's like higher impact than this medium. Like they all... Yeah, I mean, but so what you usually can do like what people have shown as a POC is that you can like...
Justin Gardner (@rhynorater) (55:57.128)
That seems a little off.
Johan Carlsson (56:05.782)
download source code from other repositories with this like if you trigger it as a victim you can download their like maybe a private repo or something and that's it has a high impact but it they are staying really strict to their like CSP no CVSS score yeah so and if you don't find a way to like escalate it from only reading stuff it will not get higher than medium so that's sort of it yeah
Justin Gardner (@rhynorater) (56:15.218)
Mm-hmm.
Justin Gardner (@rhynorater) (56:24.533)
Mm, CVSS delegation, mm.
Justin Gardner (@rhynorater) (56:32.016)
Just confidentiality high. Okay.
Johan Carlsson (56:35.294)
Um, but so, so I had this dream of like one day be able to run the pipeline as an arbitrary user, because I thought that I could do something better with it. Uh, and I was lucky to see one of these fixes going out for, uh, this guy. Now I, I forgot to look up the name of him, but this other person found a bug where you can do this. And I found a bypass to it. Uh, and so this is again, like sort of like where I.
Justin Gardner (@rhynorater) (56:44.22)
Yeah, yeah.
Johan Carlsson (57:02.902)
feel most comfortable and like where I shine is when I get some sort of like foothold and I start to escalate it and like show impact then when I when I feel like it's getting really fun
Justin Gardner (@rhynorater) (57:15.244)
We talk about this from the perspective of an exploitationist essentially. Like I think your expertise here is as an exploitationist, somebody who can take a little, just a little something that's a little bit off, and turn it into some big, huge thing, right? Versus somebody who, I don't have a specific name for it yet, but somebody who finds that initial.
a foothold. It's a little bit more recon centric a lot of time, not even necessarily in the traditional sense of recon, like we're scanning assets, running port scans or whatever, but somebody who spends time fingerprinting the whole application and understanding how all these different pieces come together and finds that one little piece that's a little bit off and then you can either hand it off to somebody who's a talented exploitationist or try to attempt that exploitation yourself.
Johan Carlsson (57:42.678)
Yeah, definitely.
Justin Gardner (@rhynorater) (58:06.46)
But I think just in an attempt to frameworkize that whole, you know, the different roles of hacking, I think those two roles are pretty clear and they're pretty different from each other too. Just because you can find a lot of, you know, footholds doesn't mean you can always take it the full distance. So it's cool to see a very talented exploitationist here. Hmm.
Johan Carlsson (58:26.348)
No.
Johan Carlsson (58:31.082)
Yeah, so what I had seen in the documentation, so it's also like just in the documentation, I had seen that if you trigger a pipeline, it will run as the user who triggered the pipeline. So that's all fine. It will run in the, so I could only do it, I ran the pipeline as another user, but in my project. But the...
Justin Gardner (@rhynorater) (58:37.084)
Mm-hmm.
Justin Gardner (@rhynorater) (58:49.872)
Can you give a explanation to what a pipeline is in this context?
Johan Carlsson (58:53.574)
Oh yeah, so a CI, CD-like pipeline, which is whenever you push something to a code base or whatever in GitHub or GitLab, it will more often than not trigger a pipeline, which it will build and run some tests and whatnot in a separate environment, like in one of these runners, which are like a sandboxed environment somewhere. But it will also have access to a lot of like environment variables and stuff like that, which is interesting to get access to. But so the...
Justin Gardner (@rhynorater) (59:06.996)
Sure. OK.
Justin Gardner (@rhynorater) (59:20.466)
Mm-hmm.
Johan Carlsson (59:23.482)
The initial bug here is that you can run like another user, but it's only in your project. So you already have access to everything in the project. So it's not that impactful. But then you can also read some of the victims like projects. But this thing that people hadn't really utilized before is that it was like in the end of the documentation for this functionality, it said that you could also trigger like down words, pipelines or whatever like
creating a chain of pipelines through different projects. So you could like from your from this pipeline, you can trigger another pipeline in another project. And this is actually kind of locked down now. So they have fixed like the main issue with that. But at this time you could
Justin Gardner (@rhynorater) (59:55.872)
Ah, interesting, okay.
Joel Margolis (teknogeek) (01:00:08.19)
Would you have control over those contexts or would it just trigger it?
Johan Carlsson (01:00:12.074)
So it will just trigger it in like you could sort of target the branch, I guess. Like you want to do it in the main branch if the user have access there. But what you could do, so this is also like not super impactful at that time. So that's maybe why they haven't really cared about it before. But I also went deeper in the documentation. It also said like, yeah, you can also specify some variables to overwrite.
when you do this new trigger you could add variables and you can also overwrite variables that are already present in this other project. So then I started to look for a gadget where this could lead to... because if you just trigger the pipeline you have no control of what's happening, you cannot leak anything more or whatever. But if you can overwrite some variables that potentially that variable is used in like a curl command or whatever and you can like...
start leaking stuff. So that was my, like the first impact I had there was that I could add, I found one template. So when you build the CI pipeline in these places, you often use like a bunch of different small CI stuff. And some of them are from templates that like GitLab provides that are like helping you with like code quality. So that was the final one that I found that a lot of people use is that like
Justin Gardner (@rhynorater) (01:01:39.206)
We're gonna increase the code quality a lot here in a second, I can feel it.
Johan Carlsson (01:01:41.731)
Yeah, yeah, yeah. So that one especially was like, they were doing, so let's see. Okay, no, so this one was actually doing like secret detection. So that's good. This was actually trying to detect secrets. That's great. But this one was actually, you could specify, they are specifying the image. So like the docker image that the...
Justin Gardner (@rhynorater) (01:01:59.518)
Nice.
Johan Carlsson (01:02:09.218)
the pipeline is going to use, that is specified through variables. Yeah, just to say like, so whenever you trigger pipeline, it will find the Docker image to use like as the base for that pipeline run. And so here I could inject whatever, I could target it to like one of my own Docker images, and so that makes it possible to me to do like, I could run whatever code I want now. So I have like...
Justin Gardner (@rhynorater) (01:02:13.424)
to detect the, okay, I see.
Justin Gardner (@rhynorater) (01:02:33.169)
Okay.
Johan Carlsson (01:02:37.838)
RCE essentially, but in this kind of like pipeline environment. But still that makes it possible for me to do a lot more than just like trigger the pipeline. I can now control the output of this pipeline and I can also read all the variables and everything. And then just to the sort of final step for me to prove to GitLab that this was a critical was to just read through their own discussions and I found this mention of
Justin Gardner (@rhynorater) (01:02:41.585)
in the runner. Okay.
Johan Carlsson (01:03:07.05)
So GitLab in their pipeline, they have a variable that contains a real access token that they use to do like more like sensitive stuff. And I just saw that they mentioned it in a bunch of places. I, my report essentially was like, I made this mocked up version of this and I sent it and then I said like, I'm pretty, I'm pretty certain that I can do this to your environment right now and I can get this token and...
Justin Gardner (@rhynorater) (01:03:14.897)
Mmm.
Justin Gardner (@rhynorater) (01:03:33.588)
Dude, you didn't even do it in prod?
Johan Carlsson (01:03:35.762)
No, no, no. No, I didn't, I didn't. I didn't.
Justin Gardner (@rhynorater) (01:03:37.468)
Oh man, see this is where like, yeah, you know, I don't know, yeah, no that makes sense though, yeah, you want to try to respect that and stuff.
Joel Margolis (teknogeek) (01:03:39.61)
That's the best place to test stuff, you know, I don't know.
Johan Carlsson (01:03:47.058)
No, but I did actually like, usually I let things like take its time, but this time I actually reached out to some of the security people on Twitter. So this was of course on a Friday. So I just reached out to them and said like, I think that this is bad. And then they jumped on it directly and on Monday they had the patch out. So that was
Justin Gardner (@rhynorater) (01:03:59.906)
Oh no.
Justin Gardner (@rhynorater) (01:04:09.256)
Well, it makes sense, you know, you've got a team like GitLab, you know, with a highly reputable team, and so to be able to not necessarily take that all the way and do it in prod and hand them their access token, you know, you still have a decent amount of trust that they're going to not do you wrong for that.
Johan Carlsson (01:04:28.675)
I did actually, I did like, I forked GitLab of course. So I had like a really similar environment so I can prove that it worked. So it was, yeah. So it was, my POC was like really similar to the real...
Justin Gardner (@rhynorater) (01:04:32.424)
Mm-hmm. Okay, all right.
Justin Gardner (@rhynorater) (01:04:37.463)
That's good.
Joel Margolis (teknogeek) (01:04:43.15)
And for sure, I think like, it'd be very rare to have a program where you have something like this, where you say, I've decided to stop and I'm telling it to you now, I'm pretty sure this does this, but I want you to check it versus going ahead and doing it and then having them to like, have to deal with that aftermath. I've heard of plenty of examples of hackers where that has not gone great. Um, so.
Johan Carlsson (01:05:02.044)
I am.
Yeah, and I have no idea what happens if I trigger a pipeline, maybe because it could also trigger like a deploy or whatever and like so it's like yeah. Yeah, yeah. So in my report I targeted like the GitLab's main. So yeah, so I had no idea like what would happen if I did it. So I just wanted to prove to them that I have all the pieces.
Justin Gardner (@rhynorater) (01:05:12.86)
Oh, okay, that makes a lot more sense now. Oh, you're talking about the get... Oh, I see. Holy crap. Ha ha ha.
Justin Gardner (@rhynorater) (01:05:25.688)
Okay, that makes a lot of sense.
Johan Carlsson (01:05:33.67)
actually run this now in the GitLab main repo and get access to this.
Justin Gardner (@rhynorater) (01:05:38.548)
So wait a second, potentially if you had leaked this token and have access to these repos now, right access, you could have backdoored the GitLab code base. Is that accurate? Ho ho ho. That is nasty dude, that would have been so bad. I see why you didn't do it. Ha ha ha.
Johan Carlsson (01:05:50.43)
Yeah. So, yeah, yeah. So that's the.
Johan Carlsson (01:05:59.766)
So that's a... Nah. No, but it was a... Again, it proves that you, if you spend the time escalating something, you can make it, like you can actually prove that it is as bad as you, you as like a hunter believes. A lot of times when you stop earlier, they might not agree with you. But if you build this scenario that is very plausible, I think it's easier to get it through triage and everything.
Justin Gardner (@rhynorater) (01:06:14.684)
Mm.
Justin Gardner (@rhynorater) (01:06:29.817)
Very good. Okay, so let me just sort of summarize this one really quick to get through it. So first of all, you're triggering this pipeline as any user because of a, I guess this is a pipeline on your own repo because of the fallback thing, is that right?
Johan Carlsson (01:06:44.991)
Yeah.
Yeah, so that... Exactly, so there was this functionality that I sort of like built upon from this earlier report where you sort of ran some sort of... Just like maintenance thingy. It's some functionality that was broken.
Justin Gardner (@rhynorater) (01:06:55.41)
Mm.
Justin Gardner (@rhynorater) (01:07:04.136)
Mm. Okay. And so you're able to build upon that functionality. You're able to spoof the latest committer. So now you can say, okay, somebody committed to this repo and now I'm gonna delete the bot or whatever and have it fall back to that user, run the pipeline and then exfil that token which is associated with an arbitrary user. Then you're using that token.
to trigger a different pipeline via this downstream pipeline feature that you found about in the documentation. And that will trigger a pipeline with a specific set of variables that you provide from your malicious pipeline. And then using that, you find a gadget that allows you to specify an arbitrary Docker file or a Docker repo or a Docker image. There you go. That's the one. I was like, I know there's a word for this. A Docker image.
Johan Carlsson (01:07:56.822)
Yeah, Docker image.
Justin Gardner (@rhynorater) (01:08:01.904)
And that Docker image gets pulled into the runner, executed, so now you've got code execution inside the CI pipeline on this specific repo, and then you can exfiltrate access tokens.
Johan Carlsson (01:08:11.626)
Yeah. Yes. So I sort of like skipped over the initial part there that you mentioned, but yeah, it's... No, it was... It was fun. Actually, like, I think it's the only time when I actually like properly celebrated afterwards. Like I went out and like bought some flowers for my wife.
Justin Gardner (@rhynorater) (01:08:16.657)
Oh
Joel Margolis (teknogeek) (01:08:18.334)
That's a sick bug.
Justin Gardner (@rhynorater) (01:08:21.852)
Wow.
Justin Gardner (@rhynorater) (01:08:31.196)
Yeah!
Justin Gardner (@rhynorater) (01:08:35.208)
There you go, dude. See, that's great. And that's actually perfect transition there, Johan, because we can move into the full-time Bug Bounty conversation with that as well. And one of the things that Mariah and I do, and something that I've been kind of public about on the pod because I think it's a really good practice in Bug Bounty, is doing a proper celebration when you crush something. And so, yeah, it's good to see that you've actually pulled that off, and it's sweet to say that you...
Johan Carlsson (01:09:01.757)
I've done it once.
Justin Gardner (@rhynorater) (01:09:03.728)
went and bought some flowers as your celebration versus like mine of like buying a hot tub or something like that. So do you have other... yeah go ahead.
Johan Carlsson (01:09:15.83)
I mean most of the time I'm pretty bad at celebrating. It's more like I get this feeling of like if I get frustrated when I fail and when I succeed I'm just like okay like did it move on and so usually I don't get that in that celebration mode.
Justin Gardner (@rhynorater) (01:09:20.401)
Mm.
Justin Gardner (@rhynorater) (01:09:30.47)
Mm.
Johan Carlsson (01:09:38.814)
Unfortunately, I should do that more often as well.
Justin Gardner (@rhynorater) (01:09:40.496)
Yeah, absolutely, I would definitely recommend that. And when you said, often failing, it actually reminded me of something I wanted to ask you about, the CSP bugs. These gadgets that we talked about, right, the script gadgets, would you say that they are often there? Like, is this something that often exists? Like, when you're presented with a foothold and you need to bypass these CSPs.
In the complexity of this modern era's JavaScript frameworks and everything that gets bundled into a page, would you say these gadgets that affect specific classes or specific data attributes, would you say that they're often in place that allow you to do what you need to do?
Johan Carlsson (01:10:22.03)
I think that they are probably way more common in like big complex applications. Uh, so, but I would say like, they're probably, they probably exist in all of these, the big things that you look at. Uh, and, uh, and, but I mean, so like coming from like a dev, uh, background like myself, I know that, so when you're working with these like frameworks, like even with react.
Justin Gardner (@rhynorater) (01:10:27.964)
Okay.
Justin Gardner (@rhynorater) (01:10:37.964)
Wow, dude, I wonder how many good HTML injections I've just let to the side.
Johan Carlsson (01:10:51.27)
or in GitLab's case, they use the view. And sometimes you just have this one piece of functionality that doesn't really, it's too hard to shoehorn down in this framework and you just make some quick custom JavaScript on the side that deals with some error or some pop-up or you're gonna have, so one of the ones I found on GitLab was like this. They just wanted to show some.
Justin Gardner (@rhynorater) (01:11:10.845)
Mm-hmm.
Johan Carlsson (01:11:19.69)
like we're doing this new feature popup thing. And you have to get that out like really quickly and like building it correctly might take a lot of time and you can just like, yeah, just script it together. So definitely like have a look in these like special JS like the utility folders where they store their like custom code because that's what's breaking. Like it's...
Justin Gardner (@rhynorater) (01:11:29.288)
Some junior dev pushed this through or something like that, yeah.
Justin Gardner (@rhynorater) (01:11:41.969)
Interesting.
Johan Carlsson (01:11:47.862)
way harder to get into like in react or whatever you there you know where you to look for you have to look for this like dangerously set in inner html or whatever it's called yeah
Justin Gardner (@rhynorater) (01:12:01.416)
Very cool, very cool stuff. All right, I'm gonna actually, I've been drinking too much water and now I've gotta hit the bathroom. So I'm gonna go ahead and put a little pause in here at, what is it, 112? Okay, great. So we'll take like a couple minute recess and then we'll jump into the bug bounty stuff, or the full-time bug bounty stuff, okay? Bathroom, bathroom break, I'm putting that in the doc. All right, be right back.
Joel Margolis (teknogeek) (01:12:14.782)
Well that's good timing bro, cause me too.
Johan Carlsson (01:12:17.614)
Ha ha ha.
Johan Carlsson (01:12:24.59)
Cool. Ha ha ha.
Johan Carlsson (01:14:52.558)
So what time is it at your... Are you just starting me? Alright. So are you working today or are you just...
Joel Margolis (teknogeek) (01:14:56.062)
It's 11.30 in the morning.
Joel Margolis (teknogeek) (01:15:01.47)
I am working, I'm working right on this screen here underneath. You can't see it.
Johan Carlsson (01:15:05.622)
Okay. Doing a stand up.
Joel Margolis (teknogeek) (01:15:11.77)
Yeah, yeah, no kidding. No, thankfully I have very, almost no meetings on Mondays usually. So it's mostly just responding to emails and doing a lot of procedural stuff.
Justin Gardner (@rhynorater) (01:15:36.221)
Alrighty, let me note the end of this rough end of this bathroom break. Julie, you ready to roll?
Joel Margolis (teknogeek) (01:15:44.347)
Yessir.
Justin Gardner (@rhynorater) (01:15:55.025)
I'm gonna give you 321, I guess. 321, boom. All right, so I got us a little bit off track there, jumping back into the scripting stuff. But let's move now, I guess, a little bit more into the full-time bug bounty stuff. So you've been doing it now for like, what, two months? Two months, all right. How you feeling, man? Do you love it? Is it amazing? Is it everything you ever wanted it to be?
Johan Carlsson (01:15:58.574)
I'm going to go to bed.
Johan Carlsson (01:16:03.779)
Ha ha.
Johan Carlsson (01:16:15.618)
Two months, yeah.
Johan Carlsson (01:16:24.354)
It's really strange. It's great in some ways. So like background is like I decided to take to ask my job essentially for three months like unpaid leave just to try this out. And they were like they were kind enough I can say. But it's also like.
Justin Gardner (@rhynorater) (01:16:38.993)
Yeah.
Johan Carlsson (01:16:47.29)
in Sweden you actually are allowed to do like up to six months of unpaid leave to try to start a company thing sort of thing yeah so i don't think they could see no but anyhow so i yeah so the main goal has been to see if like spending full time on this like would it give me like a lot of like would it
Justin Gardner (@rhynorater) (01:16:54.864)
Really? Okay, that's cool.
Joel Margolis (teknogeek) (01:16:56.094)
Very interesting.
Johan Carlsson (01:17:15.014)
enhance my experience of bug bounties, like money, but also...
Justin Gardner (@rhynorater) (01:17:16.868)
Money? Would it give me a lot of money? Would it enhance my money?
Joel Margolis (teknogeek) (01:17:23.814)
Is this a plausible way to survive?
Johan Carlsson (01:17:26.798)
Yeah... No... No, but... Both... Would I find it... Because I find it really interesting and I spend a lot of time on it but usually in my regular work environment I do my full time work and then I come home and I take care of my family and then I spend two hours at night doing this and I don't
Justin Gardner (@rhynorater) (01:17:27.5)
Sorry, I'm sorry, go ahead. Would it give you a lot of, or would it enhance what? Mm-mm.
Justin Gardner (@rhynorater) (01:17:38.385)
Mm-hmm.
Justin Gardner (@rhynorater) (01:17:41.713)
Mm-hmm.
Mm-hmm.
Johan Carlsson (01:17:56.534)
So this is also like, can I get back some free time and can I still be successful? Can I feel like not stressed about it? And like all of those. So that was kind of my idea. Yeah.
Justin Gardner (@rhynorater) (01:18:05.968)
Yeah, those are the questions that that's that you actually just read off the list of questions that I had for you there. And I will say like, you know, you mentioned your family and I've got some family expansions that have happened recently. And one of the things that I've been really grateful for inside of that environment, you know, when family is taking up more time and more, you know, investment and that sort of thing, which is great. And I love that during the day, I do have control of that.
of control of my things that I'm looking at. I can look at things that I think are interesting, whereas before when I was single, it was like, okay, I could do my day job, and then I'd have a couple hours, or more than a couple hours, a decent amount of time afterwards where I could dive into these things that I'm more interested in. And I think as your family grows and as your responsibilities to your family get bigger and bigger, that time sort of shrinks, and it becomes more...
Johan Carlsson (01:18:37.134)
Hmm.
Justin Gardner (@rhynorater) (01:18:59.872)
awesome to be able to do bug bounty full time because you can dive deep into something you're interested in during your work hours.
Johan Carlsson (01:19:06.594)
Yeah. And I mean, I've been listening to like all the pods and stuff that exists with these people who are doing it full time and like giving tips and tricks. And so just to, to preface this as well, like I, I made sure to, so I have my company now where I get my bounties too. And I had like more than enough to pay for like my salary and everything for these three months, like from starting out. So I would survive like without doing this. So.
Justin Gardner (@rhynorater) (01:19:23.036)
Mm-hmm.
Johan Carlsson (01:19:34.35)
And that's one of the things that you have to consider when you have a family as well. I have to pay my mortgage and all of that stuff.
Justin Gardner (@rhynorater) (01:19:40.66)
Mm-hmm. So you set that up, you've got that in place, and then you're feeling pretty confident going into this three months of like, all right, either way, I'm gonna be able to pay myself, so the bills are gonna be paid, and then worse comes to worse, I can just go back to this company after three months and resume my normal life.
Johan Carlsson (01:19:52.909)
Sweet food.
Johan Carlsson (01:19:57.138)
Yeah. So what I, what I could lose is my self-confidence. If I would not find anything for three months, like doing this full time, that would be hard. So I was a bit nervous in the beginning because I had like, I hadn't done like anything for January and I started doing some stuff in February, leading up to March then when I was going to start. So I was a bit nervous that I had like my pipeline was empty and everything. So yeah.
Justin Gardner (@rhynorater) (01:20:24.392)
That is tricky, yeah.
Johan Carlsson (01:20:27.358)
But so far it's been... I'm surprised that I'm still like in lack of time. I got so much more time now, but I don't know what I spent it on. It's just like still like the day just passes so quickly and I still only have like my work hours. Like I leave my kids at school and preschool at...
Justin Gardner (@rhynorater) (01:20:35.502)
Hahaha!
Johan Carlsson (01:20:51.742)
8 in the morning and then I get back and I start working and I'm like four or five they come back so then it's like then it's over and then maybe I do some things later in the evening as well but I've been trying to also like do more of like the home like the shores and stuff at home so I haven't been working eight hours a day maybe like six hours or something like that.
Justin Gardner (@rhynorater) (01:21:05.318)
Nice.
Justin Gardner (@rhynorater) (01:21:13.628)
Right, right.
Justin Gardner (@rhynorater) (01:21:19.281)
Yeah, and so in that six hours, you're focusing on primarily GitLab, or have you switched around targets much? Are you deep diving one target? Or?
Johan Carlsson (01:21:27.638)
Yeah, so I had I have my like a couple of goals that I wrote up like on this blog post that I never posted from when I started. Yeah, yes, I listed some stuff like the number one like get organized notes, automation, templates, scripts, like all of that stuff.
Justin Gardner (@rhynorater) (01:21:36.696)
Okay, that's the kind of stuff we love to get into here on the pod. Tell me about this blog post you never posted.
Johan Carlsson (01:21:53.51)
And then like deep dive one or two targets like new targets write three blog posts and apply for a talk like a owasp talk or like whatever And I decided on these like four things because I wanted it to be like even if I don't find anything There should be like an a tangible like outcome at the end But I have failed with like most of these ones
Justin Gardner (@rhynorater) (01:22:03.942)
Nice.
Justin Gardner (@rhynorater) (01:22:22.001)
I love the first one is like get or like at what every bug hunter says they're gonna do They're like I'm gonna have this automation and this automation is gonna be like finding all these bugs And I'm just gonna be like writing my notes and got my whole like API documentation built out. No, no, it doesn't work
Johan Carlsson (01:22:22.026)
because I've been... Yeah, yeah.
Johan Carlsson (01:22:29.576)
Yeah.
Johan Carlsson (01:22:36.514)
I mean I spent so much time like going through my like 200 chrome tabs 200 visual studio code like unsaved documents that I just create like on the fly like posting so yeah Like just trying So I've been trying hard to get more organized, but I'm yeah, I really failed at it
Justin Gardner (@rhynorater) (01:22:48.396)
Yeah, astiff.txt, yeah.
Justin Gardner (@rhynorater) (01:23:00.332)
This is also one of the things I've been talking to the Kaido team about as well is like, I think one of the niches where Kaido could really shine is this whole concept of organization within your sort of hacking. And I think there's a couple ways that you could go about it. Obviously we need notes and stuff like that inside of that environment. But auto naming, you know, tabs.
Trying to keep stuff unified and in one place and assisting very cognizantly with organization could be, I think, a really big niche for tooling in this industry, because everyone struggles with that same thing that you just mentioned.
Johan Carlsson (01:23:39.15)
Yeah. And I mean, as you have seen, like when I've read some of my write-up, or like it's not even write-ups, it's bug reports. Like I spend so much time, like I had this day, like a Monday, two weeks, or one week ago, maybe I spent the whole day writing two reports. Like my, all the, my six hours went into that. And, and so that's, I cannot understand these people who are just like,
Justin Gardner (@rhynorater) (01:23:50.507)
Mm-hmm.
Justin Gardner (@rhynorater) (01:24:01.348)
Oh my goodness, dude.
Johan Carlsson (01:24:07.858)
Just reported that and move on.
Justin Gardner (@rhynorater) (01:24:09.72)
That's me, so let's talk through that. But before we get to that, I wanna go back and look at your goals. So, you know, getting tools, automation, you know, organized, that's everyone's goal in the beginning. Makes sense as that one sort of fell off the horse. Deep diving a couple targets. What targets did you pick and how is that going?
Johan Carlsson (01:24:24.278)
Yeah.
Johan Carlsson (01:24:28.778)
So that's not going that well. I can, I picked GitLab. Yeah. So I'm still happy with what I've been doing. So I've had like two main tracks. One has been like deep diving some stuff in GitLab and, but then I also have had this like where I've been deep diving a topic and applying that more broadly across like a couple of programs. So I had one week when I.
Justin Gardner (@rhynorater) (01:24:34.143)
Surprise, surprise.
Justin Gardner (@rhynorater) (01:24:52.008)
Mmm.
Justin Gardner (@rhynorater) (01:24:55.197)
Okay.
Johan Carlsson (01:24:58.658)
tried to learn everything I could about this AI chat attacks. And then I just went to because that's everywhere now. So you just go everywhere and you try it. And I try to focus on like big public programs because I don't, I don't know. The private invites things. Those are really not for me because I don't get any good ones I feel. Like the big public ones are better.
Justin Gardner (@rhynorater) (01:25:02.984)
Mmm.
Justin Gardner (@rhynorater) (01:25:22.804)
Haha, oh, we gotta fix that man, we gotta fix that. Okay, solid.
Johan Carlsson (01:25:27.378)
I mean the big public ones are like they pay a lot and they are usually like very like well oiled So and everyone has this like chat thing So I then I just like jumped around on all these programs like tried it out and like tried to understand So those I did like three of these weeks in the beginning like when I just focused on one Type of bug and really tried to like deep dive in that
Justin Gardner (@rhynorater) (01:25:35.629)
That's true.
Johan Carlsson (01:25:56.83)
And that was like a really amazing experience. Like having the time to spend like five days doing that instead of just like two hours here and there. Yeah, that was great. Yeah.
Justin Gardner (@rhynorater) (01:26:01.721)
Nice dude.
Justin Gardner (@rhynorater) (01:26:07.528)
Yeah, you can make so much more progress when you put this time into this. And this is something we talk about as well a lot in Bug Bounty is like this whole concept of like, yeah, you know, a lot of people wanna do this two hours, you know, at the night or on the weekends or something like that when they've got time and they get frustrated when they don't see success. And I think it takes time to be able to do it in two hours on the weekend and it takes time to be able to do it, you know, part time.
Johan Carlsson (01:26:30.848)
No.
Justin Gardner (@rhynorater) (01:26:34.292)
and to get to that point. And it's possible 100% to do it, just like you mentioned, but there's a lot of buildup that comes up to that because your progress is so much slower when you're not able to devote eight hours into deep diving a topic.
Johan Carlsson (01:26:45.206)
Yeah.
Johan Carlsson (01:26:48.754)
So I kind of I had this idea in my head when starting this that I would become this like the hacker You know like opening up a burp or kaido and just like going to new fresh target and like looking at the requests and like Finding these kind of issues there But as it turns out like that's probably not who I am. So I just ended up like looking at this like super niche So the first week I spent on this bug type like read-dos
Justin Gardner (@rhynorater) (01:27:01.666)
Mm-hmm.
Johan Carlsson (01:27:17.098)
like reg ex dos thing. So that's one of my first payouts now. They have fixed it in GitLab. It's actually a high severity bug in the latest release. So that was really nice.
Justin Gardner (@rhynorater) (01:27:18.256)
Regex DOS, all right, very nice.
Justin Gardner (@rhynorater) (01:27:32.444)
Yeah, I actually know somebody else who also goes after Redos in GitLab. It seems to be like a pretty common problem in that environment. Yeah.
Johan Carlsson (01:27:43.654)
Unfortunately they have patched it at the language level. So right after my week of deep diving they actually put it out of scope, because they will fix it after the summer. So now the glory days of readers and... Yeah, Ruby.
Justin Gardner (@rhynorater) (01:27:46.781)
They clean it up.
Justin Gardner (@rhynorater) (01:27:51.022)
Oh, okay.
Justin Gardner (@rhynorater) (01:28:00.7)
Wow.
And that's Ruby then or is that Ruby? Okay, so Ruby's regular expression library is fixing it.
Johan Carlsson (01:28:10.346)
Yeah, their engine has... they fixed the big issues with it and they also put in like a timer that you can set because there are still ways to get it to DOS, but they also have this like timer option now so you can say like anything that runs more than like a minute just kill the process and then it's sort of impossible to get through it.
Justin Gardner (@rhynorater) (01:28:19.965)
Mm-hmm.
Justin Gardner (@rhynorater) (01:28:32.148)
Gotcha, okay, so you deep dive that, and it's possible in some languages, but maybe not as much in Ruby. And you did the chat bugs, did you find anything cool there worth sharing? I know we discussed it a little bit before, and it's a little bit shallow at this point, but.
Johan Carlsson (01:28:34.574)
Hahaha
Johan Carlsson (01:28:39.39)
No, but it was still fun and it's also good.
Johan Carlsson (01:28:52.491)
Yeah, I mean, so that was kind of what I what I found out about it is that it's actually pretty hard to find any like CVSS like to increase it from like a low medium sort of like you if the you have to find programs where they actually integrate these toolings as you kind of did with the Google thing or whatever that was the Bard.
Justin Gardner (@rhynorater) (01:29:07.292)
Mm.
Johan Carlsson (01:29:19.706)
uh... chat thingy.
Joel Margolis (teknogeek) (01:29:19.938)
Yeah. Cause I think a lot of the stuff with AI is just like, it's only as powerful as they let it be. Right. So like it doesn't, it doesn't integrate itself in terms of like, make like you to, I want to do this thing. And it doesn't just like magically know how to do that. Right. An engineer has to say, okay, if they want to do this thing, then, you know, do XYZ on the back end, like make this API call or whatever. And so it has to be integrated to some level, like a technical, right, right. There, it doesn't have its own agency. So you have to find those areas where.
Johan Carlsson (01:29:25.556)
Yeah.
Johan Carlsson (01:29:34.623)
No, exactly.
Johan Carlsson (01:29:41.078)
Yeah.
Justin Gardner (@rhynorater) (01:29:42.949)
agency.
Justin Gardner (@rhynorater) (01:29:46.631)
Mm.
Johan Carlsson (01:29:49.49)
Yeah, definitely. And I think it's valuable to look into because it's probably just gonna get worse before it gets better, like when everyone just integrates more and more stuff into it. So it was interesting, but yeah, it wasn't that, from what I could tell now, I didn't find that much super interesting functionality with it. It's fun to play with, trying to trick this chat bot to...
Joel Margolis (teknogeek) (01:29:49.618)
where you do get some agency, right?
Justin Gardner (@rhynorater) (01:29:56.649)
Mm-hmm.
Justin Gardner (@rhynorater) (01:30:14.813)
Mm.
Justin Gardner (@rhynorater) (01:30:18.084)
Yeah, I think that's a common experience. To be honest, I think the biggest thing that's going to tell you whether there's going to be chat-related bugs is what features that whole chat thing has in the first place. Because if you're just chatting, it's like, OK, well, I can make you say some bad word or whatever, but the impact there is.
Johan Carlsson (01:30:19.03)
tell you stuff, but...
Johan Carlsson (01:30:39.544)
Yeah
Joel Margolis (teknogeek) (01:30:40.81)
It was like that car chatbot that was like, some guy was chatting with the car dealership and got the chatbot to say that, give him this crazy low payment deal or whatever on the car. And he was like, you guys have to uphold this now. Or something like that.
Johan Carlsson (01:30:52.537)
I don't know.
Johan Carlsson (01:30:56.534)
Ha ha ha.
Justin Gardner (@rhynorater) (01:30:56.888)
Yeah, that was pretty crazy precedent, to be perfectly honest. I was a little surprised to see that actually happen. But okay, so you did AI Chatbot, you did Redos, which is a cool category, and then you did OAuth as well, right? That one seems a little bit more juicy.
Johan Carlsson (01:31:11.666)
Yeah, and that's just like, yeah, that's sort of compared to the AI stuff, like OAuth is like the gift that keeps on giving. Like every time you, every time you look into it, you find some new like edge case that.
Justin Gardner (@rhynorater) (01:31:21.801)
It really is, man. Yeah, right?
Joel Margolis (teknogeek) (01:31:22.898)
The curse that keeps on giving.
Johan Carlsson (01:31:33.154)
that you can dig into. And then you always have to go back to this France, Rose and Dirty Dancing thing and you find some new edge case in there as well. And that was also like, yeah, definitely. And that was also like jumping around between different programs. So I actually found some fun bugs that I cannot really disclose.
Justin Gardner (@rhynorater) (01:31:45.756)
Mm-hmm.
Very formative research there, yeah.
Johan Carlsson (01:32:00.582)
And that's on other programs than GitLab. So that are also like public programs.
Justin Gardner (@rhynorater) (01:32:04.36)
Very nice. How are you feeling at this point about income and the day-to-day life of full-time buck bounty? Are you enjoying it? Are you stressed? Is the income there? How's it going?
Johan Carlsson (01:32:18.738)
So I have a problem that I target programs that are pretty slow. They have a good reputation of paying when they have finally fixed it. But even GitLab can take a couple of months before you get anything out of it. Because they pay some...
Justin Gardner (@rhynorater) (01:32:36.316)
If.
Johan Carlsson (01:32:45.854)
Sometimes at initial triage, but otherwise they pay when they fix it and it could take like two three months for maybe if it's a medium So I have this spreadsheet now when I have I have added like three tables like what I've gotten paid What I believe is like a minimum what I will get and a maximum what I will get and then I have this span now from like the what could be like the possible like
the best possible outcome and then I have this what maybe could end up.
Justin Gardner (@rhynorater) (01:33:18.928)
That sounds like a very wise way of doing it. I think this is one of the things that for me took a while in Bug Bounty because my normal flow is like, clickety clickety, I'm hacking stuff. Oh, I got it, I popped it and then I get up and I run into the other room and I tell Mariah, I'm like, I just popped out a 100K bug and she's like, okay, just chill out here, okay. Don't count your eggs before they're in the basket or something, I forget. So she's got some saying she always says like that.
Johan Carlsson (01:33:36.834)
Yeah.
Justin Gardner (@rhynorater) (01:33:48.236)
But it's wise because at the end of the day, like you don't know how it's gonna turn out. You know, there could be mitigating factors that you're unaware of, that sort of thing. And that can crush you, you know.
Johan Carlsson (01:33:59.322)
Yeah, I definitely try to not celebrate before they pay because sometimes even like a bug that is from in like triage state it can move to like a duplicate or whatever like whenever they defined.
Justin Gardner (@rhynorater) (01:34:09.915)
It can.
It can. Well, that's good. It seems like you've got some good healthy, you know, sort of heart-saving boundaries in place there. So you've got this sheet set up, and maybe most of your bugs haven't gotten paid out yet, but it's looking pretty good, though.
Johan Carlsson (01:34:21.076)
Yeah.
Johan Carlsson (01:34:29.394)
No, but I've had the... it's looking good. I've been able to pay my first two salaries, which is great. And that's... so no, it's looking good, definitely. I'm still... it's still hard for me to understand if this is like... if I could do this... if it will like continue trickling bugs.
Justin Gardner (@rhynorater) (01:34:38.396)
Yeah!
Johan Carlsson (01:34:58.85)
I'm still at this place where I feel like whenever I've submitted something, I kind of feel like this is the last bug I will ever find. I've become, yeah, it was worse before, so now I kind of feel like I will eventually find something new, but I don't really know when it will happen. But it also helps, so targeting, for example, GitLab, I don't have to find that many bugs on those kinds of programs to actually...
Justin Gardner (@rhynorater) (01:35:07.56)
Classic, classic stuff.
Johan Carlsson (01:35:27.65)
pay my whatever like my what my goal is so
Justin Gardner (@rhynorater) (01:35:29.576)
Mm, right. Yeah, it's good when you can sort of, it's helpful in the beginning when you can couple high paying programs with a lower budget. If you're able to control your expenditures for a little while, while you're building up that confidence and while you're building up that sum of money in your company account that will eventually pay out your salary. So I think that's a really.
Johan Carlsson (01:35:45.29)
Mm.
Justin Gardner (@rhynorater) (01:35:57.596)
wise way of approaching it and how I recommend most people start Bug Bounty full time as well is that sort of, you know, smaller amounts, you know, decrease the cost of living and get that freedom back where you can work on whatever you want every day and then kind of move from there. I wanted to ask this as well. Are you working at home? Do you work at your home environment? Do you work from like an office or a cafe or anything like that or?
Johan Carlsson (01:36:11.098)
Hmm.
Johan Carlsson (01:36:19.863)
Yeah.
Johan Carlsson (01:36:23.754)
I've been... so this is maybe something that will like get to me if I spend like if I do this more that I've been sitting at home a lot mostly because I don't like I... it takes too much time to get away somewhere and I have my equipment here and I have my screen and everything so I've been sitting mostly at home but I've also went some days to a cafe and that really helps to like clear your mind a bit yeah
Justin Gardner (@rhynorater) (01:36:32.445)
Mm.
Justin Gardner (@rhynorater) (01:36:40.232)
Mm-hmm.
Justin Gardner (@rhynorater) (01:36:43.462)
Mm-hmm.
Justin Gardner (@rhynorater) (01:36:51.332)
reset, right? I do a similar thing. It's like I got my home base. It's normally fine, but sometimes I gotta like shake it and get out and like freshen things up and then you can come back to it. And I think some people, they have to work at cafes or they have to work in these co-working environments. I just like, if I had to do that every day, that would be a really big inhibitor for me, I think. So.
Johan Carlsson (01:36:53.29)
Um...
Johan Carlsson (01:37:11.399)
No, but so that is what I have not found any problem with getting to work. It's more I have more issues with like structuring my time. So I kind of have this to do list for a day and I know that I have to do this like four things. I have to answer some.
Justin Gardner (@rhynorater) (01:37:18.183)
Mm.
Justin Gardner (@rhynorater) (01:37:22.963)
Mm.
Mm.
Johan Carlsson (01:37:30.67)
person on a report or whatever and then I tell myself like in the morning like but I if I just look a Little bit on this like don't purify bypass thing and then like three hours later. I'm just like, okay I have to do some work now. I just So that happens a lot like I'm very easily as you have maybe seen sometimes Nerd snipable as well. So I spend a lot of time doing stuff that is not really relevant
Justin Gardner (@rhynorater) (01:37:41.842)
Oh my gosh.
Justin Gardner (@rhynorater) (01:37:46.257)
Yeah, man. No.
Justin Gardner (@rhynorater) (01:37:55.444)
Pchoo!
Justin Gardner (@rhynorater) (01:37:59.996)
That's great. My favorite kind of hacker to collab with, a nerd-snipable hacker. It's good though, man, because you can deep dive the stuff that you're really interested in and you kind of get focused on that. So that is definitely a superpower in some capacity and a hindrance in others. But I'm excited to hear you say that you've been succeeding with it so far and it's been a fun experiment and hopefully the rest of those bugs will get paid out soon and you'll be feeling better about the results.
Joel Margolis (teknogeek) (01:38:00.286)
Ha!
Johan Carlsson (01:38:26.039)
Yeah.
Johan Carlsson (01:38:29.426)
I definitely feel like the biggest problem I've had has been like this separation of work and free time. Like when I go to my day job it's very like, even if I work from home it's very obvious that I do like this external work for someone else and then at a certain time I just like quit and I do whatever. Now it's been more like...
Justin Gardner (@rhynorater) (01:38:29.473)
that you can actually...
Justin Gardner (@rhynorater) (01:38:46.332)
Mm.
Johan Carlsson (01:38:54.034)
maybe, so like my wife asks me like, are you working now? Or like in the evening, like, are you working now or are you not? And then I say like, no, not really. I'm just like having some fun.
Justin Gardner (@rhynorater) (01:39:00.256)
Mm-hmm.
Joel Margolis (teknogeek) (01:39:04.242)
Yeah. And personally, I think I prefer that sort of stance on because unless you're doing very like singular work where like you can spend like dedicated chunks of time working on one thing, life doesn't really work that out a lot of the time. And so it's really, really difficult to just say like, oh, for this eight hours of the day, I'm just going to not do anything except for this one thing. Like, you know, stuff happens, stuff comes up and being able to be flexible in that sense is really
Justin Gardner (@rhynorater) (01:39:05.417)
Yeah
Justin Gardner (@rhynorater) (01:39:19.174)
Mm-hmm.
Johan Carlsson (01:39:26.602)
No, I'm excited.
Joel Margolis (teknogeek) (01:39:31.966)
where you can be like, oh, I need to go do this thing in the middle of the day. And then you come back and you sort of shift those hours around where you wouldn't maybe be working after 5 p.m. normally, but now you do because instead of, you know, working at noon, you were doing something else and so now you need to work later. And so, you know, like that, I think that flexibility is just nice to have the option, even if most of the time you do work normal hours, being able to shift stuff around and have that flexibility is super nice.
Justin Gardner (@rhynorater) (01:40:00.164)
It certainly is. And I've talked about this little sign on the, on the podcast before, but is it, can you, can you see it? Cause I'm like, put it, I'm just going to put it right in front of my face, but it says, it says, um, a Gyochu in Japanese and the backside it says take UB and these mean, you know, open for business and closed for business. And it's just, it's so helpful, man, to have these little, these little things like this that, that you can, um,
Joel Margolis (teknogeek) (01:40:04.25)
Oh, but you might have to move it over a little bit to for it to show up. But yeah. Yeah. Put it right in the middle. Yeah.
Johan Carlsson (01:40:20.698)
Ha ha
Joel Margolis (teknogeek) (01:40:20.849)
I've thought about this so many times.
Justin Gardner (@rhynorater) (01:40:27.544)
put in your life, especially when you're an entrepreneur, when you're self-employed, to sort of differentiate in your brain, this is work and this is play. Especially when it overlaps so much for us that are hobbyists first in Bug Bounty and then have transitioned into a full-time job because of the freedom benefits and the, I guess, just quality of life increase. So there's lots of little hacks like that I'm sure you'll develop. And this also helps with the wife too because if you're spending so much time
you know, working and they're trying to like respect your work time and that sort of thing, but also like if you're just, you know, flitted-y hacking or just like, you know, really doing something from a hobby perspective, then you could say, hey, you want to like go for a walk in the garden or something like that versus distracting you from work. So I think it's helpful to have those sort of things in place.
Johan Carlsson (01:41:06.242)
Hmm.
Johan Carlsson (01:41:16.898)
And I actually had like, that's one of my, one experience I had that was like, that surprised me that was supposed to be a really like a good thing. But then it turned into sort of a bad thing was that I went for a break, like a vacation over Easter to, to Stockholm, to my, my parents, with the whole family. And because I don't have like work hours now, we were just like, yeah, yes. We just drive on Thursday.
Justin Gardner (@rhynorater) (01:41:36.276)
Mm.
Justin Gardner (@rhynorater) (01:41:45.894)
Mm-hmm.
Johan Carlsson (01:41:46.142)
And then we came back a week later and then it was weekend again. And all of a sudden I had like 10 days that I hadn't really done anything. And then I started to get really stressed that it was like this unplanned leave from my own work because I could just do it. But I didn't really think through it in the beginning to say like, I need to still work like one or two days this week to get like my mental
Justin Gardner (@rhynorater) (01:41:57.104)
Mm.
Justin Gardner (@rhynorater) (01:42:04.049)
Yep.
Johan Carlsson (01:42:15.966)
in a good state with this like thing that I'm doing right now.
Justin Gardner (@rhynorater) (01:42:17.852)
and then you feel like you're out of the loop or out of your groove and stuff like that.
Johan Carlsson (01:42:21.086)
Yeah, yeah, yeah. Definitely. So after that, I actually had also my worst week during this that I didn't find anything before like Friday afternoon, I find that like this small like really low bug. So.
Justin Gardner (@rhynorater) (01:42:28.616)
man.
Joel Margolis (teknogeek) (01:42:33.542)
Yeah. I mean, this is my biggest thing is that generally, like, I think for a lot of people, regardless of life situation, it's really important to have some sort of scheduled structured routine that you follow, like regardless of if you're employed or whatever, like at least wake up at the same time and like, dude, like make a coffee, like, or like have some order of events, even if, even if it's not like at the same time and stuff, but just some sort of structured routine that you can follow that helps give you like a grounding.
that every day you either start at the same or you do something that helps you know, okay, now I can start or I can do the things that I need to do today instead of just waking up and be like, hmm, what should I do today? Because that's a lot I found personally, especially very, very difficult for myself to stay on track if I don't set myself things that I want to be doing and things that I aim to actually do. And just instead of, if I approach it just as it rolls,
I'll find that I do a lot less and I'm a lot less intentional with the stuff that I'm doing.
Justin Gardner (@rhynorater) (01:43:31.268)
Yeah, and I think from my side as well, having experiences many times very similar to what you just described of like, oh, wow, I accidentally just took two weeks off, or like 10 days off or whatever. And I'm coming back to this and it's like, okay, now I'm stressed. I think it helps in those sort of contexts to be like, yeah, but I just took 10 days off. And I just like, man, how grateful am I that I
just have that flexibility and that ability to do that and reflect on that. And that's been really helpful for me and realize that is my right as a self-employed person because I'm making trade-offs. I don't have a guaranteed income coming in, right? And that obviously has stress associated with it. And that stress has to have a trade-off. And that trade-off, I told myself, when I did Full-Time Bike Bounty was gonna be the flexibility. And if I can't enjoy that flexibility, then...
Johan Carlsson (01:44:09.58)
Yeah, yeah.
Justin Gardner (@rhynorater) (01:44:28.476)
it's not a good deal. So you gotta like, I don't know, for me, I was kinda like, you know, really twisting my own arm to make me enjoy it.
Johan Carlsson (01:44:33.514)
No, but, so you sort of have to, you kind of have to learn to be conscious about it, I guess, as well. Like actually understanding, like now I'm going to do this and it's going to take time from this other.
Justin Gardner (@rhynorater) (01:44:41.)
Mmm.
Joel Margolis (teknogeek) (01:44:45.018)
Yeah, I think a good way to think about it is like kind of like the unlimited PTO thing that a lot of tech companies give, right? So like as a self-employed person, you basically have unlimited pay time off. Well, time off. Let's not say pay time off. Right? So the real key is how do you turn this into unlimited paid time off, right? Because at the end of the day, you're the one who pay rolls.
Justin Gardner (@rhynorater) (01:44:49.382)
Mmm.
Justin Gardner (@rhynorater) (01:44:57.513)
Hold up, hold up, yeah. Hold up, tech boy. Ha ha ha.
Johan Carlsson (01:44:59.104)
Hmm. Hehehehe.
Joel Margolis (teknogeek) (01:45:08.858)
And so, you know, finding that balance between like the time off and using that time off and not working yourself to the bone, but also, um, making sure that you are working and finding, you know, the time to, to balance work and family and not just like, whoo, like no obligations. Let's go, you know, like, yeah, I think it's really important.
Justin Gardner (@rhynorater) (01:45:26.792)
Yeah. The other day I took, it was like a Tuesday or something, and I went and played pickleball with my friends, you know, at 1 p.m. on a Tuesday. My only other friends that can go play pickleball at 1 p.m. on a Tuesday. And I was like, wow, I'm so grateful for this, because there's no one at the pickleball courts, the weather is beautiful, you know, it's just like, and it's, what a blessing to be able to do that. And I think sort of meditating in those moments and being like,
Johan Carlsson (01:45:41.809)
Ha ha ha.
Justin Gardner (@rhynorater) (01:45:57.276)
this is why I do full-time book bounty really helps with that. And it sounds like you're on the path to that as well, which is really good.
Johan Carlsson (01:46:03.646)
Yeah, I think I have to do this for a longer period to start to not feel stressed because I only have these like the limited Three months I kind of want to make it worth it But I also I listened again I've listened a couple of times to the pod with the alex chapman And he mentioned something that I try to like stay true to Which is like he's not doing this to get rich like the thing with that you can actually get like a lot of money, but
Justin Gardner (@rhynorater) (01:46:07.931)
Mm.
Justin Gardner (@rhynorater) (01:46:13.257)
Mm-hmm.
Justin Gardner (@rhynorater) (01:46:21.862)
Yeah.
Johan Carlsson (01:46:33.418)
You also have to like, realize why you are doing it. So, and that's true for me as well. Like the point of it is to be able to do what I find interesting and fun. And I have to remind myself of that. Like, so I thought that I would be this guy like opening burp and like finding those kinds of bugs. And that's like finding like 200 idor's sending them in and like getting rich. But that's not even what I'm like interested in. Like, so, so why would I do that? So if I find the bugs that pay my bills.
Justin Gardner (@rhynorater) (01:46:52.805)
Hahaha
Justin Gardner (@rhynorater) (01:46:59.107)
Right.
Johan Carlsson (01:47:02.594)
then I can try to spend time on like this really niche things. And while doing that, so like one of the points I had, what is like doing three write-ups or like blog posts and I, that kind of, I stressed out about it. And then I started writing one that I was planning to release like before this podcast. Uh, and when I was doing the bright up, I found a bypass to the bug, uh, that I was doing the right up for. So that was great. Like I had to scrap the blog post for now. Uh,
Justin Gardner (@rhynorater) (01:47:26.332)
Yes!
Johan Carlsson (01:47:32.45)
But like just... I really like this word, the serendipity, which is like... This idea of like, if you just do stuff, like the luck comes to you, like... If you just keep on doing things, it will just happen. And I feel like that happens to me a lot. Like a lot of the bugs I find are... Coming just... Like they just appear appearing where I happen to dig at the moment. Like there are things like everywhere, yeah.
Justin Gardner (@rhynorater) (01:47:43.325)
Mmm, mmm.
Justin Gardner (@rhynorater) (01:47:49.053)
Yeah.
Justin Gardner (@rhynorater) (01:48:00.232)
Serendipitous. Mm, yeah. No, that's a great perspective, man. It seems like you got the mental for Bug Bounty, man. And I know it's different to talk about it on a podcast versus actually implementing it in your own life and whether you can control those stressful times or whatever. But I think, like you said, as time passes, as you get more acclimated to...
Johan Carlsson (01:48:03.115)
So.
Justin Gardner (@rhynorater) (01:48:24.012)
that life and you become more confident in the fact like, okay, I can take two weeks off and feel out of my element and then get back in my element, diving back in and stuff like that, like you did that one time, right? Where you found the bug on Friday. I think that, for me, it hasn't gone away quite as much, but it's nice to also communicate with your spouse as well and say like, hey, no, you probably just all of a sudden haven't.
Johan Carlsson (01:48:34.402)
Hmm.
Justin Gardner (@rhynorater) (01:48:48.94)
lost your ability to do this thing that you've been doing nonstop for the past five or six years, and have them remind you of that. Mariah does such a great job of that, and it really helps my mental in those times where I'm like, yeah, you know what, actually I found the last bug I'm ever gonna find ever again, and I'm just done as a hacker now. It's a holistic thing, man, full-time bug bounty, and it really does help to have a great teammate as well.
Joel Margolis (teknogeek) (01:49:17.47)
I will say though, that's only like 50% of the battle, right? So like the other parts inside your own head. So you have to make sure that like, yeah, you have somebody backing you up, but then when you go and sit down, the person who you're fighting with the most is yourself. And so being able to like deal with that and cope with that when your hands on keyboard is also really important.
Justin Gardner (@rhynorater) (01:49:24.635)
Mm.
Justin Gardner (@rhynorater) (01:49:32.104)
Mm.
Justin Gardner (@rhynorater) (01:49:40.752)
Yeah, yeah it is. Well, Johann, thanks so much for sharing all this stuff, man. It was an awesome episode filled with technical information, full-time Bug Bounty information, just a quality Bug Bounty episode. So thanks for all that, man. Anything you wanna shout before we close this podcast out?
Johan Carlsson (01:49:48.355)
Ha ha.
Johan Carlsson (01:50:00.29)
Mmm.
Justin Gardner (@rhynorater) (01:50:01.488)
I always ask people that at the end and they're not prepared.
Johan Carlsson (01:50:04.486)
No, no, not really. I mean, people can, I try to keep my DMs and stuff open everywhere, so feel free to reach out. Like, that's one. Yeah, yeah, it's definitely, but it's also like with the caveat that I'm really bad at answering because I put that on my to do list and it gets pushed down all the time. But I tried. At least if people.
Justin Gardner (@rhynorater) (01:50:08.154)
Mm.
Justin Gardner (@rhynorater) (01:50:13.18)
Mm-hmm.
Joel Margolis (teknogeek) (01:50:16.694)
This is dangerous.
Justin Gardner (@rhynorater) (01:50:17.968)
OK.
Justin Gardner (@rhynorater) (01:50:24.989)
Mm.
Johan Carlsson (01:50:32.022)
reach out with actual questions or concrete like how can I do this or whatever. I try to answer them eventually. It can take a long time, but then I do it. Yeah, yeah, yeah.
Justin Gardner (@rhynorater) (01:50:44.892)
And it can lead to good collabs for you too, like you mentioned. And I've said this before on the pod, but since we launched this pod, I've definitely made five figures worth of bounties from people reaching out to me saying, hey, here's this bug, I can't fully exploit it. And then I fully exploit it and we get some percentage of it. So, wise shout out there, Johan. I see you trying to steal some of my collabs, huh? I see how it is.
Johan Carlsson (01:51:01.142)
No. I have a... It doesn't... It has happened to me as well, but I have one issue with it, which is... In Sweden here we have really strict tax laws, so it's really hard for me to collab if it's not an official collab. So that we can split it on the platform. I don't even know how I would...
Justin Gardner (@rhynorater) (01:51:17.872)
Oh really?
Justin Gardner (@rhynorater) (01:51:25.617)
Mmm.
Johan Carlsson (01:51:29.578)
tell the tax authorities about someone just sending me like a bunch of money and I'm saying yes like yeah there was a collab like it will not work so it has to be a very like official unfortunately because some programs don't allow you to collaborate.
Joel Margolis (teknogeek) (01:51:46.334)
to make collaboration on by default program platform. I don't know why this is still a thing.
Johan Carlsson (01:51:48.85)
Yeah, definitely, definitely.
Justin Gardner (@rhynorater) (01:51:50.544)
Yeah, yeah, 100.
Justin Gardner (@rhynorater) (01:51:54.688)
Who knows, man, who knows. But yeah, definitely hit yawn up if you've got any crazy CSP bypasses or client-side bugs you need expletive. And yeah, I think we'll wrap it there because there's construction noises in my house that we're gonna have to cut out, so. Seriously, all right, all right. Good pod, guys, peace.
Joel Margolis (teknogeek) (01:52:08.698)
Someone's about to fall through Justin's ceiling any minute now.
Joel Margolis (teknogeek) (01:52:14.604)
That's the pod.