Skip to content

More secure way to run a Flask instance in an Apache subdirectory.

Notifications You must be signed in to change notification settings

switham/flask_via_fcgi

Repository files navigation

A slightly more secure way to run Flask using FastCGI.

There's a security bug that people seem to spread by word of mouth. It shows up in recipes for running web apps using .htaccess and FastCGI, a.k.a. fcgi. This project gives a recipe for use with Flask, while fixing the bug.

This method could be used to run any Python, Ruby, Perl, or PHP application in part of a directory being served by Apache, when you don't have control over Apache's config files (e.g., when you're running on a hosting service). The recipe deserves explaining in English; for now an example is given by the files in this project.

The Swiss Cheese

The bug involves .htaccess files like this:

Options +ExecCGI
AddHandler fcgid-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ sponge.fcgi/$1 [L]

Here, %{REQUEST_FILENAME} means, "the absolute path in the filesystem that the requested URL maps to," and !-f means, "Not(there's a file there)." This tells Apache, "If the URL maps to a real file, don't rewrite the URL, just serve the file to anyone who asks for it, otherwise, apply the RewriteRule (which activates fcgi). In other words, make every file in this subdirectory tree publicly readable. And, if a URL that you want Flask to serve happens to coincide with an actual file, Flask doesn't get called--the direct contents of the file take precedence. If you want the Flask app to control access, or if there is any information in the directory you want to keep secret, then you need a much more restrictive rule, Fortunately it's not that hard; rewrite the RewriteCond line like this:

Options +ExecCGI
AddHandler fcgid-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !=/home/me/public_html/sponge/sponge.fcgi
RewriteRule ^(.*)$ sponge.fcgi/$1 [L]

($HOME doesn't work in this context, you have to spell it out.) What this RewriteCond means is, if the URL maps to anything but the specific fcgi script, then rewrite it--prepend the script name to it-- and try again. But once the URL points to the script, let Apache treat it in the usual way, which (given the rest of the recipe) is to run the script, which runs Flask. You could set up more exceptions (i.e. name paths you want Apache to serve directly) using multiple RewriteCond lines, but allowing almost nothing at first and adding individual exceptions as needed, is the right way to go.

About

More secure way to run a Flask instance in an Apache subdirectory.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published