788 karma · joined August 11, 2011
And to be clear, I'm talking about providing at least one legit use for passing user input directly to exec without any kind of filtering...
Neither of which have an answer. Unless you want to discuss the fine details of the problem. In which case I'll hire your site to do the architecture for free next time I have a major project.
Questions like that aren't unanswerable. They are however unanswerable without knowing a lot about your specific case (requirements, skills, staff, infrastructure, etc). So they tend not to be QA because they either get surface treatment (leading people to make bad decisions on partial information) or they lead to abuse (people taking advantage of it).
Stuff like this: http://marc.info/?l=php-internals&m=135083835232016&...
Sometimes he contributes to discussions in a very positive manner. But too often he degrades the discussion into BS rhetoric and greatly demoralizes contributors (I know I am not the only one to voice disdain, I may just be the first publicly)...
I guess you can say I just had enough...
As far as the missing parts, yes, we know those are missing. The Zval implementation was a place-holder to let it work. Now that it's working for basic code, the goal is to refactor in an appropriate design for it. Once that happens, we can implement full copy-on-write. It's very much a work-in-progress...
As far as test cases, we've been using the Zend language test cases as part of a guide. Seeing as only about 6% of them pass right now, they are not in the repo. But eventually the goal is to port them in.
Once that happens, the next goal is to get it to host run-tests.php (the PHP core test runner).
From there, there's one goal left: self-hosting.
Thanks again!!!
Thanks!!!
First, it was something that I always wanted to do. For no particular reason other than I wanted to do it. I knew it was possible, but possible and doing it are two very different things.
Second, it was far easier than I thought. The time to the initial commit (basic working VM) was only about 6 hours of work. So it's not like I spent a year building it...
Third, it could be a useful education tool. For me learning the intricacies of the Zend VM better (I know it fairly well, but knowing and building give two different amounts of knowledge). But also for teaching others how the VM works. By giving a PHP implementation reference, hopefully more people can understand how the C implementation works (they both operate off the same generic implementation at this point).
Fourth, it can enable certain interesting things. For example, we could hypothetically build an Opcode optimizer in PHP which parses the generated opcodes and optimizes things (removing redundant opcodes, statically compiling static expressions, etc). Then, we could build a PECL extension that would render those optimized opcodes directly into APC cache (or some other opcode cache mechanism).
Fifth, it can be used to quickly mock up future functionality changes. Consider that it's easier to alter a PHP VM simply because you don't need to worry about memory management at all. So whipping up a POC for a significant feature should be a lot easier in PHP than C (at least for many non-full-time C developers).
Sixth, it can be used to actually debug PHP code without working knowledge of GDB (and the underlying C structures). I wouldn't recommend this, as the chances of us getting it working 100% the same as the C implementation are practically 0, but it's a concept.
Seventh, it could wind up becoming a full implementation (like PYPY). If we can compile the implementation using HipHop, and do some other lower-level tricks, there's a chance we could achieve performance somewhere near the C implementation. I doubt it, but it's possible. Especially if we add a JIT component (or a way of rendering out to machine code certain opcodes)...
Eighth, why not?
You mean the way that iOS 3, 4, 5 and 6 have stolen things from Android? Hell, the Book position sync thing that they introduced today copies from Android (and likely the Kindle).
Stop it with the FUD about this. The two phones are rectangular with rounded corners. Since when is that protected design? Look at the automobile market. Models are not distinguished by a generic look and feel, but by very very specific design details. None of which were copied between the devices.
Show me ONE major Apple feature that wasn't copied from someone else. The entire product is a culmination of ideas and innovation from others. Multi-touch? Done before. Large screen? Done. Icons? Done. Multi-Tasking? Don't even kid yourself. Notifications? Really?
What they did, and where their value is, is not in the concepts or innovation. It's in the level of polish that they apply. That's their competitive advantage.
And their legal battles are proof that they cannot compete on any other front other than polish. And since Android has been making leaps and bounds of improvements over the years, it's been threatening Apple's competitive advantage. And that's why Apple is suing.
It's the ultimate instance of the pot calling the kettle black.
Patents are not Trademarks. Patents are valid and legal even if you don't enforce them (where trademarks become invalid if you don't enforce them).
So no, they did have a choice. In fact, they had 3:
1. They could have not gotten the patent at all. This could open them up to legal liability if someone else got it and sued them.
2. They could have kept it for defensive purposes only. Using it if they were sued for patent abuse (and to prevent others from suing on this idea).
3. They could use it offensively.
They chose #3. So yes, they did have a choice.
Additionally, I love your choice of words for the final sentence:
> What would've you done to protect ideas you spent years refining?
I think it hits the key point. They didn't invent the vast majority of what they are suing over. They just refined it. They didn't invent multi-touch, they just polished it. Now, whether that polish is worth a patent is one thing, but the concept is not.
And that's the absurdity of it all. This is not about protecting invention. This is not about protecting innovation. It's about protecting market position.
And if there's a clearer abuse of the patent system than this, I'd love to see it...
> The inventor must make an oath or declaration that he/she believes himself/herself to be the original and first inventor of the subject matter of the application, and he/she must make various other statements required by law and various statements required by the USPTO rules.
Now, it would be VERY difficult to prove the oath was broken. But if it was, it's completely and 100% valid to hold the inventor (here Apple) responsible.
I'm not saying that's what's going on here (or in most cases of an overturned patent), just that it may be Apple's fault. It's not a black and white situation here...
I thought you meant the function in its entirety.
So, to your specific point, it's not bad. That doesn't mean it can't be improved upon.
For example, `mt_rand()` is susceptible to certain types of seed poisoning attacks. That's because the state that it uses is process specific. So when running PHP in a case similar to what happens with mod_php, that state is shared among all php instances (just like with APC). What that means is that the security and randomness of your usage depends on everyone else's usage. So if someone calls `mt_srand()` in one app over and over with the same value, your randomness can be thrown out of the window.
Now, that's a very significant edge case with very limited attack potential. However, when it comes to security if there's a better way, why not use it. And in this case, there is (/dev/urandom). Just read from that source (via fopen, via mcrypt_create_iv, via openssl_random_pseudo_bytes, etc).
I'd much rather edge on the safer side as long as there are not significant downsides...
As far as 2a vs 2y, I would stick with 2y unless you have a very good reason for sticking with 2a.
As far as the error checking, I thought it was worth mentioning, since it seems that $hash = crypt(...) is all you need, when in reality it isn't. Which goes to further my point that crypt() is too difficult to use out of the box...
> That's just a stupid typo/brain fart.
I realize that. I was just pointing it out.
> That said, I'll make a note to use the new one since it is superior. I do find your comment that "if you're on too old of a PHP version to use that (5.3.7 IIRC), then don't even talk about security..." to be needlessly flippant. You don't even bother to offer an alternative to the poor bastards that are stuck on older versions.
Correct. Because older versions have fairly significant vulnerabilities associated with them. Two major DOS vulnerabilities come to mind. Is the comment flippant? Perhaps. Does that make it wrong? No...
And as far as "offer an alternative to the poor bastards that are stuck on older versions", there are plenty of those. PHPass supports PHP all the way back to like 4.2... If you need a password hashing algorithm for an unsupported version (or 5.3.x < 5.3.7), just use that.
Which actually brings me to the entire point (I don't need to tell you, just making the point again). Just use a library for this. It may seem easy to just do it yourself, but there's a lot to it. Just use a library and be done with it. There's no reason to re-implement it every time...
Hope that helps...
Additionally, the general drift hasn't been towards OOP within PHP. Some OOP libraries are being added, but the core remains largely procedural (and doesn't appear to be shifting significantly yet). It's taking the (very logical IMHO) route of "Does this make sense to be OOP". If the answer is yes, then it goes in as a class structure. If not, it goes in procedurally.
I did not feel it made sense to make this a class, and as such I did not...
But for this case, the salt generation is much better (assuming that `mt_rand` is a good enough source of entropy, which may or may not be the case).
The rest definitely applies though.
In short, you're using the wrong algorithm ($2y$ is the better one, the one you're using has a known bug). You're not checking for errors from `crypt()` prior to storing the hash. So you can wind up significantly messing up your database and potentially leaving it in a worse state than if you just used `md5($password)`... And the minor note about timing attacks...
Not to mention that you currently have an issue in your code (it needs to be .= for a string, not +=)...
There's presently no crypt(3) format specified for PBKDF2. So that means that I would need to invent one. That's not something I'm willing to do for a core language feature.
Additionally, pbkdf2 is actually slightly weaker than bcrypt (partially due to the higher memory requirements of the later, 32kb vs < 1kb).
So without a strong reason for including it, it wasn't included.
However, the API is designed to be extendable. When scrypt gets bindings to crypt(3), it'll be made available. If PBKDF2 gets bindings, it'll be made available. If a new and stronger algorithm is made, it'll be made available (but not default for quite some time).
But I personally am not willing to go out on a limb and create a new cryptographic specification for this project. And that's what it would have taken to put pbkdf2 into it. Hence, why it's not there...
Here's the last paragraph (in case it's TLDR, or you don't want to click through):
> So in short (or not), I just felt that there's room for this API and things like PasswordLib to live side by side. And I will continue to maintain that project in the long run. But for the generic use-case, I felt that an OOP API was too much risk for not enough gain for a core implementation. With that said, if you can come up with a clean API, I'd be all ears and willing to consider implementing it. But for now, this is the better alternative IMHO...
GPL has no requirement that the site make any mention of the license. It says the license must be included with the distribution. So check the download...
Could you explain something here? How can a block cipher that has 128 bits of output be attacked 8 bits at a time (where 1 bit change in the input will change on average 64 bits of the output in a non-predictable manner)? Sure, you can try every 8 bit permutation, but without knowing the form of the original text how can you know if you have a valid character? And how is that different from extracting "raw data" out of pure randomness (where the fallacy is obvious, you're extracting data that was never there)?
I'm genuinely interested, so if an email will do it, could you please follow up: ircmaxell [at] php [dot] net...
Thanks!
So while it's possible to write your own and be secure, IMHO it'd be better to stick to vetted algorithms and libraries... I think it's just that - all other things being equal - the public algorithm is more likely to be more secure...
Would the following block cipher be more secure than AES?
function encrypt(block, key) {
return block XOR key;
}> This abets a hugely widespread misunderstanding about the security of crypto. You could in fact invent your own block cipher core, and if you dropped it into Keyczar or cryptlib's high level library be more secure than people using AES-256 directly via OpenSSL.
You could of course. But the average developer cannot. It takes quite a bit of knowledge about cryptography to be able to do this and have it be more secure than AES... And even if you have that knowledge the chance that a mistake was made is high enough that you shouldn't use it anyway (the algorithm isn't vetted). So I stand behind my point...
> Encouraging people to encrypt data while giving them bad advice about how to accomplish that is a recipe for disaster.
What bad advice? The only thing I said was hash it if you just need to verify, or encrypt if you need to reverse it.
Additionally, would you rather have CC numbers stored in plain text? I'd rather have a botched encryption on them that's somewhat easy to break than have it in plain text...
> Specifically, you write: "Parameterized queries are a better way of solving the problem, because it doesn't require any escaping". This is wrong.
It's not wrong. Raw user input should never enter a query. Period. If you're going to paginate or sort or filter, you need to white-list filter on available fields and values. Escaping and adding it to the query is just a recipe for disaster... Obviously just using a parameterized query API isn't going to do it for you. But escaping, in any context, is an incorrect way of handling it...
> If you know very little about web security, the OWASP Top 10 is a fine starting point, but your readers should know that's all it is.
I'm not trying to suggest that they should only know the top 10, but that they should know it in its entirety...
Either:
$copy = $original;
Or, if you must have a function, function array_copy(array $a) {
return $a;
}
Arrays use the normal copy-on-write semantics of PHP. They are not passed by reference or object handle...The only potential issue is if the array contains references deeper in.
So very much agree, keep it up!
function foo($a, $b = "10", $c = "20") {}
foo(1, $c=20);
var_dump($c); // int(20)
The syntax would have to be unambiguous. Perhaps: foo(5, c: 30)
or foo(5, $c: 30);
or foo(5, $c => 30)
or something like that...