Block access to arbitrary URLs in the GOV.UK estate
During a recent security incident it became necessary to block a GOV.UK section in order to prevent access to sensitive data.
A quick way to achieve this is to manually add a location
block to the NGINX
configuration on the cache machines or instances serving the affected pages.
In order to block <LEAK_URL>
on <INSTANCE_CLASS>
in <GOVUK_ENVIRONMENT>
:
- Find out which
<INSTANCE_CLASS>
serves<LEAK_URL>
.
- For GOV.UK content, this can be done via the content-api:
https://www.gov.uk/api/content/<LEAK_URL>
or by using the GOV.UK browser extension. - For external/independent applications, e.g. CKAN, you may need to consult the respective routing table to find out from which machine the content is served.
- Another option to determine which machine class runs an app is to consult the GOV.UK architecture overview.
Disable Puppet on each machine of the respective
<INSTANCE_CLASS>
Edit
/etc/nginx/nginx.conf
on each machine of the<INSTANCE_CLASS>
to add a location block to the server block, forcing to return403 FORBIDDEN
, e.g.
server {
(...)
location /<LEAK_URL>/ {
return 403;
}
}
Location blocks are not limited to absolute paths, but can also include regular expressions if prefixed by the ~
operator.
See the additional external documentation [here][Digital ocean] and [here][Linode] for examples.
Note:
When using location blocks in general and regular expressions in particular take extra care to not accidentally block unaffected pages as a side effect.
- Test the NGINX configuration by running
sudo service nginx configtest
on each machine
If the configuration test is successful, e.g. returns out: nginx: configuration file /etc/nginx/nginx.conf test is successful
Reload the NGINX configuration by running
sudo service nginx restart
on each machineTo make sure the change of configuration was successful, try to browse
https://www.gov.uk/<LEAK_URL>
To make the change permanent there are different options, ranging from additional vhost configuration inline in the respective Puppet class of the app (example PR) or introduce a separate NGINX configuration template for the app if more complex changes are required (example PR). Alternatively, changes to the app may remove the offending content.
Finally, re-enable Puppet on each machine of the
<INSTANCE_CLASS>
- [Digital ocean]: https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms
- [Linode]: https://www.linode.com/docs/web-servers/nginx/how-to-configure-nginx/#location-blocks