MS RFC 56: Tighten control of access to mapfiles and templates

Authors

Daniel Morissette

Contact

dmorissette at mapgears.com

Authors

Steve Lime

Contact

steve.lime at dnr.state.mn.us

Author

Jeff McKenna

Contact

jmckenna at gatewaygeomatics.com

Status

Adopted and implemented on 2009-03-26

Version

MapServer 5.4.0, 5.2.2, and 4.10.4.

Last Updated

2021-03-27

Overview

MapServer versions 5.2.1 and older could potentially be used to access arbitrary files via the creation of mapfiles or templates in untrusted directories.

This RFC proposes a mechanism to tighten access control on mapfiles and templates and limit the risk of leaking arbitrary file contents.

The new access control mechanisms will be implemented and released in MapServer 5.4.0, 5.2.2 and 4.10.4.

Note

All available environment variables, including MS_MAPFILE and those described here, which can be optionally set to hide the MAP= parameter, are listed in the document: Environment Variables.

Technical Solution

The following mechanisms will be put in place:

  • Enforce the requirement for the MAP keyword at the beginning of mapfiles and for the SYMBOLSET keyword at the beginning of SYMBOLSETs.

  • Require a Magic String at the beginning of all MapServer templates

  • Use of environment variables to control and restrict access to mapfiles by the mapserv CGI:

    • MS_MAP_PATTERN

    • MS_MAP_NO_PATH

Each of the points above are described in more details in the following sections.

Enforce the requirement for the MAP and SYMBOLSET keywords

The MAP and SYMBOLSET keywords used to be optional at the beginning of mapfiles and symbolsets respectively.

With this change, the MAP keyword will be required on the first line of mapfiles and the SYMBOLSET keyword required on the first line of symbolset files.

If the keyword is missing then the parser will reject the file.

Require a Magic String at the beginning of all MapServer templates

With this change, the first line of a template must contain the “MapServer Template” magic string which can be surrounded by comment delimiters in the format of the template to facilitate template editing (see examples below). The first line of the template file will automatically be stripped from the template and will not be included in the MapServer output.

If the magic string is not found then the template will be rejected by MapServer.

HTML template example:

<!-- MapServer Template -->
<html>
 <head>...</head>
 <body>
 ...
 </body>
</html>

XML template example:

<!-- MapServer Template -->
<?xml version="1.0" encoding="UTF-8" ?>
<rootElement>
  ...
</rootElement>

GeoJSON template example:

// MapServer Template
  [resultset layer=foo] {
"type": "FeatureCollection",
"features": [
 [feature trim=',']
 {
  "type": "Feature",
  "id": "[id]",
  "geometry": {
   "type": "PointLineString",
   "coordinates": [
    {
     "type": "Point",
     "coordinates": [[x], [y]]
    }
   ]
  },
  "properties": {
   "description": "[description]",
   "venue": "[venue]",
   "year": "[year]"
  }
 },
 [/feature]
 ]
}
[/resultset]

MS_MAP_PATTERN Environment Variable

The optional MS_MAP_PATTERN environment variable, set via mod_env or other web server equivalents, can be used to specify a Regular Expression that must be matched by all mapfile paths passed to the mapserv CGI.

If MS_MAP_PATTERN is not set then any .map file can be loaded.

Apache’s SetEnv directive can be used to restrict mapfiles to a specific directory and subdirectories.

  • Unix users may set the following expression in Apache to restrict mapfiles to the /opt/mapserver directory and subdirectories:

    SetEnv MS_MAP_PATTERN "^\/opt\/mapserver\/([^\.][_A-Za-z0-9\-\.]+\/{1})*([_A-Za-z0-9\-\.]+\.(map))$"
    
  • Windows Apache/MS4W users can set the following expression in the Apache conf file, to limit the possible MAP= paths to the common C:/ms4w/apps/ directory (where all MS4W mapfiles and applications live), allow encoded urls, allow “.” or “_” or “-” in MAP= paths but disallow “..” directory traversing:

    SetEnv MS_MAP_PATTERN "^(C:)?\/ms4w\/apps\/((?!\.{2})[_A-Za-z0-9\-\.]+\/{1})*([_A-Za-z0-9\-\.]+\.(map))$"
    

    Note

    MS4W users can see specific examples at: https://ms4w.com/README_INSTALL.html#securing-your-ms4w-installation

MS_MAP_NO_PATH Environment Variable

The optional MS_MAP_NO_PATH environment variable can be set to any value via mod_env or other web server equivalents to forbid the use of explicit paths in the map=… URL parameter. Setting MS_MAP_NO_PATH to any value forces the use of the map=<env_variable_name> mechanism in mapserv CGI URLs.

If this variable is not set then nothing changes and the mapserv CGI still accepts explicit file paths via the map=… URL parameter.

Example, set set MS_MAP_NOPATH and some mapfile paths in Apache’s httpd.conf:

SetEnv MS_MAP_NO_PATH "foo"
SetEnv MY_MAPFILE "/opt/mapserver/map1/mymapfile.map"

… and then calls the mapserv CGI must use environment variables for the map=… parameter:

http://localhost/cgi-bin/mapserv?map=MY_MAPFILE&mode=...

Backwards Compatibility Issues

The MAP and SYMBOLSET keywords must be added to any mapfile and symbolset that did not contain them already.

All MapServer templates must be updated to contain the “MapServer Template” magic string on the first line.

The new environment variables are optional and will have no impact on existing applications that don’t use them.

Files Impacted

  • mapserver.h

  • maptemplate.c

  • mapserv.c

Ticket Id

Related security tickets:

Voting History

Adopted on 2009-03-26 with +1 from DanielM, TomK, PericlesN, JeffM, SteveW, AssefaY, SteveL and TamasS.