Because Run-time Substitution affects potentially sensitive areas of your mapfile such as database columns and filenames, it is mandatory that you use pattern validation (since version 6.0).


Similar validation pattern mechanisms have been available for variable substitutions since version 4.10, but then it was optional. The pattern for %myvar% was then provided in METADATA using «myvar_validation_pattern».


It is also strongly recommended to review the security steps for the MAP= call to the MapServer executable, by setting MS_MAP_PATTERN or MS_MAP_NO_PATH or hiding the MAP= parameter on public servers, as recommended in the document Limit Mapfile Access. All possible environment variables to secure your server are listed in Environment Variables.

Pattern validation uses regular expressions, which are strings that describe how to compare strings to patterns. The exact functionality of your systems” regular expressions may vary, but you can find a lot of general information by a Google search for «regular expression tutorial».

As of MapServer 5.4.0 the preferred mechanism is a VALIDATION block in the LAYER definition. This is only slightly different from the older METADATA mechanism. VALIDATION blocks can be used with CLASS, LAYER and WEB.

  # %firstname% substitutions can only have letters and hyphens
  'firstname'     '^[a-zA-Z\-]+$'

  # %parcelid% must be numeric and between 5 and 8 characters
  'parcelid'      '^[0-9]{5,8)$'

  # %taxid% must be two capital letters and six digits
  'taxid'         '^[A-Z]{2}[0-9]{6}$'

If identical keys appear in more than one validation block, then keys in more specialised blocks override those in more generalised blocks. So CLASS overrides LAYER which overrides WEB.

Default values if not provided in the URL

The runtime substitution mechanism will usually create syntactically incorrect, and almost always semantically incorrect mapfiles if the substitution parameter was not provided in the calling URL.

Since version 5.6, you can provide a default value for any substitution parameter, that will be applied if the parameter was not found in the url. You do this by providing special entries inside CLASS, LAYER or WEB validation blocks:

    'default_sound' 'yes'
    'default_nseats' '5'
    'default_multimedia' 'yes'

In this example, the mapfile will be created as if the url contained «&sound=yes&nseats=5&multimedia=yes»

If identical default keys appear in more than one validation block then keys in more specialised blocks override those in more generalised blocks. i.e. CLASS overrides LAYER which overrides WEB.

The same functionality is available using METADATA blocks instead of VALIDATION but this is deprecated as of MapServer 5.4.0.

Test with Commandline

You can test at the commandline, allowing you to test runtime substitution mapfiles without using a webserver, with the mapserv utility such as:

mapserv -nh "QUERY_STRING=map=D:\ms4w\apps\filter-validation\" > ttt.png

Filter example

You can use runtime substitutions to change values within a FILTER as you go. For example your FILTER could be written like this:

FILTER ("multimedia='%multimedia%' and seats >= %nseats% and Sound= '%sound%')

Then (assuming you’re using the CGI interface) you could pass in variables named multimedia, nseats and sound with values defined by the user in an HTML form.

You must define validation expressions on these variables to guard against unintentional SQL being submitted to postgis. Within the layer you’d do the following:

    'multimedia' '^yes|no$'
    'sound' '^yes|no$'
    'nseats' '^[0-9]{1,2}$'

The first two limit the value of multimedia and sound to yes or no. The third limits the value for nseats to a 2 digit integer.


Be careful not to use a variable specifically named id as this will cause an error such as:

msCGILoadForm(): Web application error. Parameter 'id' value fails to validate

Instead use another variable name such as code or myid. For example:

    "code" "[0-9]"
  FILTER ("[reg_code]" IN "%code%")
END # Layer

..and calling it as: https://xxx.xx/cgi-bin/mapserv?,13