Why isn't this HMAC construction/check secure? A MAC is calculated the following way:

mac = sha1(secret || m)[0:8]


[0:8] denotes taking the first 8 characters from the resulting hash.

The length of the secret is unknown. Users (and potential attackers) can check the validity of a particular MAC and message pair online.

if(macInput == sha1(secret || m)[0:8]){
   // ok
}else{
   // access denied
}


Can this be attacked? I heard it can, but I don't see why and how.
OK, there are two issues with this:

First, the MAC length is at most 64 bit, that is an attacker could try to brute-force-find a valid MAC with "merely" $2^{64}$ submissions, which is border-line feasible for large companies today.
If it actually only is 8 hex character, then each hex character encodes at most 4 bits of information and thus you get $8\cdot 4=32$ bits for the MAC security meaning brute-force would take at most $2^{32}$ (around 4bn) tries to recover a valid MAC.

Second, much more severe is the naive verification of the MAC which will probably allow for a classic timing side-channel attack.
Chances are that this multi-byte equality verification is implemented as an "optimized" check, that is (in a python-ish way):

if len(lb)!=len(rb):
   return false
for (lb,rb) in zip(l_input,r_input):
   if lb != rb :
      return false
return true


Which checks the that the input lengths match and then pairs all the bytes at the same position in both inputs and outputs false as soon as a miss-match is detected and true if no missmatch is found.

Now what we can do is to measure the time it takes to verify our MAC. So we would start of with 7 0 characters and prepend each possible value (character) value to this string. We send all to verification. The one that takes longest has a match on the first character. Now we fix this first character that we just verified and continue with the second with the same method. We continue with this process until we have recovered the full MAC and get access in return.

If we get all-equal times for the first character, we take iterate over all possible choices for the first two characters (enlarge as needed). If we know the size of the information $b$ (in bits) encoded in the constant-time verification data structure (eg 8 for byte-wise, 32 for integer-wise, ...) and we know the mac information $l$ in bits, then we take at most the following amount of calls to the verification oracle to recover the valid MAC:

$$n=2^b\cdot(l/b)$$

If in your case 8 hex characters need to be verified this becomes $2^4\cdot 8=256$ calls to the verification oracle (because the effective information of the hash is 32 bits composed of 4 bit elements).