Businessman with domino

Recently I had the chance to integrate the Money library into a Symfony app with Doctrine. It looked as a pleasant learning experience in the beginning, but I swiftly found myself dealing with complexity here and there, so I said, "Let's share some feedback with those guys behind the PHP Money library."

And I ended up opening a discussion here. By the way, don't get me wrong, Symfony, Doctrine and Money, they all are fantastic free software projects in my opinion.

The thing is that a config file was copied from GitHub and pasted into the app I was working on, and it was already set up for Doctrine to handle BIGINT by default. The reason being: I guess that many developers out there will use BIGINT for money with no strong reason behind. But think a bit about it. Why do we need BIGINT for currency/money in our PHP/MySQL applications? Do we actually need the BC Math extension or the GMP extension?

Today I would like to raise some awareness about a programming principle that in my humble opinion can be beneficial for apps. I am talking about the minimum privilege principle...

The Principle of Minimum Privilege?

Exactly! Applied to writing PHP/MySQL apps dealing with money, it is somewhat of a mindset saying:

  • "Use BIGINT only when necessary"
  • "Dealing with money is not a necessary condition for using BIGINT"
  • "Stay away from libraries processing astronomical numbers, because you don't need BC Math or GMP"

More specifically, in a context of Symfony + Doctrine + Money library, the principle highlights the cons:

  • Doctrine will convert BIGINT into string
  • This is a tricky issue across different database vendors
  • 64-bit machines handle bigints differently than 32-bit machines
  • Mapping SQL BIGINT to actual PHP integers is an issue
  • And most importantly, by including BC Math and GMP you're introducing vulnerabilities into your app

Listen to What It Says...

It is all about approaching the app's design with a simplicity mindset. We want to control complexity, so rather than including this or that library in our projects almost as a habit, we perform a basic analysis first by addressing some questions:

  • "What is a realistic max limit for money in my app?"
  • "Does my app need to use currencies?"

The answers to them will serve as a guideline for making a decision about how to proceed next.

OK, let's say we estimated that $10,000,000 is a realistic limit in our app's domain. We don't need to care about currencies, and we must process cents; if that is the case, the SQL DECIMAL type is a simple solution that works OK. More specifically, use DECIMAL(10,2), or DECIMAL(12,4) if you want to comply with Generally Accepted Accounting Principles (GAAP) rules.

This way:

  • DECIMAL is consistent with the app's domain rules
  • The Money library is not included into the app
  • BC Math and GMP functions are not included into the app
  • As a developer, you simply forget about the arithmetics involved in money
  • Doctrine won't complain about integrating with custom types
  • The app's attack surface is reduced

Applying minimal privilege concepts into your apps will have a positive impact on stability, security and scalability. Of course you are not forced to use the least privilege principle all the time, but I think it is absolutely necessary in many instances. I like it!

You may be also interested in...

Previous Post Next Post