Good.
Nine o'clock.
First, then people.
Welcome.
Good morning.
And thanks for waking up early to be here with us today.
So, if you read the news lately, these last days, there was some publications about some issues found in open SSL.
Right?
With some security security issues, due to some bugs that opened back door.
In open SSL, some of these were found by artificial intelligence.
And some of these were present for more than 20 years in the systems.
That's a bit what the situation that we have with the PHP engine.
And that's why we have Alexander with us today to lead us through this story.
So, Alexander is the city of 80L.cop.
Let you go, go, go.
Right?
This is also an active contributor of the PHP Franken, and also a contributor to the PHP language.
So, ladies and gentlemen, please welcome Alexander Dubois.
Thank you.
Really glad to be here to present some security talk and talk about PHP.
Really glad to be at first them.
This is actually the first time I'm coming to this event.
So, yeah, pretty excited about it.
It's really impressive the size of the event and the number of tracks that are in parallel.
So, yeah.
Really glad that you choose this one.
And this is a right choice.
So, yeah, let's talk about live exploiting PHP engine security bridges.
So, I'm Alexander Dubois.
I am citywatletiel.cop, French company, based in Lille, near here.
I'm part of the symphony core team, symphony which is PHP framework.
So, how many of you maybe know symphony?
Great, and who use it?
Oh, not great.
Maybe more larvel or things like that, I guess.
Yeah.
Okay.
So, yeah, I'm also part of the Franken PHP and PHP core maintainer team.
And yeah, this is why I'm going to talk about PHP.
Because this is my main expertise domain, let's say.
So, at Lille.cop, we maintain OSS projects.
So, we are French company that creates on-demand websites, applications and so on.
But we also maintain open source projects such as symphony, API platform,
API platform being like an extension of symphony.
Which allows you to create easily API rest API restful APIs and things like this.
We also maintain the PHP interpreter, etc.
We are a few in the company to be a core maintainer of these things.
So, I'm not the only person that maintains these projects.
We are like three, four, five to actively maintain those projects.
And so, yeah, as you can guess, PHP is our expertise because main open source projects are created.
For PHP or in PHP.
And yeah, PHP is very old.
The first time it was released is like in 1994.
And then in 60 years later, in 2000, then giant 1.0 is released.
And this is a huge improvement for the performances of the language.
And then four years after that, then then giant 2.0 is released.
And this is the first time PHP can embed the object oriented programming.
Before that, it was just functional programming and so on.
And then in 2004, then there is object oriented programming.
And in 2020, we have the just in time compiler that is introduced.
So, just in time compiler is like a big optimization for CPU intensive applications.
So, if you have like a lot of calculations and math and things like that, it's a huge per boost for free, literally.
And it works really well.
And then in 2025, we have PHP 8.5 that is released.
And we are currently working on PHP 8.6 that is key to be released in November, 1226.
So, yeah, 30 years and counting.
And I'm showing you this to show you that the language is old.
That's right.
But it's continuing to evolve year after year.
And bugger fixed and new features are introduced.
And it keeps, yeah, catching up with modern languages and modern text and stacks.
So, it's not like PHP 8 is dead and things like that.
It's more alive than ever.
We have the PHP foundation that now sponsors full time and part time code developers to maintain the PHP interpreter.
So, yeah, the future of PHP is assured.
And yeah, we'll see PHP in 10 more years for sure.
So, this is a good look.
The Github page of the PHP interpreter, PHP source.
And we can see that we have more than 100,000 commits in 30 years.
It's huge.
So, yeah, this is a number of commits since the beginning in 30 years.
And if you take it on those entire lifetime of PHP,
it's nearly 5,000 commits per year or 13 commits per day.
And the average time of 2 hours between each commit during the last 30 years on the PHP interpreter.
And this is thanks to more than a thousand unique contributors.
And yeah, my nearly 40 Github stars.
So, again, I'm showing you this to show you that this is really PHP is really a project that is evolving and being maintained.
Actively, like with 2 hours of average time between 2 commits.
And it's not abandoned, I think, and it's still an excellent choice for your application.
If you want to start a new project and things like that, this is definitely a good choice.
And PHP powers 75 to 80% of the web.
So, thanks for a press.
Of course, if anyone wants to create an e-commerce or things like that,
of course, they're going to have a look at a press.
Thanks to all the one-click solutions provided by the cloud providers and things like that.
But here are still PHP powers 75 to 80% of the web.
And this is huge, of course.
And as you can imagine, security is a big challenge.
This is the most important yet complicated topic in tech projects.
And with a project that powers that much websites all over the world,
you can imagine that this is really a big challenge as well.
So, if you have a look at the GitHub page of the projects, again, you have, of course, the security tab,
and all the security advisories that are published for the PHP source code, which is all the security vulnerabilities that were discovered in the source code.
And of course, this is not all the security advisories for the last 30 years.
It is just since PHP is on GitHub, but still.
We have publicly disclosed security advisories that are just available here.
And yeah, so you can see on the right some score on some severity for those bitches.
And this is given thanks to the CVSS, a common vulnerability scoring system.
So, this is a way to give some security escort to Narbitis and to know if this is bad or really bad.
So, you have many factors to determine if this is bad or really bad.
The first one being the attack vector.
So, this is, this is, this vector is how you can exploit this vulnerability.
Is it by plugging a USB stick? Is it by the network?
And things like that. So, attack vector is this.
Second vector is attack complexity. Is it super easy for anyone to use this vulnerability?
Or is it super complicated and you have to to know many prior knowledge to exploit this vulnerability and so on?
Third factor is privilege is required. Is it security vulnerability accessible to anyone?
Unauthenticated user and so on or does it require to be an admin on the website or to be authenticated and things like that?
User interaction. This one is pretty important because this is, you are going to tell if the security vulnerability requires someone to do something on its own to use it.
This is really bad if you have a security vulnerability without any user interaction because this means that you can just use a virality without anyone noticing or doing anything.
And of course, it's order for the security vulnerability to be exploited if user interaction is required.
This factor is a scope. So, does it affect the whole project or just a tiny bit of the project?
Six one is confidentiality. This means that does your security vulnerability is known by everyone.
So, this is really bad or no one knows that it exists. So, this is a better situation, of course.
The seventh is integrity. Those security vulnerability compromised some of your data or not.
So, in the case of the PHP interpreter, it doesn't make that sense but keeping mind that this scale is for all projects and yeah, this is why we have this kind of factors.
And the last factor is availability. So, is it does it touch many versions of your project?
For example, in the PHP source, if the security vulnerability is actually touching like versions since like 10 or 20 years, this is bad, but if it's only on the latest versions, this is less bad.
So, this is how you can know if a security vulnerability is bad or not, thanks to the CVSS V3 here.
And once you have answered all those questions, you have this, which is the string that represents everything that you just answered.
And you can see that it's just actually all the factors that we saw with an answer. So, for the first one, we have AV, so attack vector and N, for example, or network or things like that.
And we have also AC for attack complexity, high, low, non, things like that.
And with this string, you can have the final score that you saw earlier on the GitHub page with the moderate low and so on. This is a thanks to this that you are able to categorize availability.
So, depending on the score you have, the CDRT is different, so zero is none. Of course, zero to 3.9 is low, 4 to 6.9 is moderates 7 to 8.9 is high and then 9 to 10 is exceptional and critical.
As you can imagine, critical and exceptional are not happening that often. Otherwise, we are all knowing that it is happening, like the XZ that we, security vulnerability that we saw, like one or two years ago.
But otherwise, most of the security theories are between zero and seven, let's say. So moderates and low are the most common vulnerabilities of security.
So, know that you know how we can categorize security vulnerability or security weakness. Maybe we want to know how they really look like.
Because we all know about security, we don't exactly know what is it or how to use them actually, like how people that have bad intentions can use them and why they can use them. So this is what we are going to see.
And I would like to present those first. One, I'm going to present is a CVE 2025 11.
So new bad termination in host names. So this is something that happened last July in the PHP interpreter. So this is pretty new and yeah, this is what we are going to see.
So this CVE is about opening a so-cat in PHP with the built-in function fso-copen. So for the people who know also a bit of C language, you also recognize this function, of course.
Because sometimes PHP is just a CVE. A lot of system functions and built-in functions of PHP are actually just wrappers around C functions.
Yeah, a few things of course to make it work with PHP, but it's just a wrapper.
So it looks like this. We have the PHP function. So in this example fso-copen, when you call the fso-copen in your scripts, then we are going to call the wrapper in the PHP interpreter.
Register this function and say, okay, I know this function and I can, yeah, just through and call it in the RIMC function.
And not most, but often in the PHP interpreter, this is how it's done for system functions and low level functions.
And yeah, the problem for the CVE is just here. It's not really the function, the PHP function itself.
No, the wrapper of the PHP interpreter, but actually the underlying C function, but the underlying C function is not the culprit also.
Yeah, we are going to have a look at this.
So to understand how this security bridge works, you have to understand how strings are managed in C.
So storing hello in the C language requires six memory blocks. So five memory blocks for the actual string and then one memory block, when additional memory block with a new byte.
This tells the C language that this is the end of the string and this is a convention that all C programmers knows that the new byte is actually dominating the string.
Because when you are manipulating strings in C, you are not manipulating just a string.
Actually, you are manipulating a pointer to precise memory address. So you are at the first address with the H and then you also have the rest of the memory before that and the rest of the memory after that string.
And if you want to pass the whole string in C, then you are going to just advance the pointer one by one, read the memory block.
And then whenever you are going to encounter the new termination bytes, then it means that this is the end of the string.
And we do this because if we try to read the memory block just after this one, we are not allowed and it's a null defined behavior, but it will likely crash and provoke a cycle.
So this is how you know that a string is stopped in C. And the problem here, this is the whole problem that led to the security advisory.
Because in PHP, you are like, okay, I'm currently manipulating the string, just a string. And in C, you are, I'm currently manipulating a pointer.
So in PHP, because it's a loosely typed language, you have a huge structure to represent all variables, to represent your variables in your PHP scripts, with its typids value and so on.
And many, many other properties like that, but you are manipulating, yeah, just a string. There is no manipulating the pointer, there is no manipulating the null bytes for the end of the string and so on.
So the two representation are pretty different, and of course, C is more low level.
And the problem with the CV is that the PHP interpreter is calling the underlying C function that relies on the null bytes to determine the end of the string, where in PHP, it's not a problem to have a null byte in the string.
So it would look like this. We would like to open the sockets with F sockets, so we have local hosts, and then we put the null bytes.
That's what we are going to see. But then the rest of the URL and the ports, and then we are going to write into the sockets, and then it opens the connection and we write something into it.
But what's really happening here? This is a question. And this is what I want to show you right now.
So let's take PHP storm, yeah, it's big enough, I guess. So we are going to type in with when and so, sorry.
In this one, and we are going to just on the trainer.
In the meantime, so yeah, my container here is just a PHP version, so 8.3.22.
This is the latest version affected by this problem. So this is why I chose this version.
And then we just copy the source into the repository to have our PHP server and we expose port 8080. So yeah nothing fancy here.
One thing that I want to show you is, so okay, we run the container like this, so we expose the port with superb name here, vulnerable PHP, and also we are going to create a secret service.
Into the existing container, okay, so this means that we are going to have a secret service or secret PHP service that is living right into the container.
So it's not accessible from the outside of the container, but only by services that are inside the container because no port is going to be exposed.
So I'm going to, like this, so we have our secret services with some API keys and some environment variables and so on.
Okay, so now we are ready.
Or set up as well here, and I can show you how the security vulnerabilities that I show you can be used.
So let's get here and let's have a look at the first query.
So we are going to call localhosts with a host and a file.
Basically what we are going to do.
Let me show you is we are, okay, so we are getting the request.
We are gathering the hosts and the file parameters that are given in the query parameters, okay.
And we are going to ensure that the host that we are providing is actually ending with secret partners come.
So let's just imagine that this service is like, okay, I want this file on this URL for secret partners, so gather the five for me and then send it back to me.
Because maybe only our PHP server can access the secret partner and so on, okay.
So we are ensuring that it finishes by secret partners come.
We will try to read the file on the server.
And then we are going to open the connection to the hidden service, well, to the service, I mean.
So if so, open with the host that we provided, some error management here.
But if it succeeds and the sockets is open, then we can write an HTTP request.
So we are getting the file and then we are writing into the sockets and we are waiting for response.
And then we are going to wait for the response and then display it to the user.
Okay, so this is what our script is doing.
We check that it finishes by secret partner and then we are opening the sockets and retrieving the file.
So if I'm doing this, we can see that an authority is domain.
Why? Because our host here is not ending with secret partners come.
So of course, it doesn't work. It is expected.
But now, the moment of truth, we have a second query here and we have hosts.
So local host again, then we have a null byte here because it is load in the query parameter.
And then ending with secret partner that come just as we wanted to have in our indexed PHP and then the file.
And if we run this, we can see that we actually gathered something.
And this something is actually a secret service that was inaccessible from the outside of the container.
So what's actually happened here is that, okay, we sent local host null byte secret partner come.
So of course, this one passes because it ends with secret partner come.
And then the host is provided as is to fsocopen.
But fsocopen is just a wrapper to see underline function.
And whenever it finds a null byte, then it will say, okay, this is the end of the string.
So what happens is that it will see this and say, okay, this is my whole string.
So I just cut here and then I will connect to my local host.
And the whole thing here is discarded.
And because I started some secret services on the local host inside the container,
then because PHP is running also inside the container, we are able to access this secret service.
All of this because fsocopen is just a wrapper to the c function.
And whenever it saw the null byte, then it stopped and said, okay, this is the end of the string because everybody does this in c.
And this is how, yeah, this vulnerability could be used in production until, yeah, version.
It's like 8.3.22. So it was discovered last July.
So it's not something that is old and like 10 years ago, I think that's, this is really something that is recent.
So yeah, this is how you can, this is a security vulnerability that was patched.
Lately, right, this is for the demo for this one.
And we just did SSR, so server side request for jury.
We asked another server to create malicious requests on our behalf.
And then the server, the remote server sent this malicious request for us without us to do any request on our side.
And this is a 5.9 on the CVSS score.
So this is a moderate security advisory.
But yeah, as you can see, even if it's moderate, it's impactful.
And pretty easy to use, actually, because you just have to, yeah, put a null byte somewhere and you can put and should use it.
So it's moderate, but impactful.
That's a bit of the problem of this scale, because we could say that's okay, it's low or it's moderate.
So it's not that bad, but actually, even if it's not critical, it could be impactful and should not underestimate what happens with security vulnerabilities like this.
So yeah, language wouldn't raise our attack surfaces.
So PHP is memory safe. She is not.
And the boundary is where bugs are born.
Yeah, it's like, it's not necessarily hold code that was a problem, but yeah, we had interface between two languages that don't have the same represented internal representation of variables and things like that.
PHP strings and C strings are not the same, and because of implicit assumptions, we have vulnerabilities and it's not hard code that was a problem.
It was obvious code, because of course, you are doing this wrapper and you don't necessarily think about, yeah, the null byte is different in C and so on.
So it was obvious code that led to vulnerabilities like this, so pay attention to this.
And yeah, security audits should include the runtime, so just the user name, not just framework.
You should also maybe audit the engine itself, and it's difficult to audit anything, your app or things like that.
But correctly, if you don't have a deep understanding of what happens underneath and how the engine turns on works actually internally.
So yeah, to prevent this, we could just have sanitized a bit more the input and we could have just, yeah, say, okay, we take the host and we are going to sanitize and remove all the forbidden characters.
We don't want to see like null bytes or yeah, whatever forbidden character you want.
But we could have protected ourself easily by always sanitizing their inputs, always, always.
Okay, so that was the first view of the idea I wanted to talk about, and now we are going to talk about the zero-dion bug door and when a full remote control bug door made it to one of the real estate of PHP.
Yeah, this one's bad because bug door is bad, nobody wants a bug door.
Back doors are intentional entry points in malicious entry points in a project in an application where it gives full control to someone just by doing something special.
Like sending a special request and sending a lot and then this server is able to give full access to the people that know the bug door, but it should be invisible.
And this is what we are going to see because this is quite an interesting story.
So all begins with this commit, skip CI, fix typo.
Fix typo, it looks pretty innocent, what could go wrong.
That was on March 28th of 2021, so just four years ago, four or five years ago.
So this commits, here is its contents.
So yeah, what we can see is that it's not typo, definitely.
We don't know exactly what it is yet, but that's not just typo, of course.
This was added in zlib.c, so you can see on the top of the screenshot, the file.
And this is very important because PHP is built with some an extension mechanism, which allows you to enable or disable extensions in your PHP setups.
To have like a minimal PHP installation or have more features if you want to.
But this one's a limit is enabled in every installation of PHP by default.
And it allows to compress responses, sense back to the browser.
So that's why it's enabled by default in PHP.
So this means that the snippet that you saw would be put initially executed on every default installation of PHP.
And this contains all the PHP version distributed by major Linux distribution.
So db on Ubuntu and things like that have this extension enabled by default in their APT repositories.
And then the whole thing is about this HTTP user agent with 2G.
And this is the key.
So what you have to know is that whenever PHP gets an HTTP request, it will automatically parse the HTTP adders and put them in a global variable called HTTP globals.
And then they will be renamed like this.
So this one, this means this is the actually the user agent HTTP adder.
But we still need this type of course.
And we are going to see what it is. So this is the heart of the code that was added in the fixed type of code.
So basically what it happens here is that the first line so right in two lines is okay in the HTTP globals array.
So where are all the HTTP adders find an entry with the HTTP user agent with 2G again.
And if that case have a look at it's value.
And if the value of this header starts with the zero-dium string, then then you are going to call this and ever string.
And this function is basically telling PHP okay this is PHP scripts executed right now.
So you feel it coming okay and this is pretty bad because basically if you have an HTTP adder called user agent with 2G.
And the value starts with the zero-dium and you put anything any PHP scripts just after that.
The server is going to execute it right away.
So we are talking about zero-dium which is a zero-dave in the Arabic marketplace. You saw it in the code.
Actually that was just like a troll or things like that of the person that did it to make it harder for the maintainers to understand where this comes from.
But actually zero-dium which is a known marketplace as never is not related to this.
So the disturbing discovery is that this commit so the skipsi fix type of actually created and pushed by Rasmus Lerdorf.
And Rasmus Lerdorf is the creator of PHP.
Yeah that's strange then this commit was reverted by Nikita Popov which is one of the biggest contributors of PHP.
Okay and then just after that the revert was reverted by Nikita Popov.
Right and then finally the final revert was done by Levi Morison.
So they be your what happened why one of the biggest contributors of PHP would like to revert and then reintroduce it and why the creator himself would like to introduce such backdoor such obvious backdoor in the code.
Well this is something that we are going to see just in a few minutes but all everything that we show you there it was just in a matter of a couple of hours.
So it was pretty quick it was quickly seen that there is a problem in the source code but yeah it was reverted like in a hour or two after the first commit but you have to know that the commit was actually pushed to the
release candidates of PHP and this is the biggest problem. Before going further I would like to show you how you and how this would have work if it was actually in the final release.
So just here I'm going to just stop and it's one and the keynote of course the ways and then to the second one like this.
So in the second directory we have yeah so index.php so just this one whatever way it's every request with response with a little from index.php and that's it.
And here I have compiled a PHP binary with the backdoor so you cannot compile it now because it's too whole version but I took the latest version of PHP and cherry picked the commits just to show you how it would have work if it was in the final release.
So we have the PHP compromised here so don't deploy this one on your service please.
And we are just going to again like this okay so we have an HTTP server like this but it's compromised and I recall that we just have a row in the index from PHP and we are going to send requests like this.
And as I told you we are going to send the get requests or first or anything like that with this.
HTTP editor so user agent with 2G the string 0dm and then any PHP scripts just after that and here I choose to use system and then go to some directory and then print the directory and list everything in it.
So if we ever run this request like this we have a response we have the response from the screens but just above.
We have everything here so it printed the working directory and also it listed everything I have in this directory and I just put here a system but I could have extract any file actually it truly any PHP.
PHP scripts but you can put in there so you can imagine what would be the images if we would have made to the final release but luckily it didn't make it to the final release so let me stop that.
Imagine if this was in PHP right now I would mean that 80% of the web would be vulnerable to this kind of attack which is exceptional in this case because at a vector is super simple you don't have to be authorized.
You can compromise any data super easy to use and you don't have to you don't need any user interaction to have it well this is it would have been a critical or exceptional security vulnerability in this case.
Actually I told you that the creator of PHP committed this it was actually because the VCS server was compromised.
Do you know that gets doesn't check anything in your name or thing that you could put any name you want when you push a commit in the get server until that and at this time the PHP organization was hosting its PHP source code on its own VCS server and this server was compromised and this is what led to it being act.
Actually it was of course not Rasmus Lardorf or Nikita Popov that committed this apart from the reverse of course.
But the actual commit it was some impersonation from someone we don't know who it is but they made it and they nearly made it because I told you it made it to the PHP 8.1 release candidate one.
So it's not like a development version or an alpha or beta it made it to release candidate and if someone didn't code that then it would have maybe it would be still in the source code right now.
So from this they GitHub became the official repository of the PHP organization because they were like okay we are hosting our own GitHub and it just gets on the so do we really want to maintain this and have to.
Yeah, they teach and patch security the Narbitis and so on or self the response is no and at this time GitHub was just a mirror of the PHP source repository.
But yeah, then they decide that GitHub would be the source of truth and they don't want to maintain any VCS server anymore themselves and yeah let that just GitHub do their job and it would be better.
But we can still find the commit on GitHub as I show you.
The screenshot that I show you earlier is still available and we can see some people that commented on the on the comments on the commit sorry saying what's that so it's not a typo and so yeah pretty funny so yeah trust is not a security mechanism.
It was created by a repeatable author's well it seemed to on a repeatable project but it was still compromised and this is because.
Yeah, okay we see Rasmus Lardo of the creator of PHP and so on but it doesn't it doesn't mean that it's this person that created the commit and yeah it's not because you see a famous name or thing like that that this is security mechanism.
Once again because it's VCS and all those tools well doesn't verify the identity.
By default so you can also have then you can have gpg and so on but I mean by default there is no verification whatsoever.
The first structure is part of your tweet model so VCS here if this process everything is.
Yeah part of your tweet model because everything here can be yeah compromised it's not just about your source code or it's not just about.
Yeah reviewing your commits and put requests and so on here it's not the problem the problem here was that the VCS was compromised so.
It's part of the street mode even if we could think that okay just the T the CI and things like that so we don't have to bother but yes you have to bother.
Open source is not even but it is resilience.
Thanks to open source it was detected and publicly documented which wouldn't have been possible if this was not open source if it was proprietary source code then nobody would have noticed maybe.
And maybe we will have this back door in our in our PHP installations but this is only possible because of open source and this is why we always say that open source is more secure than proprietary software because this kind of thing can be audited.
And seen by a hundred and thousands of people that just look at the code by curiosity or want to do some security audit and things like that on those projects and yeah this was detected thanks to this and because the source code was open to everyone.
So yeah these are the few takeaways that I told you so yeah language boundaries are attack surfaces that structure are not the same everywhere.
Security audit should include the runtime and sanitize your inputs please trust in nature security mechanism.
Picture of your in front and open source is not even but it is really resilient and this is why we love open source.
So yeah this was a two bridges that I wanted to show you and yeah I really hope that you liked to.
To yeah understand what are those security but she's how do they look like actually in the code and how they can be exploited by people and to yeah know who to protect yourself again them because we always hear about security which is having their abilities and so but we actually don't really know what it is.
Or what it looks like so I hope that I give you a give you a glimpse of what it is in security and yeah if you want to.
For me for more blog post and things like that I'm being a space engineering goal if you want to have a look next.
Thank you very much.
We have seven minutes for questions so yeah there is one here.
I thank you so for the first one you talked about how was it discovered.
So yeah the the first security bridge was discovered well actually I don't have the name but there are people that are.
sending emails to dedicated address of course if you discover some security vulnerability do not discuss them publicly and do not put them on an issue and GitHub of course there is always dedicated email address.
like security at PHP.net or things like that and yeah someone sent an email saying okay I have this proof of concepts this is how you can.
Yeah compromise something with this function and then we just have to patch it and it's the same for every.
I'm hoping to project I maintain symphony front in PHP and so on everything all these projects always have.
The dedicated email address where you can send some proof of concept and so on and we are going to acknowledge this problem quickly and tell you if it's actually confirmed or not.
And yeah most of the time it's like this that we are aware of this which is.
Yes no.
I know it was super clear so fine.
Okay.
There are still five minutes so if you change your mind if you have a question and don't be shy you can come.
If you have any question and just here so yeah just get me up.
Thank you.