9 ms·
Upcoming Hardening in PHP
- ChrisMarshallNY 2y ago> I find it fascinating that people are putting so much efforts optimizing exploitation techniques, yet ~nobody bothers fixing them, even if it only takes a couple of lines of code and 20 minutes. There's definite reward in having a 0-day. Either you can get a bounty, or sell it in the hacker-souk. That "couple of lines of code and 20 minutes" is sort of in the eye of the beholder. If you are a highly-experienced language developer, the fixes are likely to be a lot more obvious, simpler, more comprehensive, and robust, than if you are a relatively junior IC.
- maple3142 2y agoI think it is probably because a lot of things are deemed as acceptable. For example, the stream filter chain one is only exploitable if the input to some php IO functions like file_get_contents are attacker-controlled, and those things are already treated as LFR vulnerabilities in application, not the language runtime. Also some of the them (e.g. stream filter chain) are fun and useful enough (turning LFI into RCE), so I bet there definitely some people would rather those thing is not fixed. Given that a properly-secured application wouldn't be affected.
- eru 2y agoWell, you can produce the exploit all on your own and showcase it. But to get your fix in, you'd have to interact with the PHP ecosystem.
- est 2y agoBreaking something is easier than protecting everything from all fronts. Hackers write the worst code, but all the mess needs only one successful hit to become a 0day.
- blueflow 2y agoInstead of making a website about it, you can take any step of your exploit chain and change the code that exploit cannot possibly work, and submit that as patch. You would still get a CVE number assigned that you can add to your resume. For example, look at the glibc/iconv CVE some other user posted[1]. In the section "Out-of-bound write when converting to ISO-2022-CN-EXT" they have mapped out the boundary checks. By diagnosing the problem this detailed, they already did 90% of the work. The other 10% are the patch and writing to the mailing list. [1] https://www.ambionics.io/blog/iconv-cve-2024-2961-p1 https://www.ambionics.io/blog/iconv-cve-2024-2961-p1
- frogsRnice 2y agoMaking a website about it benefits other people; finding the vulnerability helps other people; even if its 10%, why can’t someone else do it? Surely someone doing all this would already have submitted a patch if they felt comfortable.
- PaulRobinson 2y agoI think if somebody wants to describe themselves as an "ethical hacker", and a conference wants to let people talk about exploits they've found, the minimum bar for disclosure is at least a description of a mitigation that could be taken, and ideally an actual code diff if its an open source project. There's a bit of street cred for finding a 0day, a bit of glamour about figuring out the puzzle. There's not much for the person who fixes it. I think as an industry it might be worth trying to fix that somehow.
- calvinmorrison 2y agoSelling hacks is ethical
- berkes 2y agoWhy? And: Always?
- calvinmorrison 2y agoPaying for bounties is paying for exploits. That is to say, choosing not to pay for exploits is tantamount to selling your customers off for a price, the price of the bounty.
- PaulRobinson 2y agoLet's suppose you are right. Why not accompany that with a proposed fix, too?
- frogsRnice 2y agoDon’t necessarily agree that selling hacks is ethical, but if I already spent time figuring out how to exploit a system - reporting it to the relevant place is charity. Ill do that, but Im definitely not spending time trying to fix the code if the solution isn’t immediately obvious. ++ so if you have to fight to get the bug recognised in the first place
- 2y ago
- pjmlp 2y agoWhen liability and cybersecurity laws start being more hardly enforced, many companies will certainly bother to fix them. It like no one cares to keep a kitchen clean, or a factory in order, until the inspection shows up and closes doors. Naturally even for those, we are at various levels of how those inspections are honestly enforced across the globe.
- deleted 2y ago[deleted]
- mgaunard 2y agoThe real question is why does PHP have so many bugs that it's so trivial to exploit?
- phplovesong 2y agoHistorically is has been an skill issue. It seem it persists even today
- craigmcnamara 2y agoSeems like an attitude problem.
- that_guy_iain 2y agoHonestly, the development of the PHP core has always been rather amateur. From historically just adding features whenever to know adding hundreds of breaking changes per minor release. This results in a terrible codebase and a language where upgrading minor versions is so painful and costly for some firms they end up stuck on old version. The last part makes the fact their could be massive security holes like RCE in the core language very worrying.
- ipaddr 2y agoHistorically they have been one of the languages that added very few breaking changes and were criticized for that. You can't have it both ways. Going from php 4 to php 8 isn't even that painful and there are twenty years between. It's the one language where what you wrote 20 years ago probably still works today. Upgrading a php application is one of the least expensive and uneventful things you can do. Try upgrading that java swing application or that react app that's 15 months old. Go, haskell, vue, python 2 to 3 are more difficult because of syntax changes where in php you have some breaking changes like globals being removed or ereg removal or mysql_ being removed. The changes were small like using mysqli instead of mysql or using preg instead of ereg.
- JodieBenitez 2y agoSurprised to see Go in your list though.
- urban_alien 2y agoAre these issues very particular to PHP? Honest question, this is all above my current programming knowledge.
- wbl 2y agoYes. Most languages don't have anything like the filter notation for arbitrary reads to escalate through.
- metadat 2y agoThe linked CVE-2024-2961 article is a pretty fantastic read on its own: https://www.ambionics.io/blog/iconv-cve-2024-2961-p1 https://www.ambionics.io/blog/iconv-cve-2024-2961-p1 People are so creative, I can't help but feel some hope for our future :)
- MBCook 2y agoThat’s for that. I’ve never seen it before. What a neat path they took.
- 1oooqooq 2y agoi find it boring. because it's very obvious whoever added php://filter was clearly just adding exploit paths (java flavored ones no less). there's zero valid use for that thing.
- talkin 2y agoYes. Just like the Log4j issue root cause. Too powerful and abstract features to wield securely. Or maybe if we keep intent out of it; features were added in a time when we all worried less about security and internet implications. I would like to say ‘in the security dark ages’ but we are probably still in that era. ;)
- marcosdumay 2y agoWhat a perfect shit-storm! - What people are saying about the filter protocol, and anything else that interprets the files. - Why do people insist on making all remote file protocols transparent? Fuck that, a file is a file! If you want to support some remote stuff, do that on the OS, where it's opt-in. - And PHP keeps insisting it's not a web framework while being a web framework. So it has no access control around local file reading, while clearly designing it to be used in a way where only a few directories should be accessible. - A buffer overflow in glibc, go figure... But yeah, C is perfect and the only issue is that the devs don't know the language well enough or there aren't enough people reviewing this niche library. - Didn't everybody decide to ditch the pre-unicode encodings from the standard tools? I remember the announcement (that was supposed to include glibc), it made a lot of people angry. Those have been an endless source of CVEs.
- justinclift 2y ago> Suggestion to make those parts read-only was rejected as a 0.6% performance impact was deemed too expensive for too little gain. Big Oof. :( :( :(
- ipaddr 2y agoI'm okay with the tradeoff. PHP prioritizing speed over uncommon security is the right call here.
- dev_hugepages 2y agomissing /j
- bigtimesink 2y agoAt a large PHP shop, 0.6% can be tens of millions of dollars.
- kortilla 2y agoOver what time period? You’re implying they are spending at least a billion dollars on hardware costs for 0.6% to be tens of millions.
- Tepix 2y agoAt a large PHP shop, a successful exploit can be the end of the company.
- 1oooqooq 2y agoalmost everyone have all the things required for those exploits disabled. why would i accept performance penalty if i don't allow open('https://google.com https://google.com') to begin with? the correct action would be to remove all the stupid features everyone serious disable to begin with.
- Tepix 2y ago
- Abismith 2y ago[dead]
- EZ-E 2y ago> I find it fascinating that people are putting so much efforts optimizing exploitation techniques, yet ~nobody bothers fixing them, even if it only takes a couple of lines of code and 20 minutes. Like it or not, exploiting seems just more fun and rewarding. A lot of people will be interested to learn on your blog how you came to find and exploit a vulnerability. The 10 line of code patch gets little attention. Not even taking into consideration bug bounties...
- Tepix 2y agoExploiting is mainly much, much harder. Programmers are pretty good at preventing the obvious exploits so the gaps left to exploit are the tricky ones.
- p4bl0 2y agoSomething I'd really like is for PHP to somehow be stricter on the number of arguments passed to a function. As of now, PHP emits an error if arguments are missing but not if there are too many. A way to bake that in without breaking old code would be to allow function definition to put an explicit stop to the argument list, for example using the void type keyword: function foo (int $a, string $b, void) : bool { ... } A few month ago I discussed this on the development mailing list and people seemed to agree and even suggested that this would be a good idea by default without the keyword thing I suggested. But I never got the time to properly write an RFC. There is already an old one from years ago that was voted against but In was told it was from before anything strict and typing related was considered important in PHP. If anyone's up to it, please write this RFC :) !
- MH15 2y agoI'd be curious to read about what percentage of active PHP devs use the recent features. The last time I worked in a PHP codebase (2020?) was half PHP 5 (bad) and half PHP 7 (much nicer). Curious if there's any real info out there on this
- zuppy 2y agophp 7 has been released 9 years ago.
- noduerme 2y agoYeah, and I just finished porting an enormous amount of production code from PHP 5 to 7.x before fully moving it to 8. There are so many breaking changes in each major version, when you have a lot of live projects and clients don't have the budget to pay you to upgrade them, they can lay stagnant for years until way past EOL. It would have been nice to know, for instance, that future versions of PHP would throw warnings about undeclared variables or unaccessible named properties of "arrays" - which could previously be relied upon to be false-ish. That's a major pain point in code bases that treated arrays as simply dynamic objects that could be checked or defined at will. Lots of isset() and !empty() and other BS. Fine, but it takes time to sit down and check it all. I really preferred it when it let you just screw up or try to access a null property or define a variable inside a block and access it later without throwing any errors at all. Nothing about its actual functionality has changed in that regard; it's just errors you have to suppress or be more verbose to get around. In PHP 8 you can still do this: `if ($a) { $previouslyUndefined = 2; } if ($previouslyUndefined) { echo "yeah"; }` PHP still knows what $previouslyUndefined is or isn't at the second if statement, but it'll throw an error now in the first statement if you hadn't declared it outside the block. Why? Who cares? Scope in PHP is still understood to be inline, not in block; there is no equivalent to let vs var in JS. Stop telling me where I can check a variable if you're not enforcing various kinds of scope.
- piokoch 2y agoOff topic: there are two key technologies that "digitalized and computerized" the World: Visual Basic and PHP. And Excel.
- canadiandev 2y agoThat's good, PHP is too permissive
- coding123 2y agoI found the solution: sudo apt-get purge php.*
- fghsss 2y ago### Структура проекта ``` project/ ├── data/ │ └── surveys.json ├── app.js └── package.json ``` ### Шаг 1: Инициализация проекта 1. Создаем папку проекта и переходим в неё: ```bash mkdir project cd project ``` 2. Инициализируем npm: ```bash npm init -y ``` 3. Устанавливаем Express.js: ```bash npm install express ``` ### Шаг 2: Создаем файл `surveys.json` для хранения опросов Создаем папку `data` и файл `surveys.json` в ней с начальным содержимым: ```json [] ``` Это будет массив объектов, где каждый объект — отдельный опрос. ### Шаг 3: Создаем файл `app.js` для серверной логики Вот код для `app.js`: ```javascript const express = require('express'); const fs = require('fs'); const app = express(); app.use(express.json()); const surveysFilePath = './data/surveys.json'; // Функция для чтения данных из файла const readSurveys = () => { const data = fs.readFileSync(surveysFilePath, 'utf-8'); return JSON.parse(data); }; // Функция для записи данных в файл const writeSurveys = (surveys) => { fs.writeFileSync(surveysFilePath, JSON.stringify(surveys, null, 2)); }; // Создание нового опроса app.post('/surveys', (req, res) => { const surveys = readSurveys(); const newSurvey = { id: Date.now(), ...req.body, editable: true }; surveys.push(newSurvey); writeSurveys(surveys); res.status(201).json(newSurvey); }); // Получение всех опросов app.get('/surveys', (req, res) => { const surveys = readSurveys(); res.json(surveys); }); // Редактирование опроса (если он редактируемый) app.put('/surveys/:id', (req, res) => { const surveys = readSurveys(); const surveyId = parseInt(req.params.id); const surveyIndex = surveys.findIndex(survey => survey.id === surveyId); if (surveyIndex === -1) { return res.status(404).json({ error: 'Survey not found' }); } if (!surveys[surveyIndex].editable) { return res.status(403).json({ error: 'Survey cannot be edited' }); } surveys[surveyIndex] = { ...surveys[surveyIndex], ...req.body, editable: false }; writeSurveys(surveys); res.json(surveys[surveyIndex]); }); // Удаление опроса app.delete('/surveys/:id', (req, res) => { const surveys = readSurveys(); const surveyId = parseInt(req.params.id); const newSurveys = surveys.filter(survey => survey.id !== surveyId); if (newSurveys.length === surveys.length) { return res.status(404).json({ error: 'Survey not found' }); } writeSurveys(newSurveys); res.status(204).send(); }); // Запуск сервера const PORT = 3000; app.listen(PORT, () => { console.log(`Server is running on http://localhost:${PORT}`); http://localhost:${PORT}`); }); ``` ### Пояснение к коду: 1. *Маршруты*: - `POST /surveys` – создание нового опроса с полем `editable: true`. - `GET /surveys` – получение всех опросов. - `PUT /surveys/:id` – редактирование опроса по ID, если `editable: true`, после чего `editable` становится `false`. - `DELETE /surveys/:id` – удаление опроса по ID. 2. *Функции*: - `readSurveys` – читает данные из JSON-файла. - `writeSurveys` – записывает данные в JSON-файл. ### Шаг 4: Запуск проекта Запустите сервер командой: ```bash node app.js ``` Теперь API будет доступен по адресу `http://localhost:3000 http://localhost:3000`.