Why does line 4 not throw an    Uncaught SyntaxError: Identifier 'number' has already been declared?
As Sébastien already mentioned, variables declared with var are declared in the current execution context and can be redeclared. The concept of an execution context can be compared to a box. Per the ECMAScript Language Specification Section 8.3:
8.3 Execution Contexts
An execution context is a specification device that is used to track the runtime evaluation of code by an ECMAScript implementation. At any point in time, there is at most one execution context per agent that is actually executing code. This is known as the agent's running execution context. 
[...]
Execution contexts for ECMAScript code have the additional state components listed in Table 22.
  
  Table 22: Additional State Components for ECMAScript Code Execution Contexts
 Component           Purpose
LexicalEnvironment   Identifies the Lexical Environment used to resolve identifier references made by code within this execution context.
VariableEnvironment  Identifies the Lexical Environment whose EnvironmentRecord holds bindings created by VariableStatements within this execution context.
So everytime you write JavaScript code, it's separated into small individual "boxes" called execution contexts that are created whenever the interpreter encounters a new syntactic structure such as a block, function declaration, etc. In each of these boxes, there are many components, but in particular the LexicalEnvironment and VariableEnvironment. These are both "mini-boxes" inside the parent execution context "box" that hold references to the variables declared inside the current execution context that the code may access. LexicalEnvironment refers to the variables declared with let and const. VariableEnvironment refers to variables created with var.
Now looking at Section 13.3.2:
13.3.2 Variable Statement
NOTE      A var statement declares variables that are scoped to the running execution context's VariableEnvironment. Var variables are created when their containing Lexical Environment is instantiated and are initialized to undefined when created. Within the scope of any VariableEnvironment a common BindingIdentifier may appear in more than one VariableDeclaration but those declarations collectively define only one variable.
The last part of the quoted note states the reason why you can declared a var more than once. Every time the interpreter encounters a function, a new VariableEnvironment is created because var is function-scoped, and if you're in the global scope there is one global VariableEnvironment. In your case, you've declared number both times in the global scope because { … } is a block, not a function, but they collectively only define number once. So, your code actually performs the same as this:
var number = 10 //declared once
{
  number = 42 //since { … } does not create a new VariableEnvironment, number is the same 
              //variable as the one outside the block. Thus, the two declarations only define
              //number once and every redeclaraction is essentially reassignment.
}
console.log(number) //42
And as you said, let and const are block-scoped. They do not throw an error because { … } creates a new block.
Why is var given a "free pass"? Does it have to do with the number property being reassigned to the window object when var is used?
As described before, a var declaraction can occur many times within a VariableEnvironment - but the same doesn't hole true for let and const. As Bergi mentioned, the ECMAScript authors hadn't realized the downfalls and quirks of having such a bad declarator var until much later, and changing var's behavior would cause the whole internet to collapse, as backwards-compatibility is a huge aspect of ECMAScript/JavaScript. Thus, the authors introduced new declarators, let and const that would aim to be block-scoped and predictable, more like other declarators you see in other languages. As such, let and const declarations throw an error whenever there is another declaration within the same scope. This has nothing to do with window, just because of compatibility and historical issues.