3

I'm wondering about the common practice of embedding things like hashing and encryption deep inside lower level code. Seems like it would be better to use some sort of object or macro convention so that security features can be easily assessed and updated as exploits are discovered and efficiencies made. For example, I see the following convention in PHP code dealing with authentication (blogs, code canyon, framework wikis, etc) ... here is a made up example to illustrate the point.

if ($myhash !== md5(shaX($this->key) . blah($this->salt) . blah($this->var))

instead of burying this down deep, wouldn't this be better as

if ($myhash != MY_HASH($key))

with MY_HASH in a config file or other easily accessible object, thus making it easier to update/maintain with better security as it becomes available? Why not put any nugget that encrypts or hashes into a config file or special hash file that contains only the transform functions?

Also - consider database access. PHP has so many abstractions, but I see applications doing this:

// grab some data from the database
if ($this->mongo_flag)
{
    $this->mongo_abstraction
    ->where($blah1, $x)
     ->update($blah2);
}
elseif ($this->mysql_flag)
{
    $this->mysql_abstraction
    ->where($blah1, $y)
     ->update($blah2);
}
elseif ($this->couch_flag)
{
    $this->couch_abstraction
    ->where($blah1, $z)
     ->update($blah2);
}

Maybe only x,y,z are different.

Can't an object be instantiated that has the proper db method up front, thus eliminating the if/else logic, which is repeated everywhere a data base access is made?

i.e.

$mydata = $this->db_get_method($blah1, $blah2);

or

$mydata = $DB_GET_METHOD($db_type, $blah1, $blah2);

When if/else discrimination is preferred, then it seems like you should you skip the abstraction stuff and just use the native API making it more efficient and simpler to maintain since the native api probably isn't going to change and the abstraction is mostly nullified/voided by calling out each possible database type. Or not?

My main experience is with real-time embedded C programming (a lot of PHP code looks like procedural C designed with global structs) so I'm wondering whether performance might be the definitive answer, i.e. it just runs faster this way? Do objects introduce too much latency/complexity?

  • 2
    It seem to me that PHP developers are thinking the same about password hash functions, there's an rfc for php 5.5 that would introduce password_hash() function to simplify the whole hashing procedure: https://wiki.php.net/rfc/password_hash – complex857 Jul 20 '12 at 18:35
  • As @complex857 said, use password_* – Scott Arciszewski Aug 13 '15 at 16:53

3 Answers3

0

I like what you are suggesting. Especially with the hashing, I think its smart to wrap that up into an easy to access location. I also like what you are suggesting about calling the db methods. However, with PHP to do what you are suggesting will require reflection and there are performance issues with that, take a look at this post PHP 5 Reflection API performance. The performance hit does not seem too bad, but there is still a decrease in performance. I think a better way to achieve the db method calls would be with OOP inheritance instead of passing around dynamic methods. There should be a different object for each database.

Community
  • 1
  • 1
hackattack
  • 1,087
  • 6
  • 9
0

As @complex857 said in his comment, there are some efforts in PHP to develop a simplification of the hashing process. Anyway, you can do them by yourself (plain functions, or more sophisticated classes).

Maybe I didn't understand you right, but regarding DB abstraction, with PHP PDO (and also with PEAR's DB and MDB2) you can build an object for an specific DB engine, and after that, the methods are roughly the same (differences arise only when dealing with specific features of any engine).

There's also a big problem regarding PHP: sometimes you stumble upon scripts written utterly bad, perhaps made by amateur programmers. So, if you see many times the same bad practices, it doesn't mean there is no better way to do it with PHP. Also take into account how old those scripts may be: PHP has evolved a lot in its lifetime.

Nicolás Ozimica
  • 9,481
  • 5
  • 38
  • 51
0

Authentication and database abstraction are both frequent sore spots. Programmer hubris or inexperience does lead to a large amount of poor reinvention (and occasionally useful innovation).

As far as database abstraction goes, your example breaks down quickly when the backend implementation differs dramatically. For example, query language and data modelling for a NoSQL database like Couch or MongoDB does not line up well with the traditional relational queries used by SQL databases. You end up with a leaky abstraction where you either use a "common" interface with a lot of caveats about what works for a given backend .. or a lowest common denominator which is severely limiting. This is a common problem with ORMs .. they often struggle to represent a join or subselect which doesn't quite fit into the expected ObjectClass <=> DatabaseTable mapping.

The same is true even within "similar" products such as databases supporting a common relational language like SQL. Every database generally has its own SQL dialect which usually diverges starting from the supported data types and varies even more greatly as the implementation extends to more advanced features like triggers, stored procedures, and views.

From the looks of your other examples, you are also coming across some of the spaghetti code where developers may be doing a poor job of implementing their own abstractions.

If performance is an issue, the best outcome is likely going to be optimizing for a specific database backend and taking advantage of the unique features.

If supporting a variety of database backends is more of a priority, there are standard relational interfaces such as PDO, Doctrine, or MDB. An emerging category of database abstraction is the ODM (Object Document Mapper) for NoSQL databases such as MongoDB and Couch.

Stennie
  • 63,885
  • 14
  • 149
  • 175