[Geomoose-users] Security Advisory for MS4W users

Jim Klassen klassen.js at gmail.com
Wed Mar 31 16:05:22 PDT 2021


For most of the GeoMoose sites I run, I make the mapfile look like the endpoint (e.g. "/datasets/wms.map?SERVICE=WMS&..." instead of "/cgi-bin/mapserv?map=/datasets/wms.map&SERVICE=WMS&..."). This URL layout has a number of advantages and has worked really well for us for over a decade now under various implementations.

The current implementation uses a combination of the Apache AddHandler/Action directives and RewriteRules to work.  Using Action lets Apache do most of the heavy lifting with security and access control because the normal Apache file/path access control rules (ex. under <Directory> and <Files>) and path sanitation rules (cleanup up attempts to evade rules by using /../ or other special characters, requires files to exist, etc.) apply. RewriteRules then set MS_MAPFILE and MS_MAP_NO_PATH environment variables so people can't override it with the map= parameter (in the QUERY_STRING or in a POST).

Writing a regex that is safe against people using unconventional ways of expressing a URL (especially under windows where case insensitivity of the filesystem comes in to play) is not trivial. Using the Apache <Location> or <LocationMatch> directives and not missing some unconventional way of expressing the URL is also not trivial.  Action helps a lot here in avoiding common mistakes.

Besides sidestepping the map=/path problem, this allows giving different users access to different mapfiles using standard Apache directives.  It also makes the mapfile accessed be the main URL component in the server logs (instead of just a bunch of calls to /cgi-bin/mapserv).

The main catch with this is MapServer's automatic calculation of the server URL (for GetCapabilities) becomes incorrect.  MapServer calculates the URL to the mapserv CGI file (which is inaccessible to end users) instead of the URL to the mapfile.  This can be worked around by setting the "wxs_onlineresource" metadata in each mapfile.  However, as setting and maintaining that metadata value for every mapfile gets cumbersome, I wrote a small patch to MapServer [1] that lets it calculate the right path by default.

Also, we've always used normal CGI (not FastCGI) so I'm not sure if this causes any issues under FastCGI.

apache.conf snippet:

     <Directory "/srv/mapserver/cgi-bin">
         AllowOverride None
         Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch

         # Only allow specified files
         Require all denied

         # Mapserver
         <Files "mapserv">
             Require all granted

             # log to apache error.log
             SetEnv MS_ERRORFILE "stderr"
             SetEnv MS_MAP_NO_PATH "true"

             RewriteEngine on

             RewriteCond %{env:REDIRECT_HANDLER} ^mapserver
             RewriteCond %{PATH_INFO} ^/datasets/(.*)
             RewriteRule .* - [C,env=MS_MAPFILE:/srv/datasets/%1]
             RewriteRule .* - [C,env=MS_MAP_PATTERN:^/srv/datasets/%1$]
             RewriteRule .* - [C,env=MS_ENCRYPTION_KEY:/srv/secret.key]
             RewriteRule .* - [L]

             RewriteCond %{env:REDIRECT_HANDLER} ^mapserver
             RewriteCond %{PATH_INFO} ^/moredatasets/(.*)
             RewriteRule .* - [env=MS_MAPFILE:/srv2/moredatasets/%1,L]

             RewriteRule .* - [F]
         </Files>
     </Directory>
     ScriptAliasMatch ^/apps/mapserver/cgi-bin/(.*) /srv/mapserver/cgi-bin/$2

     <Directory "/srv/datasets/">
         Require all denied

         Action mapserver /apps/mapserver/cgi-bin/mapserv
         AddHandler mapserver .map
         <Files "*.map">
             Require all granted
         </Files>
     </Directory>
     Alias /datasets/ /srv/datasets/

     <Directory "/srv2/moredatasets/">
         Require all denied

         Action mapserver /apps/mapserver/cgi-bin/mapserv
         AddHandler mapserver .map
         <Files "*.map">
             Require group moredatasets
         </Files>
         <Files "*.pdf">
             Require all granted
         </Files>
    </Directory>
     Alias /moredatasets/ /srv2/moredatasets/


[1] https://github.com/klassenjs/mapserver/commit/2d69a4bd27e668fa5e8fad6b43d3f81e3e1dea56

On 3/31/21 3:02 PM, Jeff McKenna wrote:
> Dear GeoMoose community, please see the message below for those running MS4W (or MapServer on any operating system) on public-facing servers. thank-you.
>
>
>
> -------- Forwarded Message --------
>
> Hello everyone,
>
> As the security of MS4W on your public-facing server is important, please take some time to review the possible security steps to enable for MS4W at: https://ms4w.com/README_INSTALL.html#securing-your-ms4w-installation You will notice MS4W examples, as well as instructions to use an online tool for testing your MS4W instance.
>
> As stated there, setting the *MS_MAP_PATTERN* environment variable is strongly recommended for your server instance.
>
> The past few weeks (and especially the past few days, which were full of intense regular expression testing) I have been working with Steve Lime closely and other MapServer steering committee members, to release the security advisory for MapServer: https://mapserver.org/announcements/2021-03-30-limit-mapfile-access.html
>
> Future MS4W releases will likely be tighter, with definitely the popular .exe installer setting & enabling the *MS_MAP_PATTERN* regular expression on-the-fly, for new installations, as well as providing a few default settings in the distributed Apache httpd.conf file.
>
> MS4W security is my priority, always has been, and I hope the examples and expressions that I provided in the MS4W readme above, help everyone implement, and take some of the fear of expressions away.
>
> Thank-you all.
>
>
> -- 
> Thank-you for using MS4W.
> "MS4W: open doors as well as windows"
>
> -jeff
>
>



More information about the Geomoose-users mailing list