May 16, 2024 in DevSecOps by Zoltan Toma15 minutes
In my experience, DevSecOps best describes what I’ve done. Although I prefer Lead Security Software Engineer (Good luck finding a description that can be understood by HR). But when I mention in a conversation that I developed server security software in PHP, everyone is surprised.
And that’s the end of the conversation. (Unfortunately, this usually happens in interviews.)
Absolutely valid points. But when YouTube accidentally suggested this video and I saw this reaction, I had to rethink my attitude.
Source: PHP Doesn’t Suck Anymore? | Prime Reacts
Original video: PHP doesn’t suck (anymore)
Let’s start at the beginning. Why PHP? The answer is simple. I wasn’t the one starting the project.
We needed a couple of developers who could code. And we needed a server-side script language that could be easily run. The software is designed to solve shared hosting server problems. And what do shared hosting system admins see every day? PHP code.
Sure, there is Bash and Python is available on every Linux server. But what do you read day in and day out trying to figure out how the heck the server got hacked again? The client’s site? PHP.
But why didn’t we switch to a faster, safer language later? I’ll write this down as well.
There was another reason the code was in PHP. Many have since forgotten this. How do you trust the “security” software of an unknown small company?
I always raise my eyebrows when I hear this statement. Why do you think it not safe?
When was the last time you looked at an actual PHP project? Which wasn’t a Wordpress plugin? (But they have already made great progress there as well.) What they usually think of are the HTML, CSS, JavaScript, PHP monstrosities taught in bootcamps or created by beginner developers. Which are all in one 20,000-200,000 line monster file. They really aren’t safe. But not because of the language. But because of the inexperience of the developer.
The same mistakes are present in any language. You can still make an XSS error if you don’t validate the input or format the output as HTML safe, in Java, C#, Go, Python. If you don’t use prepared statements, you will have a SQL injection vulnerability.
But have you ever had to write a Buffer overflow exploit? Or perhaps a format string exploit? These are not present in the language, because they are handled at the language level.
You will be surprised about the types if you watch the video.
When I hear that PHP is slow, I just nod slowly. Well, yes, in PHP 5.6, the language was really slow. But how could it be accelerated? Let’s say you changed web server? Yes. PHP code is usually served by a web server. It’s just that the web server itself is not able to handle requests fast enough.
But the code we wrote ran on the server. It was not connected in any way to the web server on the server. So we had no such limitation. But this raised another interesting question. Do we need a PHP plugin for web services? No. So what if we don’t use them? In fact, we shouldn’t even load them?
What do you need for this? A custom PHP runner must be created where these plugins are not included in the created binary. Only what is absolutely necessary to run PHP-CGI. And imagine if you don’t load unnecessary modules into your program. Would you think it would be faster? Much more faster.
I did a benchmark a long time ago. But I have to disappoint you. In terms of string processing, Python 3.x moves at a similar speed as PHP 5.6. How can this be improved? You use Python C bindings. Which essentially transfers the operation of the Python code to a faster plugin written in C.
What do you need for this? You nned to install Phyton 3 first. Because most operating systems don’t have it by default. Then you have to build a C binary locally on the server with the C compiler located on the server. (Wondering why it’s not good to work with Python on Alpine? That’s why.)
So I need to install a package. In which extensions are written in C to speed up processing. Just wait a second. This can also be achieved in PHP. Because anyone has the opportunity to write PHP plugins, extensions in C, C++. And PHP 7.3 was already about 8x faster compared to its Python counterpart.
And if I tell you that after installing the php_aho_corasick
module, we achieved a 7000% speedup in text recognition, even after that. I think you won’t believe me. (I did not make a mistake. The improvement was 7000%.) But I was the one who started porting the extension from 5.6 to PHP 7.2. See https://github.com/ph4r05/php_aho_corasick/pull/5. (Sorry guys about I couldn’t do more to help your work.)
So why didn’t we write it in C? Have you ever tried to solve an edgecase on a remote server? Where you don’t have other permissions than SSH and nano? A dynamic language was needed.
For quite some time I have been trying to get into the development of a security software that uses Go. There is a reason for this. But when we start talking about security technology, acronyms immediately come up. Have you ever dealt with application security?
What they mean is this figure from the OWASP DevSecOps Guideline:
Source: https://owasp.org/www-project-devsecops-guideline/latest/
Oh, I know this figure. I have tried many tools on it and other alternatives as well. But to be honest, I haven’t found anything better than the free extensions that can be installed with php composer. And imagine. They can also be run locally. I don’t need to subscribe to a SaaS solution just to write secure code.
The annoying thing about the whole thing is when I finally get into the project and see that not only is the full DevSecOps pipeline not implemented, but not even a basic Linter is set up. And the interview was about whether I had already used SonarQube and Snyk, or had I set up ZAProxy.
What kind of security expectations do you think we had if our software was installed on potentially hacked to root servers. And nothing else helped? In addition, all supported distributions had to work the same way.
I have to disappoint you. There are also only Linux servers on the cloud. They have deployed our software on AWS, Azure, GCP, Linode, etc. And guess what. Malware hits and blocked incidents also came from there.
The Cloud provides a solution for only one thing. For scalability. But mostly for their own scalability.
Let’s start at the beginning. Where does the DevSecOps pipeline start? Locally. A developer sits down in front of his computer and starts tinkering with something. There is no commit, no collaboration, nothing. A developer sat down in front of the machine and works. If you are done with your task, you would like to publish it.
Do You need git? Not necessarily. It is enough to upload the code to a server. Let’s say in a zip. (Thanks AWS for still having this bullshit…)
But if several of us want to work together on the code, we have to figure out how to do it. So why not use a version tracker? This could be git. Git’s job is to help people edit text files together. No more, no less. But what goes in and what happens with the changes is a completely different question.
There is nothing more annoying than when someone commits code to master on Friday night that is missing a semicolon. Then at dawn the phone rings that the site needs to be fixed because customers are complaining. That’s what Lint is for. It can be installed with composer. Let’s say `composer require –dev overtrue/phplint’. Then I can check from the command line that there are no language errors in my code. No more Friday night phone calls.
But wait! Composer? That is, can I manage packages and simply download them? Yes it can be. Package information is available in composer.json
. What You can check with, say, Trivy, Dependabot, there used to be a security checker that could be installed with composer. But as I read now, the `composer update –audit’ switch is also available.
Two things we say in security. Update your software. And check regularly that there are no vulnerabilities. This is also ticked with one command.
But if we can use composer, we can also install other add-ons that make our work easier. These can be accessed from the autoloader. And with this, we can get to know the PSR-4 standard. At a standard level, it is defined how I can split code into multiple folders.
I don’t know where to put my additional scripts? In the utils folder, in the scripts folder? How can I refer to them? It can drive me crazy when I have to research how individual files are connected in an unknown code base.
But when it comes to standards. PRS-2? How do we format our code? Should we use spaces or tabs now? The brace should be at the end of the line or on a new line. Do I need brackets? It is handled by a standard. And, even better, we can fix the formatting of the code according to the standard by running a command.
But if talk about code quality control. Where are the tests? Code cannot be secure without tests. Using Composer, we can install PHPUnit and write tests.
If we want something good for ourselves, we can solve the code quality control with a combined tool. Let’s say phpqa. composer require --dev edgedesign/phpqa
. Then, by running one command, we can generate beautiful, transparent, searchable HTML reports from it locally. How much is my code smell now? Oh, I see.
Because it is not enough to know how much the code quality has changed. If shit doesn’t change, it’s still shit. (Yes I mean you SonarQube)
But there are testing tasks that cannot be performed with Unit tests. So how about using it for something more serious? Let’s say Codeception? composer requires codeception/codeception
. This is a BDD framework. And we can even write cucumber tests in it.
Everything I have described so far works locally. No subscription required. No need for a pipeline. Just run one command in the commandline. The problem starts with the fact that not everyone remembers to run these commands. git pre-commit hook
is a good solution for this. You are not allowed commit until the commands run successfully. And again, you still don’t need a pipeline.
The problem is when, despite these, someone is not willing to use the tools. This is what a git pipeline is for. It doesn’t matter who is stubborn. How fast do you want to go. The pipeline runs after every push. (Or before merging, but this now a branching strategy).
What do you think what the Selenium test is? And in Codeception, there is a Selenium test driver. But of course, we can try to spin up a ZAP or other crawler, which fuzzing the application. But this requires more complex testing. It might be worth running on a build server. But this is no longer a PHP specific problem.
How much do you think I know about testing if I created an Asyncron FakeApi fuzzing module for PHP Codeception? See module-fake-api
It is not for nothing that I say that we should not talk about DevSecOps best practices if the code that should be monitored has 0% test coverage. For me, this is the most important metric. If there is not at least 80% coverage, don’t even think about DAST. What do you do when it finds something? And it will. This is also the case with PenTest. What do you do with a report if they find something? And they will.
The entire pipeline ends on the live production server. But again, this is not a PHP specific problem.
Yeah I know. Many things cannot be solved with PHP. There are better and more optimal solutions. But in this case PHP was only the manager code.
Do you need low level speed optimization? PHP module solves most of the cases.
But I’ve written PAF in PHP before. You read it write. PAF. This means Protocol Application Firewall. On an average server, not only HTTP ports are open (Unfortunately). So this resulted in some pretty interesting catches. We detected the WannaCry virus months earlier, but we didn’t have enough human resources to go after it. (Sorry world.)
But PAF most used function was serving HTTP requests. The PHP language was not able to serve this amount of requests. Therefore, it was necessary to replace the code with a more efficient solution. Which could be anything but ModSecurity.
I really enjoyed working on this project, but unfortunately we got to the 1% problem. And unfortunately, that’s what keeps me from using PHP again to build security software of this magnitude.
It is not possible to satisfy all the needs of every client in 1 package. First of all, there aren’t that many people who can do this. The other is that not all customers have the same problems. This can only be solved with microservice architecture. And no. You cannot install Kubernetes on a customer’s server. Neither Docker. Nothing more serious than a couple of binaries. You do not have the right to do so, as you do not manage the servers.
In other words, you need something that is OS independent. Binaries can be made quickly. It can be released independently. It’s easy to learn. And that is Go.
Why do you think Kubernetes was written in Go? Just because of this problem.
The funny thing is that PHP was not the limitation. What do you think was necessary for this project?
And I’m tired of listing it again. So is it possible to write effective server security software in PHP? Yes it can be. But don’t be surprised that everything else is also needed.
When I left the project, it was protecting 7,000 servers and millions of websites around the world. But it could have handle much more than that. It was just a matter of getting and keeping customers.
How does this relate to mental health? Do you think the human brain can remember so much? Have you ever been responsible for millions of websites? Have you ever woken up to the fact that more than 200 servers have stopped and hundreds of thousands of pages are not working?
Don’t be surprised that I was burned out. Nor that I forget things. Or that it takes a long time to recall things. If possible, do not use acronyms in interviews. They can mean many things. And if someone didn’t recall a tool, it’s not certain that they didn’t use a similar one. Don’t humiliate the other just because they don’t know XYZ.
I’ve been thinking a lot about an impactful call to action section. The results? Well, basically, I’ve been constantly looking at various statistics, emails, and social network sites.
So, if you liked what I wrote, please:
And DO NOT! I repeat, DO NOT follow my work. It would only feed my own Ego while I am working on the #MentalInCyber topic and trying to convey the (cyber) security-first business model.