00:00:00.320 --> 00:00:03.279
I'd like to clear something up right now.
00:00:04.080 --> 00:00:08.560
Most security bugs are not caused by bad developers.
00:00:08.720 --> 00:00:15.199
They're caused by good developers doing exactly what the system rewards them for doing.
00:00:15.439 --> 00:00:17.440
They aren't stupid mistakes.
00:00:17.679 --> 00:00:19.440
They're rational ones.
00:00:19.839 --> 00:00:23.600
Hi, I'm Tanya Jenka, also known as SheHacksPurple.
00:00:23.839 --> 00:00:30.879
Welcome to DevSecStation, a podcast for software developers who want to build more secure software.
00:00:31.120 --> 00:00:41.119
In each episode, I'll share a short practical lesson about secure coding, software security, and how to build safer systems without slowing development down.
00:00:41.359 --> 00:00:45.039
You can jump in at any episode, at any time.
00:00:45.359 --> 00:00:47.200
No homework required.
00:00:48.000 --> 00:00:50.399
This episode is sponsored by Maze.
00:00:51.039 --> 00:00:58.479
One of the biggest problems in security right now is that every vulnerability or cloud scanner says everything is critical.
00:00:58.640 --> 00:01:01.200
And honestly, no one has time for that.
00:01:01.439 --> 00:01:12.799
MAZES uses AI agents to investigate vulnerabilities in context, so you can focus on the issues that are actually exploitable in your environment and not just theoretically scary.
00:01:13.120 --> 00:01:24.560
Their AI agents also generate and prioritize fixes that knock out multiple vulnerabilities at once, which is honestly the kind of scaling that security teams really need right now.
00:01:24.799 --> 00:01:30.159
Learn more about maze at mazehq.com slash devsec.
00:01:30.719 --> 00:01:36.319
If you've ever looked at a security issue and thought, I knew better, why did I do that?
00:01:36.560 --> 00:01:39.920
Oh this episode's for you.
00:01:40.239 --> 00:01:51.760
There is a very persistent myth in security that insecure code comes from ignorance, that if developers just knew more, these issues would magically go away.
00:01:52.079 --> 00:02:04.319
But in practice, most insecure patterns come from incentives, from deadlines, performance reviews, feature pressure, operational complexity.
00:02:04.640 --> 00:02:13.840
When the system rewards speed, availability, and delivery, developers optimize for those things and not for security.
00:02:14.080 --> 00:02:17.039
That's not negligence, that's professionalism.
00:02:17.199 --> 00:02:21.360
I'd like us to look at a few very common examples of how this happens.
00:02:21.680 --> 00:02:29.280
You skip input validation because the data is internal, and you're trying to hit a deadline and you know that it's safe.
00:02:29.599 --> 00:02:35.520
You reuse old authorization code because it mostly works, and rewriting it feels pretty risky.
00:02:35.840 --> 00:02:41.039
You log less than you know you should because verbose logs they cost too much.
00:02:41.360 --> 00:02:48.240
You copy a known pattern because it worked last time, even though you know that maybe it's not ideal.
00:02:48.560 --> 00:02:52.400
In isolation, each of these decisions totally makes sense.
00:02:52.639 --> 00:02:54.960
They made sense in that moment.
00:02:55.439 --> 00:02:59.120
But over time, these shortcuts can really stack up.
00:02:59.360 --> 00:03:02.960
And eventually, they can turn into vulnerabilities.
00:03:03.280 --> 00:03:05.120
This isn't about bad judgment.
00:03:05.199 --> 00:03:06.639
That's not what I'm talking about.
00:03:06.879 --> 00:03:11.280
It's about local optimization in a very complex system.
00:03:11.680 --> 00:03:13.360
So, how do we fix this?
00:03:14.000 --> 00:03:20.960
A bad approach would be assuming insecure code means someone messed up and then blaming them and shaming them.
00:03:21.360 --> 00:03:29.840
That leads to discussions, lectures, more rules, more shame, and shame does not produce better software.
00:03:30.159 --> 00:03:35.360
A slightly better approach is reminding developers to slow down and be more careful.
00:03:35.840 --> 00:03:42.400
This could help in the short term, but it still asks people to fight incentives using willpower.
00:03:42.560 --> 00:03:47.120
And willpower is an extremely fragile security control.
00:03:47.680 --> 00:03:51.599
The best approach isn't telling developers try harder.
00:03:52.000 --> 00:03:59.919
It's changing the environment so that the secure choices are the easiest and best choices.
00:04:00.319 --> 00:04:04.159
Let me give you some concrete examples of what that actually looks like.
00:04:04.479 --> 00:04:08.400
Example number one: authentication checks.
00:04:08.560 --> 00:04:21.040
So instead of copying and pasting authentication checks everywhere, teams either use a trusted product or they create a shared helper or middleware and they use it repeatedly every single time.
00:04:21.360 --> 00:04:23.439
Now the incentives have shifted.
00:04:23.600 --> 00:04:27.360
Using the secure pattern is faster than rolling your own.
00:04:27.680 --> 00:04:30.959
Example two, authorization logic.
00:04:31.279 --> 00:04:39.519
Instead of sprinkling role checks all throughout your code base, teams centralize authorization decisions in one single function.
00:04:39.680 --> 00:04:42.240
Developers don't have to remember all the edge cases.
00:04:42.399 --> 00:04:46.240
They can just call that helper that already enforces it for them.
00:04:46.560 --> 00:04:47.199
When.
00:04:47.839 --> 00:04:50.720
Example three, input validation.
00:04:51.040 --> 00:04:58.480
Instead of ad hoc validation in every endpoint, teams adopt a standard validation library or schema.
00:04:58.639 --> 00:05:08.639
Skipping validation or writing your own stops being the shortcut because the safe version is already there and it's easy to use and everyone else on your team is doing it.
00:05:08.879 --> 00:05:11.680
Example four, error handling.
00:05:11.920 --> 00:05:18.480
So instead of catching exceptions inconsistently, teams define a standard error handling library.
00:05:18.639 --> 00:05:22.720
Then you do it the same safe way every single time.
00:05:23.040 --> 00:05:26.399
Example five, secrets and configuration.
00:05:26.800 --> 00:05:33.920
So instead of letting developers decide where secrets live, team make secret management the only supported path.
00:05:34.160 --> 00:05:42.079
You scan every check-in for secrets, and if it's not in the secret manager, it just doesn't work and does not run and does not let you check it in.
00:05:42.399 --> 00:05:43.040
When?
00:05:43.680 --> 00:05:49.120
In all of these examples, we didn't fix security by giving a developer a big lecture.
00:05:49.360 --> 00:05:57.920
We fixed it by making the secure option easier, faster, and less risky than some shortcut that they usually did before.
00:05:58.240 --> 00:06:04.079
That's how we can eliminate insecure patterns without blaming people.
00:06:04.720 --> 00:06:09.279
If you do just one thing this week after this episode, please do this.
00:06:09.839 --> 00:06:16.319
Identify one insecure pattern your team uses for good reasons and then make it safer.
00:06:16.639 --> 00:06:18.399
How do we do that, right?
00:06:19.199 --> 00:06:24.399
Step one, find a security shortcut that has been happening for some time.
00:06:24.639 --> 00:06:30.800
Perhaps a security tool has been chirping about that same thing forever and you have been suppressing that result.
00:06:31.279 --> 00:06:36.160
Perhaps there's a comment that keeps showing up over and over in your PR reviews.
00:06:36.480 --> 00:06:41.360
A security incident was caused by this shortcut, or perhaps there was like a near miss as a result.
00:06:41.759 --> 00:06:45.920
Something that is copied and pasted all the time, but no one maintains that thing.
00:06:46.160 --> 00:06:49.920
Code that has a note on it that says fix later, but has never been fixed.
00:06:50.160 --> 00:06:56.399
Developers don't discover insecure patterns by knowing security better and being an expert on vulnerabilities.
00:06:56.480 --> 00:06:59.759
They discover them when the same problem shows up repeatedly.
00:07:00.000 --> 00:07:02.959
Okay, step two, ask why does this exist?
00:07:03.439 --> 00:07:04.399
Is it saving time?
00:07:04.560 --> 00:07:05.439
Is it reducing risk?
00:07:05.600 --> 00:07:06.800
Is it avoiding outages?
00:07:06.959 --> 00:07:13.199
Because if you change it and you don't also fix why it exists, it's definitely going to come back and we don't want that.
00:07:13.279 --> 00:07:15.360
Okay, so you need to understand the why.
00:07:15.519 --> 00:07:18.319
Step three, improve the pattern.
00:07:18.800 --> 00:07:23.839
So for example, replace that copy paste auth check with a shared helper.
00:07:24.079 --> 00:07:27.120
Add a safe default wrapper instead of raw access.
00:07:27.279 --> 00:07:32.959
Introduce a lightweight validation library instead of ad hoc checks that are inconsistent.
00:07:33.199 --> 00:07:39.680
You are not asking people to stop doing their jobs, you are giving them a safer way to succeed.
00:07:39.920 --> 00:07:43.199
Good developers don't write insecure code because they don't care.
00:07:43.279 --> 00:07:48.079
They rate it because they care about shipping, stability, and users.
00:07:48.319 --> 00:07:54.399
When we acknowledge that, security stops being adversarial and it starts becoming collaborative.
00:07:54.560 --> 00:07:56.240
And that is what we want.
00:07:57.040 --> 00:07:59.680
Thanks for listening to DevSecStation.
00:07:59.839 --> 00:08:05.199
If you enjoyed this episode, please subscribe, share it with a friend, or leave a review.
00:08:05.360 --> 00:08:07.759
It helps more people discover the show.
00:08:08.079 --> 00:08:13.120
If you'd like to learn more, I'm Tanya Jenka, also known as SheHacksPurple.
00:08:13.279 --> 00:08:16.879
And I teach secure coding training for software developers.
00:08:17.120 --> 00:08:20.399
You can find me online at shehackspurple.ca.
00:08:21.040 --> 00:08:22.800
Thank you for being here.