Update: I rewrote this article, after taking an English writing class on Coursera. I only removed cutters, and kept the content intact.
Update: Nate Lawson wrote a thoughtful comment..
Update: A few more thoughts from Brad Hill of PayPal and W3C.
For example, if you have an array x of 10 elements, accessing x or x won't throw an out of bound exception, but return undefined. This behavior is hostile to crypto code, as demonstrated in this neat exploit discovered by Bleichenbacher, the grandfather of many crypto attacks:
* Encrypt this string: ưưưưưưưưưưưưưưưư as ASCII.
* Decrypt the ciphertext.
* XOR each character of the decryption with 0x52.
* And the result is the key.
What happened? The program expects ASCII inputs, but we give it Unicode. The function that causes the vulnerability is SubBytes
// do S-Box substitution
function SubBytes(state, Sbox)
for( i=0; i<16; i++ )
state[i] = Sbox[ state[i] ];
The state variable holds the input. If state[i] >= 256, state[i] would become undefined,because Sbox is an array of only 256 elements.
Many libraries have this “type confusion” vulnerability. How do you fix it? First, you need to validate input. If a function accepts a byte array, it should always check input is an array whose elements are bytes. Secondly, you need to minimize type conversions. Instead of accepting strings in one function and big integers or byte arrays in others, we need to use a single type everywhere. Thirdly, instead of plain old array of numbers you should use typed arrays. When a function accepts an Uint8Array it knows that each element of input is a byte, without doing expensive type checks. Finally, you should Closure and annotate variables and parameters with its pseudo types. The Closure compiler will type-check your program and report type mismatch bugs.
1. Build crypto clients
2. Stay out of scope of PCI DSS
3. Avoid data leaks
4. Reduce latency