Difference between revisions of "Catalyst"

From HalfgeekKB
Jump to navigation Jump to search
Line 100: Line 100:
 
====Massive redirection prowess====
 
====Massive redirection prowess====
  
For functional security, these features would be desirable:
+
With the following methodology, it is possible to:
  
* The Catalyst project exists ''outside'' the website directory, so the probability of files being exposed due to misconfiguration is reduced.
+
* Store the project separately from the document root, preventing access to material in the event of a misconfiguration.
** e.g. The website root is /home/someuser/sub.example.com but the project is /home/someuser/projects/Foo
+
* Prevent, with caveats, the dispatch script from being requested directly by a client.
* The dispatch script cannot be accessed directly from the browser.
+
 
** e.g. http://sub.example.com/d/dispatch.fcgi/ is not equivalent to http://sub.example.com/
+
=====Pre-flight=====
** e.g. http://sub.example.com/d/dispatch.fcgi/bar is not equivalent to http://sub.example.com/bar
+
 
* Rewrites exist so that the URL to the dispatch script or its directory is redirected into the dispatcher.
+
First, you'll want to make sure you have a minimalist shell such as dash installed locally. This can be used to wrap the true dispatch script and run it elsewhere without adding the overhead (and potential vulnerabilities) of bash. For this discussion, it's installed at
** e.g. http://sub.example.com/d from the browser is redirected to http://sub.example.com/d/dispatch.fcgi/d internally.
+
 
** e.g. http://sub.example.com/d/ from the browser is redirected to http://sub.example.com/d/dispatch.fcgi/d/ internally.
+
/home/someuser/bin/dash
** e.g. http://sub.example.com/d/dispatch.fcgi from the browser is redirected to http://sub.example.com/d/dispatch.fcgi/d/dispatch.fcgi internally.
+
 
** e.g. http://sub.example.com/d/dispatch.fcgi/ from the browser is redirected to http://sub.example.com/d/dispatch.fcgi/d/dispatch.fcgi/ internally.
+
Also, ensure that the domain is enabled for FastCGI.
** e.g. http://sub.example.com/d/dispatch.fcgi/bar from the browser is redirected to http://sub.example.com/d/dispatch.fcgi/d/dispatch.fcgi/bar internally.
+
 
 +
Finally, note your project's name and location. For this discussion, the project is named <code>Foo</code> and based at
 +
 
 +
/home/someuser/catalyst-projects/Foo
 +
 
 +
=====Deployment=====
 +
 
 +
Do the following in the document root.
 +
 
 +
<syntaxhighlight lang=bash>
 +
DASH=/home/someuser/bin/dash
 +
PROJECT_FASTCGI_SCRIPT=/home/someuser/catalyst-projects/Foo/script/foo_fastcgi.pl
 +
 
 +
# Generate an obscure dir name by which to access the dispatcher
 +
OBSCURE_KEY="`uuidgen -r`"
 +
 
 +
# FastCGI script
 +
SCRIPT="$OBSCURE_KEY/dispatch.fcgi"
 +
 
 +
# Set normal-looking permissions
 +
umask 0022
 +
 
 +
# /(dir)/
 +
mkdir "$OBSCURE_KEY"
 +
 
 +
# /(dir)/.htaccess
 +
echo "DirectorySlash Off" > "$OBSCURE_KEY/.htaccess"
 +
 
 +
# /(dir)/dispatch.fcgi
 +
cat >"$SCRIPT" <<EOF
 +
#!$DASH
 +
"$PROJECT_FASTCGI_SCRIPT" "\$@"
 +
EOF
 +
# Make executable
 +
chmod 755 "$SCRIPT"
 +
 
 +
# /.htaccess
 +
cat >.htaccess <<EOF
 +
RewriteEngine On
 +
RewriteCond %{ENV:REDIRECT_STATUS} ^$
 +
RewriteRule ^(.*)$ $SCRIPT/\$1
 +
EOF
 +
</syntaxhighlight>
 +
 
 +
=====Caveat=====
 +
 
 +
By the standard of [[Mod_rewrite/Hide_a_script]], this is a perfect deployment. However, Catalyst seems to try a little too hard to reconcile the path, so an access to /$OBSCURE_KEY/dispatch.fcgi/bar still behaves the same as /bar. This is why the dir name is made obscure: Chances are that nobody's going to guess the obscure key, so it's unlikely a client will be able to access it and unlikely that real content will be made available by that name. Even if the obscure key is known, this by itself only reveals that a script named dispatch.fcgi is in use, which doesn't provide all that much (more) information to an attacker.
 +
 
 +
An actual fix may be attempted in the future. For now, this should probably work.

Revision as of 14:26, 15 January 2015

Notes on Catalyst, an MVC web framework for perl.


Installation

Other people's instructions

On Dreamhost with perlbrew

Here, I am using perlbrew instead of the typical instructions, and hope to bypass the whole local::lib thing.

Presume that myperl is a perlbrew environment that's already been set up and that its executable is at

/home/someuser/perl5/perlbrew/perls/myperl/bin/perl

