Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

security issue (negative number bug) in histogram comparison

Hi all,

The file histogram.cpp uses fabs() in several places, towit this code for chi-squared histogram comparison:

        for( j = 0; j < len; j++ )
        {
            double a = h1[j] - h2[j];
            double b = h1[j];
            if( fabs(b) > DBL_EPSILON )
                result += a*a/b;
        }

This is used to ensure that b can be safely used as a denominator. However, histogram values are never supposed to be negative, so the fabs() call is both unnecessary and a potential vulnerability.

It's a vulnerability because histogram comparison is used for face identification by LBPH recognizers. If an adversary ever gains the ability to twiddle a number in a face recognition database, he or she can replace a zero value with a negative number of small magnitude exceeding DBL_EPSILON. It will then pass the if() test, and cause a negative value to be added to the CHI_SQUARE sum, producing a lower value and hence a closer match.

With just the right magnitude, this will result in a negligible change in CHI_SQUARE values, so nobody will notice the negative number insertion in ordinary use; but an adversary holding up a card with the right gradient pattern can spike that histogram value, causing a sudden and unexpected match to an intended victim.

I have produced a video demo of this exploitation in action. On the left is a graph of match values to 8 different users, and you can see the match drop to about -2.4 when I hold up the card. I did this by replacing a single 0 in the President's histogram to -8e-6. An attacker who can perform this tampering of a single value can do so far in advance of its actual exploitation, allowing a back door to be inserted in a face recognition system.

This demonstration uses an LBPH with a 5x5 division into cells, with 8-bit LBP values. We are now working to confirm the same effect with 8x8 division, cropped based on Haar wavelet face recognition; at that point we should be able to demonstrate the vulnerability using the facerec_video.cpp application.

To fix this, I think fabs() should simply be removed, at least from CHI_SQUARE comparison. If we assume that b is nonnegative anyway, it shouldn't make a difference; and this will exclude a negative value from being added to the sum.

/Also, I think I need to shave.