¿Cómo se puede aplicar la escritura estática a la programación web, cuando la web se escribe de forma dinámica o flexible?

La web no se escribe dinámicamente.

Veo de dónde sacas la analogía, y no es mala, de verdad. De hecho, los parámetros de URL no se verifican hasta que se ejecutan realmente en el programa del lado del servidor, que es muy similar, en forma, a la escritura dinámica.

Sin embargo, esto es cierto para todas y cada una de las cosas que se obtienen de fuera de cualquier idioma. Incluyendo datos serializados de un lenguaje estático a través de un shell a otro lenguaje estático.

Los programas en lenguajes tipados estática y dinámicamente necesitan leer y analizar datos de todos los diferentes tipos de fuentes. Los parámetros de URL son un ejemplo. En un lenguaje de tipo estático y en un lenguaje dinámico por igual, deben leerse, analizarse, posiblemente rechazarse y luego convertirse en la representación de datos subyacente para ese idioma.

Es el paso “posiblemente rechazado” lo que es interesante aquí. Si un parámetro de URL es un entero, un lenguaje de tipo estático necesitará leerlo como tal, y no lo convertirá en un Int si lee algo más. Si es un lenguaje dinámico, existe la opción de leer cualquier cosa, pero tan pronto como se use como un entero (en la mayoría de los idiomas) se bloqueará. En la práctica, muchos lenguajes dinámicos, sin embargo, optarán por obtener errores por adelantado y temprano simplemente haciendo una verificación.

No existe ningún obstáculo para aplicar un sistema de tipos a la web, o cualquier otro conjunto de valores aparentemente sin tipo . De hecho, solo hay beneficios en seguridad.

Un tipo es solo una afirmación comprobada sobre un valor. Es extremadamente útil saber algo sobre un valor. No saber nada, como en los sistemas de tipo dinámico, es extremadamente incómodo.

Comienzas de lo que sabes: es decir, “este parámetro es una cadena”. Luego puede refinar su tipo a algo que le interese probándolo. Por ejemplo, “ahora se sabe que este parámetro es el ID de un cliente existente”. El establecimiento de un tipo más específico de un valor se puede hacer mediante la coincidencia de patrones o probando las propiedades del valor de otras maneras, por ejemplo, probando contra otras fuentes de conocimiento, como una base de datos.

Una vez que haya afirmado un tipo útil, puede dejar que el compilador verifique todos los supuestos que ha hecho en su programa. Esto es de gran beneficio, porque sin esto, necesitaría verificar a mano todas sus suposiciones de manera poco confiable. Te perderás uno o más, y el resultado es un error de tiempo de ejecución, o peor, un error de cálculo silencioso o una vulnerabilidad.

Esto se aplica a todos los niveles del programa y a todos los valores en los que opera.

Ver: la respuesta de Toby Thain a ¿Está sobrevalorada la comprobación de tipos estáticos?