Install modules with cpanm:

perlbrew use myperl
cpanm Catalyst::Runtime Catalyst::Devel

Version check

Run the following, which always fails:

perl -M"Catalyst 999"

If the failure is about a version number, the install worked (and the error displays the version number). Otherwise, there was a problem.

Link catalyst.pl

Instructions and tutorials refer to the bootstrap script catalyst.pl. This is installed in the bin dir of the perlbrew environment:

/home/someuser/perl5/perlbrew/perls/myperl/bin/catalyst.pl

To make this less of a mouthful, make this accessible from your path. In this example, I'll qualify it with the name of the perlbrew env in case I want to set this up for multiple sites; anytime the doc says "catalyst.pl" I'll substitute "myperl-catalyst.pl".

ln -s /home/someuser/perl5/perlbrew/perls/myperl/bin/catalyst.pl ~/bin/myperl-catalyst.pl

Test on a site

Here, sub.example.com is a domain that has been set up with FastCGI enabled.

Save the following script, modify the variables SITENAME, CATALYST, PERLENV, and PARENT as necessary, and run. This script will:

  • Go to the root specified by $PARENT
  • Create a new, empty site named $SITENAME at $PARENT/$SITENAME
  • Create and chmod $PARENT/$SITENAME/script/dispatch.fcgi to automatically run the generated FastCGI script
    • The reason for this naming is discussed in the Dreamhost wiki.
    • This part is skipped if catalyst.pl has not generated the expected *_fastcgi.pl file.
  • Replace all instances of "/usr/bin/env perl" with the path of the specified perlbrew perl
  • Run perl Makefile.PL, as suggested by catalyst.pl to "make sure your install is complete"
#!/bin/bash

# Load perlbrew env
source ~/perl5/perlbrew/etc/bashrc

SITENAME=Foo
CATALYST=catalyst.pl
PERLENV=myperl
PARENT=~/sub.example.com

myperl="`perlbrew use "$PERLENV" && which perl`"

perlbrew use "$PERLENV" &&
cd "$PARENT" &&
"$CATALYST" "$SITENAME" &&
cd "$SITENAME" &&
(
    cd script &&
    for fcs in *_fastcgi.pl; do
        cat > dispatch.fcgi <<EOF &&
#!/usr/bin/env perl
do '$fcs';
EOF
        chmod 755 dispatch.fcgi
    done
) &&
# This part corrects all the "/usr/bin/env perl" shebangs with the perlbrew perl
find -type f -exec perl -p -i -e "s!/usr/bin/env perl!$myperl!g" {} \; &&
# "make sure your install is complete"
perl Makefile.PL

After this, visiting the page

http://sub.example.com/Foo/script/dispatch.fcgi/

(note the trailing slash) results in a default welcome screen. (If the result is a 500, something wasn't set up correctly.)

Massive redirection prowess

With the following methodology, it is possible to:

  • Store the project separately from the document root, preventing access to material in the event of a misconfiguration.
  • Prevent, with caveats, the dispatch script from being requested directly by a client.
Pre-flight

First, you'll want to make sure you have a minimalist shell such as dash installed locally. This can be used to wrap the true dispatch script and run it elsewhere without adding the overhead (and potential vulnerabilities) of bash. For this discussion, it's installed at

/home/someuser/bin/dash

Also, ensure that the domain is enabled for FastCGI.

Finally, note your project's name and location. For this discussion, the project is named Foo and based at

/home/someuser/catalyst-projects/Foo
Deployment

Do the following in the document root.

DASH=/home/someuser/bin/dash
PROJECT_FASTCGI_SCRIPT=/home/someuser/catalyst-projects/Foo/script/foo_fastcgi.pl

# Generate an obscure dir name by which to access the dispatcher
OBSCURE_KEY="`uuidgen -r`"

# FastCGI script
SCRIPT="$OBSCURE_KEY/dispatch.fcgi"

# Set normal-looking permissions
umask 0022

# /(dir)/
mkdir "$OBSCURE_KEY"

# /(dir)/.htaccess
echo "DirectorySlash Off" > "$OBSCURE_KEY/.htaccess"

# /(dir)/dispatch.fcgi
cat >"$SCRIPT" <<EOF
#!$DASH
"$PROJECT_FASTCGI_SCRIPT" "\$@"
EOF
# Make executable
chmod 755 "$SCRIPT"

# /.htaccess
cat >.htaccess <<EOF
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)$ $SCRIPT/\$1
EOF
Caveat

By the standard of Mod_rewrite/Hide_a_script, this is a perfect deployment. However, Catalyst seems to try a little too hard to reconcile the path, so an access to /$OBSCURE_KEY/dispatch.fcgi/bar still behaves the same as /bar. This is why the dir name is made obscure: Chances are that nobody's going to guess the obscure key, so it's unlikely a client will be able to access it and unlikely that real content will be made available by that name. Even if the obscure key is known, this by itself only reveals that a script named dispatch.fcgi is in use, which doesn't provide all that much (more) information to an attacker.

An actual fix may be attempted in the future. For now, this should probably work.