341 character querystring fails to load with Error 400 - Bad Request

48 Views Asked by At

The documented querystring limit accepted by browsers is typically 2K. However, I have found our Angular apps, hosted by IIS, throw a Bad Request (400) error if the URL length exceeds a few hundred characters. The specific conditions of the failure are:

  • The URL must not be localhost (localhost does not produce error)
  • The URL must use ";" format for the name-value query parameters
  • The subdomain, domain, and TLD can be of any lenghth.
  • The URL must not exceed 2000 chars in total.
  • "?&" query string parameters may (also) be present but must not exceed 2000 chars in total.
  • Site is hosted by IIS

The gyst is, if the querystring portion of the URL uses semicolon format and exceeds ~350 chars, IIS throws a 400 error. The request does not make it to the Angular app. enter image description here

This is the same IIS error format if the app pool is stopped and generates a Service Unavailable 503 error.

I think IIS might have subfolder name length limit and is treating a semicolon separated URL as a complete segment rather than as query parameters - as it does with the ?-& pattern.

Is there any truth to this? Does anyone know the root cause?

Error 400 (contrived sample)

https://citations.venteksys.com/search;metu=santemaximusleo;idpharetranuncarcuegetlorem=Nuncdignissimerosneque;veleuismodnequeblanditvitae=Namconsectetursedmassaape;llentesque=Maecenasliguladui;cursussedsc=elerisqueeget;gravidaacerat=Nullautaliquet;tellus=Curabitureleifendmis;edcommodovehicula=Suspend;issepotenti=Donecorcienim;hendreriteg=etviverraeget;efficiturutnibh=Pellentesquefauci;busvariusturpisquisdapibus=Duisiaculisfelisseddolorcursus

Success 200 (reduced length)

https://citations.venteksys.com/search;metu=santemaximusleo;idpharetranuncarcuegetlorem=Nuncdignissimerosneque;veleuismodnequeblanditvitae=Namconsectetursedmassaape;llentesque=Maecenasliguladui;cursussedsc=elerisqueeget;gravidaacerat=Nullautaliquet;tellus=Curabitureleifendmis

Success 200 (?& format)

https://citations.venteksys.com/search?metu=santemaximusleo&idpharetranuncarcuegetlorem=Nuncdignissimerosneque&veleuismodnequeblanditvitae=Namconsectetursedmassaape&llentesque=Maecenasliguladui&cursussedsc=elerisqueeget&gravidaacerat=Nullautaliquet&tellus=Curabitureleifendmis&edcommodovehicula=Suspend&issepotenti=Donecorcienim&hendreriteg=etviverraeget&efficiturutnibh=Pellentesquefauci&busvariusturpisquisdapibus=Duisiaculisfelisseddolorcursus

Troubleshooting attempts.

  • Logically trimmed URL length until a successful 200 response was received.
  • Switched to ?-& format which produced a successful response.
  • Attempted to load using extra long path property defined on route (failed as expected)
1

There are 1 best solutions below

0
derpirscher On

You are building your URL wrong (because you probably misunderstood something). There different types of separators in an URL. Take for instance the following URL

 https://example.com/path/to/resource?query1=foo&query2=bar
 schema | host      | path           |    query

There are 5 different types of separators in this url

  1. :// which separates the schema from the host

  2. / as path separator, which separates the path from the host and different parts of the path (like in a file system) like for instance in to/separator

  3. ? as separator between the path and the query, ie `path/to/resource?...

  4. & as separator between two query parameters, ie query1=foo&query2=bar

  5. = as separator between key and value of a single parameter, ie query=foo

The separator between path and query (ie number 3 from above list) MUST BE a ?. That's defined in the respective RFC If you don't follow that "quasi"-standard no URL parser will be able to find the query.

Second is the separator between the query parameters themselves (ie number 4 from above list). Currently it seems to be widely accepted, that this is done with an &. I'm no expert in angular (I only used it once may years back) but it seems strange, that they would use something different (do you have any canonical source of that). And I don't know any current URLParser/QueryParser that would accept the ; as a parameter separator.

What you are now noticing with your failing URL is probably the following:

The URL https://citations.venteksys.com/search;metu=sant..... is sent to IIS. Because there is no ? in there, anything after /search.... is assumed to be part of the path of the resource. Thus IIS tries to locate this resource in the filesystem. On Windows (depending on the version), paths have a defined maximum length. And if the path you are searching for exceeds that maximum length, IIS may return an error.

So, for fixing this issue, use a proper query separator, ie use https://citations.venteksys.com/search?metu=sant.... instead. Then IIS will be able to correctly separate your URL into path and query and happily pass on the request to your backend implementation (assuming that the backend can actually cope with query parameters separated by ;)