Timing leak in RPC authentication #2838

issue pakt opened this issue on July 20, 2013
  1. pakt commented at 11:10 AM on July 20, 2013: none

    bitcoinrpc.cpp

    
    bool HTTPAuthorized(map<string, string>& mapHeaders)
    {
        string strAuth = mapHeaders["authorization"];
        if (strAuth.substr(0,6) != "Basic ")
            return false;
        string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64);
        string strUserPass = DecodeBase64(strUserPass64);
        return strUserPass == strRPCUserColonPass;
    }
    

    Last string comparision strUserPass == strRPCUserColonPass gets compiled to:

        do
        {
          if ( !len )
            break;
          less = *(_BYTE *)strUserPass < *(_BYTE *)strRPCUserColonPass;
          eq = *(_BYTE *)strUserPass++ == *(_BYTE *)strRPCUserColonPass++;
          --len;
        }
        while ( eq );
    

    which is a byte-by-byte compare. Attacker with precise clock (being in the same LAN, for example) might learn the RPC password letter by letter, by trying passwords like 'a...", "b...", "c..." and observing which took the longest time to verify.

    This code in bitcoinrpc.cpp:

                if (mapArgs["-rpcpassword"].size() < 20)
                    MilliSleep(250);
    

    protects from bruteforce for short password. Unfortunately, when run, bitcoind suggest a 32 chars password. Paradoxically short passwords are safer to use than longer ones, wrt to the timing leak.

    Here's an example of time independent array comparison: http://rdist.root.org/2010/01/07/timing-independent-array-comparison/

  2. jgarzik commented at 3:14 PM on July 20, 2013: contributor

    It's Basic authentication; easier just to decode the base64 ;p

  3. gmaxwell commented at 4:45 PM on July 20, 2013: contributor

    @jgarzik he doesn't mean timing an actual authentication session, he means that even absent a user who knows the password an attacker who could reach the rpc port could analyze the timing of the rejections to derive the password one character at a time because the comparison shortcuts and thus returns faster when the error is at the front.

    If you've exposed your rpc port to an attacker— life is probably not good for you to begin with. But this should probably using a constant time comparison and also delay all failures. I'll look into it.

  4. grayleonard referenced this in commit 5d3228217c on Jul 23, 2013
  5. fgeek commented at 9:23 AM on July 25, 2013: none

    Please use CVE-2013-4165 for this issue as per http://openwall.com/lists/oss-security/2013/07/24/7

  6. laanwj commented at 2:24 PM on November 12, 2013: member

    Solved by #2886

  7. laanwj closed this on Nov 12, 2013

  8. cryptokat referenced this in commit bc8d0cbc75 on Dec 28, 2017
  9. semuxgo referenced this in commit 8a6938f693 on Jun 11, 2018
  10. semuxgo referenced this in commit 28bbddfcc4 on Jun 11, 2018
  11. semuxgo referenced this in commit 8f808a5272 on Jun 11, 2018
  12. IntegralTeam referenced this in commit 92feade817 on Jun 4, 2019
  13. MarcoFalke locked this on Sep 8, 2021
  14. uvhw referenced this in commit 80d8d042ae on Jun 3, 2022

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-05-03 15:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me