Dima Kotik is an Application Security Engineer at Security Journey and has been programming in Python for years. As he was working on building out Security Journey's Secure Coding with Python content, he came across the Zen of Python, a set of guidelines for how to program in Python.
Audio hosted by Buzzsprout. Nothing loads until you press play.
Episode chapters · 10 chapters
- 00:00Meet Dima Kotik: Application Security and the Zen of PythonAudioVideo ↗
- 02:02That is, how did you get your start in application securityAudioVideo ↗
- 05:06That consistentAudioVideo ↗
- 06:45Does Python fit into web applicationsAudioVideo ↗
- 09:53Yeah. So, you wrote a blog post about the Zen ofAudioVideo ↗
- 13:17You wrote this article, you took the Zen of Python andAudioVideo ↗
- 17:23What's the security takeaway then in regards to readable codeAudioVideo ↗
- 21:15That was readable, plus talking about the applicability of this wholeAudioVideo ↗
- 32:57What's the security takeaway then on the singularAudioVideo ↗
- 34:40This has been very beneficial to understand the Python use casesAudioVideo ↗
About this episode
Dima Kotik is an Application Security Engineer at Security Journey and has been programming in Python for years. As he was working on building out Security Journey’s Secure Coding with Python content, he came across the Zen of Python, a set of guidelines for how to program in Python. He wrote a blog post about how to apply application security to the Zen of Python, and then we recorded this interview to talk about the concept in more depth. We hope you enjoy this interview with…. Dee Makotik is an application security engineer at Security Journey and has been programming in Python for years. We hope you enjoy this conversation with— Dima Kotik.
The Application Security Podcast is brought to you by Security Journey.
About Security Journey
Dee Makotik is an application security engineer at Security Journey and has been programming in Python for years.
→ Learn more about Security Journey
Connect with Dima Kotik:
→ Zen of Python (PEP 20)
→ Dave Cheney: The Zen of Go
Resources
→ Zen of Python (PEP 20)
→ Dave Cheney: The Zen of Go
→ Go
→ Rust
→ Node.js
→ Ruby
→ Flask
→ IronPython
→ Stackless Python
→ Zig
→ WireGuard
→ OpenSSL
→ NASA Ingenuity Mars Helicopter
Actionable
From this conversation
- 13:44
Write readable, explicit, simple code
The 4 basic principles are that excellent Pythonic code should be readable, explicit, simple, and singular.
- 21:29
Handle errors explicitly
Don't write functions that ignore error or the infamous, try-catch block with the catch part empty,
- 25:32
Split functions with multiple responsibilities
Don't write— if you have a function that does 2 things, has a boolean parameter, okay, that needs to be split up.
Transcript · 39 min conversation
0:00Chris RomeoDee Makotik is an application security engineer at Security Journey and has been programming in Python for years. As he was working on building out Security Journey's secure coding with Python content, he came across the Zen of Python, a set of guidelines for how to program in Python. He wrote a blog post about how to apply application security to this Zen of Python, and then we recorded this interview to talk about the concept in more depth. We hope you enjoy this conversation with—
0:26Robert HurlbutDima Kotik.
0:28Chris RomeoAt Security Journey, we believe security is every developer's job. We work with our customers to help them build long-term sustainable security culture amongst all their developers. Our approach is to provide security education that's conversational, quick, hands-on, and fun.
0:45Robert HurlbutWe don't do lectures.
0:47Chris RomeoInstead, we let the experts talk about what's important. Modules are quick, 10 to 20 minutes in length. We believe in hands-on experiments, builder and breaker style, that allow your developers to put what they learned into action. And lastly, fun. Training doesn't have to be boring. We make it engaging and fun for the developers. Visit www.securityjourney.com to sign up for a free trial of the Security Dojo.
1:11Robert HurlbutHey folks, this is Chris Romeo and welcome to another episode of the Application Security Podcast. I'm the CEO and co-founder of Security Journey and also co-host of said podcast. Today we're gonna talk about the Zen of Python, but first we're gonna talk about Python, then we're gonna talk about the Zen of Python, and then we're gonna talk about how application security can take away some lessons from the Zen of Python. I'm joined today by Dima Kotik. Dima, we like to always start these conversations by asking a very simple question.
2:00Chris RomeoSure.
2:02Robert HurlbutAnd that is, how did you get your start in application security?
2:06Dima KotikHey, Chris, thank you for the invitation. That's really exciting. I am starting in application security this year. I have actually a long route as an engineer, a hobbyist for a long time. I worked in college in PHP for many years, and then I self-taught Python, had really a lot of fun with it. It was limiting in many ways. Then I fell in love with Go. About 2 years ago, and I spent almost the entirety of 2 years rewriting old projects into Go that used to be in Python and PHP. And then, you know, this last year, 2020, was kind of crazy. Lots of things changed, and I was contracting, and people were asking for application security help. A lot of it had to do with Python, with other things, and I was like, well, that's something that's interesting to me. And it's grown from a hobby into a career now, full-time.
2:54Robert HurlbutYeah, that's pretty exciting to come from being a hobbyist developer to starting to do more focused development to then pivoting into a career in the world of application security. It's pretty exciting stuff.
3:10Dima KotikYeah. And it's, for me, a particular challenge. I like puzzles. I get drawn into those wild goose chases. Why is this not working? It's not enough for me to fix it. I want to understand what caused the bug. And as an engineer, I aspire to become eventually, like over 10, 20 years, so good that if I wrote a piece of code, nobody would have to go and wonder if it will fall over. And it's very difficult to achieve. And even because some of the best guys make mistakes. And so, how can you write so it's really, really stable? And in Python, it was a little bit hair-pulling sometimes, not always because of the language, but some of the libraries, et cetera. It just was like, I thought of it as chaos management or complexity management because you're trying to do something and you think it's easy and then you get deep down into it, it just grows out of your control. And it's chaos management and it's also attention deficit management. How do I, as an engineer, pay attention to all those things that cause bugs? And ultimately, I mean, a security vulnerability is really just a bug. It's just a class of bugs. And I really hate those. So, that's the keen interest, you know, how do I set up systems, routines, disciplines for myself to figure out how do I write this to minimize at least the occurrence of those?
4:29Robert HurlbutI know we want to kind of step back and think and talk a little bit about Python from a foundational perspective. And so, I thought we'd start by just discussing what is Python used for these days? Because when I think Python, I think old school. I think scripting. I think when people just want to create a script, a quick and dirty script, almost like a better Perl for those people that have been around for a number of decades and remember Perl.
5:00Chris RomeoThat's what I— that's sometimes is the perspective that I have on Python.
5:05Robert HurlbutIs that consistent? Is there much more than meets the eyes to Python? What's Python used for these days?
5:12Dima KotikYeah, well, there is a whole lot. I mean, in the news recently, right, they launched the helicopter on Mars, which was a tremendous achievement. And it seems like so many people haven't even heard about it. You know, I talk to friends and they're like, oh, what helicopter? Mars' atmosphere is like 1/10 of the density of the Earth, and a lot of it is enabled by Python. It's C family there as well, but a lot of it is open source. And so that already shows you how far the language has gone.
5:39Robert HurlbutYeah.
5:39Dima KotikThere are some really beautiful things about it. It's attractive. It promises some things that are very, very attractive, especially if you come from corporate Java world or .NET world. Python has a lot of things that make it suitable, especially for those types of applications. Surprisingly, it's super popular with scientists, and it's understandable why, because a scientist is not a programmer. But now they realize to be a good scientist, you have to know data crunching, you have to know all those engineering things, well, what is going to give you the best bang for your buck, right? Learn Java? It's like, no. Learn C++? No. Python? Oh, I can pick it up in a month and I can start crunching datasets, doing some AI work, and I can share code. That's the other really important thing because science is all about collaboration, international collaboration, right? So it will gravitate towards standards and patterns and approaches that are kind of universal or aspire to be universal. And Python turned out to be one of the best languages What about Python in the modern web?
6:44Robert HurlbutWhere does Python fit into web applications?
6:47Dima KotikWell, it's kind of fighting tooth and nail with Node infrastructure. Python made some missteps because it's earlier than Node, but then Node, they did a few things slightly better than Python and it just took off. And they're kind of in the same niche right now in the web and duplicate almost everything. So, async was a huge feature in Node, so Python in some ways to compete for the same attention, for the same features, imitated async. And there's a huge argument right now if that was even a smart step. Was that the right approach? Because async as a paradigm is odd. It has to do with just the way our hardware is right now. Some limitations in manufacturing is just the way we make chips. There's no way to really undo that. So async is kind of a compromise of sorts. And Python went all in, but async, you know, everywhere it is kind of a mess. Rust async is a huge pile of mess, and Node.js is not quite together. And then Python got a little late implementing it, and in some ways it's a little bit better. And now there are frameworks that are coming out which are kind of, you can say, solid, reliable, production-ready. But it's kind of left a trail of corpses along the way.
7:59Robert HurlbutSo it sounds like Python's used quite extensively. It's from all the way from flying a helicopter on Mars, which is pretty darn cool when you think about it, to data science, to things that are happening in the world of scientific research, all the way to web applications. So it sounds like Python is a bit of a Swiss Army knife in that it can fit into a lot of different situations. And I guess based on one of the other things I heard you say, because it is relatively easy or an easier language to learn than something like C++, there's also that advantage going forward as well.
8:37Dima KotikYes. And it's also kind of— it's a language that transcends many, many areas, right? Because it'll get into data. There are flavors of Python like IronPython and Stackless Python. There are very peculiar, very interesting. And in the web space, you know, we barely touched on it, but Ruby and Python overlap like 99%. in what they offer. And that's good. It's like the competition kind of drives the thing. But Python Flask is a wonderful, marvelous library that— and many, many others which can be used to— you got to launch something quickly. Somebody says, hey, we have this engineering problem. And then somebody raises their arm and says, hey, I can do this over the weekend in Python. with minimal, you know, you can even do like a Lambda function and it'll take so little time. And, uh, and that makes it valuable, you know, because the deadline, we all face it. We all face it, especially if something's not working, you know, or, or a client has a crunch and they say, we need you to deliver this, but you only have 2 weeks to do it. What are you going to do? You can do it on .NET, but, uh, if you have someone who is strong in Python, it will— they'll certainly deliver. 2 weeks is doable. Some crazy stuff can be done in Python in 2 weeks.
9:52Robert HurlbutYeah. So, you wrote a blog post about the Zen of Python and application security, which we're going to get to those details in just a second. But I think it's beneficial to stop and discuss this idea of the Zen of Python because I know this was a relatively new concept when you were explaining it to me a few months ago. that is gonna be beneficial for everybody to have a perspective on. So, let's start by defining what is the Zen of Python, what do I find in it, and then what is it useful for?
10:25Dima KotikYeah. So, Python has a set of standards, PEP, and Zen of Python is PEP 20. And there's many of them. So, those are kind of code guidance. How do you write proper Python code or this other phrase, idiomatic code that is kind of elusive, you know, who knows what that means. But it means it's just a code that's idiomatic, meaning that people recognize that, oh, that's the correct way to do X task or function or like a worker pool or something. And that's an idiom of code. And so PEP is collection of idioms. Well, Tim Peters, a long time ago, he just came up with his own idiom and he made it kind of as a joke in a sense, in a haiku format, like in the Asian wisdom type of literature format. It's 19 statements which are pithy. They're not meant to be like laws. Those are not like 10 Commandments of Python. Those are more like wisdom proverbs of Python. So, if you follow those things, you'll write good code. And it's very interesting. Yes.
11:30Robert HurlbutSo, let's explore a couple of those just to give people some perspective. We'll certainly provide a link to the original Zen of Python in the show notes for anybody who wants to go read it and consider, you know, all of the individual details that are there. But, you know, pick one or two as an example and let's just explain what the statement is and then how it applies to Python.
11:51Dima KotikYeah. Well, some of them are like really, really obvious, you know, like readability counts. I mean, why is that even a thing? Well, 10 years ago, that was a big thing, right? Because that's the reason why Python appeared because they said like Java and C# code, I mean, it's just not readable. It's like, The lines are getting so long, especially when you add all the class names, you know, and all the proper computing variable names. Thingy Mingy, which does thingy and, you know, implements interface, and there's like a list of 5 interfaces. It's like, it's just crazy. So Python, they said, well, readability counts. So that's one of the proverbs. The other one that I think a lot about is like simpler— simple is better than complex. But complex is better than complicated. Is that how it says in there? Something along those lines. But the point being is that there's actually a lot to that statement. If you think about it from a computer engineering architecture perspective, that forces you to sit down and think, okay, how do you actually in practicality do this? Because programs are not simple at all, especially those large multi-service complicated pieces of software. So, how do you make them actually simple? And why is complex better than complicated? What is meant by those words? And that kind of causes you to go into the Zen state. Okay, let's meditate on this. Let's really think about this, how we can apply this to architecture. So, those are just 2.
13:16Robert HurlbutWhen you wrote this article, you took the Zen of Python and kind of broke it down into some categories or buckets, I guess, so that then you could draw out some conclusions about how application security is impacted by that category. How did you break down the Zen of Python when you were doing that categorization? What was your justification for saying, like, these things go together and these things don't?
13:44Dima KotikYeah. Well, I've thought a lot about the Zen of Python, and a lot of it has to do because it's so influential. Every major programming language that appeared recently was under influence of the Zen of Python one way or another. You know, some big people like Dave Cheney wrote a blog on the Zen of Python for Go, for example, but for similar blog for Ruby, for other places. So, it's incredibly influential and people think about it. People who design languages think about it because they're like, I want to do better. Python was a really good step in the right direction, but can we do better than Python? And of course, when they ask that question, it goes back to the Zen of Python. You know, what about that? So, when I was thinking about myself, so how do I develop practical advice for myself? How can I learn this? And also, I try to simplify things because 19 principles are really hard to remember. And since Tim Peters, when he was writing it, he wasn't really trying to be 100% serious, he wasn't trying to make like a manual or a material or a guidance. It's more like a joke, like an inside joke of the community, so to speak. So the easier way to remember it, the way I classify the 19 principles, is into 4 categories. And obviously, it can be argued which one goes where, but the 4 basic principles are that excellent Pythonic code should be readable, explicit, simple, and singular.
15:07Robert HurlbutLet's go ahead and unpack each of those because I want to draw out the security goodness that exists within each of these properties. So let's start with readable. Describe for us what that means, and then let's talk about the security takeaway there.
15:27Dima KotikYeah, so readable code, you can group those as well. Like, I group readable and explicit together as something that has mostly to do with functions, with writing functions. And simple and singular has more to do with on the package level. I mean, that's at least the way I parse it. So readable, why is that such a big deal? Why the code should be readable? And this, I learned this from Go as well. That's one of the things that surprised me because a lot of things you read is like, A little bit counterintuitive. And so, one of the Go proverbs is, it's easier to write code than it is to read. It's so strange, you know why? And that's why you always have this guy, you hire somebody in your company and they come up and they say, all this is junk, we need to rewrite this. So, how many people who have large projects have heard this? It's like, oh, this is garbage, this needs to be rewritten. It's a trap, and partly it shows some weakness on the engineer side because it is always easier to rewrite than to read. Because when you read the code, you have to hold all those entities in your head, and they multiply so quickly. They just escalate, and then all of a sudden it becomes a threat. So I go from this function to this function to this function. Oh, that's another thread interaction there. And then there is a caching layer here. And then there is like a little event handler for notifications and there's a logging service. And all of a sudden you're like, I can't keep track of all of this. So it's so hard. And Python, it took minimalistic approach in this. So they say it needs to be readable. It needs to be really easy for me to look and almost in plain English, you know, if I just read the code out loud, does it make any sense? Right? So, that's a good question. And of course, a lot of code doesn't make any sense when you just try to read it out loud. With Python, it's possible to write it in such a way. Yeah. So, that's readability.
17:22Robert HurlbutWhat's the security takeaway then in regards to readable code?
17:28Dima KotikYeah. Well, the number one security takeaway, I mean, again, if we talk about security as chaos management and attention management problem, we talk about teams specifically. Security, like a lot of those bugs, They escalate or they get out of hand when you have 5 or 6 people handle the same code, right? Especially when you stretch that out over like 5 years. There's an obscure function that somebody wrote. Somebody went in because they needed to add and extend it slightly and they put a comment and they were trying to make the best out of it and they were careful. They even wrote maybe a couple of tests. But you do that 5 times, all of a sudden the function that was like 10 lines of code is like 200 lines of code now. And it's full of comments and it's just fat. And you can't make heads or tails of it. You look at it and it's just a matter of time. It's just a matter of time before someone, even an experienced engineer, goes there, starts trying to sort it through, gets distracted with notification, goes back, and there you have a security vulnerability. So readable code is more secure, 100%. It's not for your sake, it's for the sake of your teammates. and for the sake of people who inherit, you know, the stuff we produce and then have to live with it.
18:40Robert HurlbutSo, I wanna stop here just for a second and talk about, because as I'm listening to you talk about this, it's like, this isn't really Python-specific. This is specific to programming languages in general. So, is that a fair conclusion that I'm drawing so early in this conversation? Is it, can I take this same, like, this using readable, for example, it seems like that fits in a Ruby world, a Java world, a Go world, C#. I can't think of a language where it doesn't work, where I'm like, no, maybe machine language because nobody can read that. I don't know. But like, you know, is there another— like, is this applicable to everything, to every development language out there?
19:22Dima KotikIt is. It is. You know, and that's why, you know, the Zen of Python tried to make it as a core element of the language. And I think code— I mean, not code, Go language does it in some ways better. Because it took a similar principle and just, it went and was a little bit more systematic about it, at least on a standard library. Like, Go is famous for having a really strong standard library, and a lot of it has to do that they emphasize this. It has to be readable. If it takes you more lines to do it, if it takes you more effort to do it, spend the effort, make it readable. So it applies to any language. I mean, the same thing with Rust. There's like Zig right now that appeared, you know, it's kind trying to be a C++ replacement. And it's a similar thing. It's like, it's a C++, but it's more readable. It's easier to comprehend. There's less lines. There's less funky constructs. Sadly, unfortunately, Python does not always follow the Zen of Python. I mean, that's like the theme of our security conversation with it, right? So Python is also famous for idiomatic windliners, like list comprehensions. And hilariously, the Zen of Python is in the open, in the source code. You can go and look at PEP 20 source code. It's a string that's encrypted with a Caesar cipher and has a list composition to decrypt it. I mean, that's not a readable way to do anything, right?
20:44Robert HurlbutThat's some of the humor from the author.
20:48Dima KotikYeah. There's a lot of humor in that. And people are starting to say, Zen of Python is a farce, but it is a problem. You have those guys who are really good at writing one-line shell things, like a command that does 200 things. And so, people apply that to Python and be like, oh, I'll do a triple list composition with a context manager on top of it, and it will be just great. Well, it's not great because then someone has to read it, and then it's awful.
21:14Robert HurlbutSo, that was readable, plus talking about the applicability of this whole idea of Zen of Python and AppSec to other languages. What about explicit? What am I getting through this? Keyword explicit.
21:29Dima KotikYeah, so explicit, the first line of application there is error handling, right? So that means never let error just go by. Don't swallow it. Don't write functions that ignore error or the infamous, you know, try-catch block with the catch part empty, you know. Yeah, people do that. And so Python says never do that. It needs to be explicit, you know, meaning that You have to model not just the proper behavior, you have to model improper behavior and it has to be very clear. Why is this there? What does it do? For what reason? And what are potential ramifications? So that has to do a lot with documentation as well, so meaning explicit. So your variables have to be explicit. You know, you don't want to use a variable called x. That's a mark of a junior programmer. They use a variable called x because, you know, that's what they use in a math algebra class. x and y and z, those are going to be my variables.
22:26Robert HurlbutYeah.
22:28Dima KotikWell, if you're doing like array math functions, maybe that makes sense, but you never want to do that in Python or any other language. You want to explicit whatever it does, just call it by the name. You know, quacks like a duck, you know, call it a duck. This is a duck, or this is a process, or this is a task, whatever it is. And preferably it doesn't just have to be plain meaning, it has to be apparent to a person without having to know the entire context of the program. So a lot of really generic names for variables other than i and j, those are kind of fell into— for list processing, those are kind of standard from the C/C++ days. But for everything else, you want to have explicit variable names. There's actually an argument about that too. I can talk about variable names for a long time because Go has a disagreement with Python strategy on this. But in Python, If you have to write a variable name that has 3 parts with underscores, they would say go ahead and do that. That would be better. I mean, if you must. If you can get away with one word, that's even better. But not in such a way that now I have to read like 5 other pages just to understand what signal means or what port means. Are you talking about network port? Are you talking, you know, what kind of port you're talking about? So be specific, explicit.
23:46Chris RomeoYeah.
23:48Robert HurlbutSo the key, the security takeaway then for being explicit is I could draw out, I guess, the fact that you're saying make sure you never swallow errors. Proper incident response requires notification and error tracking and logging of everything that's happening inside the program. And if you're swallowing those or you've got the infamous empty catch block, you are losing that error data and you are weakening your ability to respond to a given incident.
24:19Dima KotikYes, and also error types. That's the other big thing, right? Because people will a lot of times return generic error like a connection error. Okay, what's a connection error? There's like 200 things that could go wrong with the connection. Did it time out? Did the worker pool get overfilled? Was there a protocol error? Was there a handshake error? Was there SSL error? Like what error really happened? You have no idea. So when you write the code, you want to make it explicit. So if there's an error type, it means that there's similar errors to this one. It's not one of a kind. You want to define a type of that type and then pass it as of that error type with a proper error message and some context if you need to. And so a person can then operate on the receiving end, right? When you do your try and catch clause, in the catch clause in Python, you can say catch and you list the types of errors you're looking for. So, that gives you, the person on the other side, the ability to differentiate different failure conditions and respond to them accordingly. That's so important.
25:18Robert HurlbutThe next category that you had in the article is simple.
25:23Dima KotikYes.
25:27Robert HurlbutI'm trying to be so simple with my entry there, my question. I was being too simple, perhaps.
25:32Dima KotikYeah, yeah, too simple. So, how do you write? Everyone wants to write simple code. Easily said and hard to do. And simplicity is something to pursue. It's one of those things, you know, that's where the whole Buddhist, you know, Zen part comes into it because, you know, Buddhist ideals, they're not attainable. They're not possible. You just kind of imagine them and then you imagine yourself doing them. And over time, you may approach to some level of that practice, right? So, it's the same thing. Simple, yeah, It means the number one thing, you know, we talk about, you know, package level. So, package needs to do just one thing. A function needs to do just one thing. Don't write— if you have a function that does 2 things, has a boolean parameter, okay, that needs to be split up. That needs to be divided. Testing really helps with that, you know, because when you write tests, it forces you to break up those complicated structures. And so, simple, how's it different from readable, people will say? Well, readable and simple are different because Readable just has to do with how you perceive. Simple has to do with how it operates. Like the form and the function, those are 2 different parameters, how it operates. So you have a task to do, how are you going to do it? Try to think of like 5 or 6 different ways, you know, brainstorm, because I mean, you do this, I do this, you know, we have something and you're like, the first idea that comes into my head, I'm doing it, right? For whatever it is. And simple says, no, stop. Try to think of if there is— there are 5 or 6 other ways of doing it. And then after you've imagined all possible ways of doing it, pick the one that is actually simplest. Don't just jump on the first thing that comes into your mind or just, you know, the other big one. Don't copy paste code from Stack Overflow that somebody else wrote, right? Because you didn't have time to think about it. That could be a way to fish for options. to fish for possibilities, but you always want to eliminate the more complicated ones. And there's different ways to measure complexity too. Like, that's a big argument. So what does it mean simple? Fewer lines of code? That was a good benchmark some time ago. Right now, the thinking is that may not be the best benchmark. So simpler may be how many— like, one good way to think about how many entities do you have to hold in your head to comprehend it, right? So this is a known fact from neurology. A person A smart, educated person can maintain in their mind 5 to 11 concepts of different kinds, right? There's like the test you can do, like spill the pencils and you look at a pile of pencils, how many do you see? And so if it's under 12, people can just identify the number with a quick glance. If it's more than that, they'll just say it's a pile of pencils, I don't know how many there are. And so your code is the same way, right? You look at it, if you have more than 5 variables, oh man, you're in trouble. Because it's just hard. And because that's the only thing, not the only thing you're thinking of. You're not just thinking about variables, you're thinking about other contextual things. So that means simple, less nesting. Don't nest that far. Actually, one level of nesting is all you need. If you're nesting 2 levels, I mean, that just means you're asking for a split function. You need to rewrite that to split it apart. All right. If you're returning, how many values are returning? How many objects are you juggling? So simple means less, less, less, less, less. And kind of like, I like how the Go settled because in the Go community they say at most 3 parameters accepted and at most 2 returned. That's kind of standard. And the last one is always error in Go. So in Python you can apply the same kind of thing. At most 3 to 5 stretching it, 5 is like really, really stretching it. And then if you return just 1 value in Python, that's considered more Pythonic. If you return multiple values, I mean, there's sometimes benefits to that. You can do like, you can decompose return values and things like that, but really you should not do that. You should try to have just one return value just to kind of manage that chaos.
29:32Robert HurlbutAnd so, the keep it simple applies to Python, applies to life, applies to everything. Keeping things simple is always gonna be a better approach. And when I think about this from a security perspective, obviously, simple is greater than complex in regards to security.
29:56Chris RomeoYeah.
29:56Dima KotikWell, the big one for security— sorry. But the big one for security, if you look at OpenSSL, you have those protocols that allow you cipher negotiation. That's bad. Who thought that was going to be a good idea? I mean, you're trying to future-proof it. If you look at WireGuard, I think WireGuard does it right. There's a couple newer protocols that do it. They just said, we're not going to mess with cipher negotiation because once you don't do it, all of a sudden your entire protocol is like 8 times more simple. And it is more secure. You just look at it, how many vulnerability critical bugs you had in OpenSSL and then you compare it to WireGuard and it's like a magnitude of 50 at least, maybe more.
30:39Robert HurlbutSo definitely simple's the way to go. And that takes us to our final category that you had in the article there, singular. So, explain singular to us.
30:50Dima KotikYeah. So, singular is a simple idea. Do not repeat yourself, right? So, if you did it one time, you shouldn't have to redo it the second time. So, singular, it has more to do with package level, right? So, you have similar tasks, they need to be grouped, they need to be together. That helps with cognitive load because the other thing you have when you have similar functionality kind of spread out throughout your program, You have a little bit here, a little bit there. You end up traversing huge territory just to try to figure out what this or that thing did. Yeah, so singular, put it together, and it just doesn't mean just only one function, only one, you know, one-to-one entity relationship. Not necessarily. You might have multiple entities. But what you want to do is also you want to group things that are similar singularly, like meaning they're kind of in the same pile. That's on a kind of a higher meta level. It's harder to do because that requires planning, and it also requires refactoring. Like, one of the massive reasons why we do refactoring is because we get out of the singular issue, because you end up writing fast, you're copying-pasting code from other parts of your program because it looks similar, but it probably is suggesting to you, the program is suggesting to you that it needs to be refactored. And layered perhaps so that some functionality can be removed onto a separate layer, separate management into its own package, do it there, and then apply that. Kind of the antithesis of singularity, that's the wrong way to do it, is the infamous utility package. Every large project has it, like the kitchen sink of stuff that doesn't fit anywhere, throw it into a utility package. Yeah, that's not the way to do singularity. That's very close to God object, which is the opposite of being singular. When you hang everything on your session object or you hang everything on your database model and you try to do way more complicated things than your database layer, for example, should do. So, singular means stratified, separated, grouped, in essence.
32:57Robert HurlbutSo, what's the security takeaway then on the singular?
33:03Dima KotikYeah. Well, singular, you try to think of it this way, right? So, if your program is a castle and you have good defenses, we talk about defense at depth, right? Or in-depth defense in depth. So, you have multiple layers of obstacles for an attacker to overcome. There are some standard blocks, and then there is an AI agent that's watching your application dynamically. There's a proxy perhaps separating you from the internet that's kind of watching for intrusion attempts, preventing intrusion attempts. And so if you think of it, each castle wall is the defenses against your main, you know, on the hill, your main castle, and you don't really want enemies to get in there. Well, the application to security here is you want to have as little wall as possible, especially when you do defense at depth, because each layer, I mean, it automatically adds complexity, but it also lengthens the amount of walls. So if the first layer is like, you know, a football field in circumference, then you add another layer above it. I mean, that's just going to be at least twice, you know, 3 times longer than the layer you just covered. And all of a sudden it gets way out of hand. So if you have an army, if you have your archers, you know, you have your utilities and you have your scanning tools that are watching your back, you want those archers concentrated on those walls so the fire is thicker, so to speak, right? So, singular means shorten those walls, you know, less, less, less, less, especially around your core so that when you end up adding layers, it doesn't become this unmanageable creeping mess.
34:40Robert HurlbutSo, this has been very beneficial to understand the Python use cases, to understand Zenith Python, and then tying all the application security ideas, concepts, and things into this from, you know, a readable perspective, explicit, simple, singular. Now, as we're coming to the end of our conversation, what would you say is the key takeaway or the call to action that you want to leave our audience with? What should they do as a result of what we just talked about?
35:13Dima KotikYes. Well, for Python, number one thing is that we're actually calling people to the simplicity of the Zen of Python, to go back to those principles, because Python has kind of strayed over time. The big thing right now is performance, Everybody wants more performance, everybody wants integrations, hot new features, everybody wants all the latest bells and whistles, the cool stuff. And it's so difficult to resist that, obviously. But actually, the original idea that Python had expressed in Zen of Python is excellent security advice. Python standard library could use a whole lot of Zen of Python. Big Python projects, most of them could use a whole lot of Just let's go back through and look at our packages and just walk through the 19 principles, see how they apply. Refactor. Refactoring is good. Going for simplicity, just the choice. The other big thing is dependency reduction. Like we have a dependency bloat. There's so many more dependencies for each project to install. So that needs to be actively fought against. Like people need to go through and say, what features can we drop? What features can become plugins? That's the other thing. You know, a lot of times we add a feature. Instead of adding extensibility, because that's a more Pythonic way of approaching things, right? So you want to have extensible core rather than complicated core. So you want secure, something that's very secure, very robust, have it built as extensible. So very lightweight. What do you actually want to do? Have extension points and let the other people, you know, handle the extension points. You just guard the interface, you know, protect the interface. Then you have— there's less things to worry about. If it gets out of hand and your interface is bypassed, then there's less things to again worry about because you have all the loggers attached at the right places and things like that. So for the Python community, it means that, you know, let's go back to the basics. Zen of Python is actually really good. It's really good for security. Let's live it. For other languages, it's the same thing. Let's consider, you know, how can Zen of Python can continue to be applied to new projects. There's new things being released. There's the whole family, interesting family of Lisp languages, which actually at the core, in the whole idea of Lisp, like, let's write something so simple that has only one operation and parameters just in a list processing instructions. That's very Pythonic. It's very curious, very interesting. But have you tried reading Lisp code? The bracket. Oh my goodness. Right. It's just awful. Too many brackets. And it comes out unreadable in the end, even though it's considered initially to be a simpler thing. So Lisp, I mean, if somebody took Zen of Python and just did something with Lisp, maybe as a white paper or as a guidance, that would do some really interesting things for security and for the programming community in general.
38:11Robert HurlbutVery cool. Well, Dima, thanks for taking the time to walk us through and explain. And I know you've been the person at the center of Security Journeys Python-related secure coding guidance. So this is just another extension of, of the direction that we've been going in and helping people to do secure coding, to code better from a security perspective in regards to Python. So thanks for taking the time and look forward to a future conversation where we talk about All things Go and secure coding.
38:41Dima KotikThank you so much for the invitation. Have a good day.
38:44Chris RomeoThanks for listening to the Application Security Podcast. You'll find the show on Twitter @AppSecPodcast and on the web at www.securityjourney.com/resources/podcast. You can also find Chris on Twitter @edgeroute and Robert @roberthurlbut. Remember, with application security, there are many paths but only one destination.
6,982 words · transcript by assemblyai
More on Secure Development
View all episodes →- July 9, 2024 · 1 hr 5 minTanya Janca -- Secure Guardrails
- September 20, 2016 · 44 minChris and Robert -- The Activities of the Secure Development Lifecycle
- February 26, 2025 · 49 minTanya Janca -- A Secure SDLC from a Developer's Perspective