Download - Protecting Plone from the Big, Bad Internet
Protecting Plone From
The Big, Bad Internet
Steve McMahonReid-McMahon, LLC
Erik RoseWebLion, Pennsylvania State University
<SteveM>
CVE Vulnerability Records
CVE Vulnerability Records
Common Vulnerabilities & Exposures
CVE Vulnerability Records
Common Vulnerabilities & Exposures
CVE Vulnerability Records
Common Vulnerabilities & Exposures
So, why
worry?
<Basics>
Defense in Depth
Defense in Depth
Single Wall Defense
Maginot Line
Maginot Line
Maginot Line
Maginot Line
Maginot Line
Failure of single wall defense
Failure of single wall defense
Proposition:
Zope is our Maginot Line
CVE-2007-5741
Original release date:11/07/2007
Last revised:09/05/2008
Source: US-CERT/NIST
Overview
Plone 2.5 through 2.5.4 and 3.0 through 3.0.2 allows remote attackers to
execute arbitrary Python code via network data
containing pickled objects for the (1) statusmessages or (2) linkintegrity
module, which the module unpickles and executes.
Principle of Least Privileges
Principle of Least Privileges
Principle of Least Privileges
</Basics>
Daemon Security
No Rights
Bad Example: Sendmail (1990s)
mailbox file
Sendmail*
/bin/mail*
to networkfrom network
local submission
local delivery * uses root privileges
to |command**
to /file/name**
** in ~/.forward files and in /etc/aliases
owned by recipient
executed as recipient
Good Example: Postfix
Compartmentalization
smtpd
local
pickup
smtpdinternet
smtp
server
other
programs
smtpdsmtpd
local
delivery
smtpdsmtpdsmtpclient
internet
mailbox
|command
/file/name
queue
directories
privileged
smtpdsmtpd
to external
transports
uucp
fax
pager
privileged
unprivileged
unprivileged
unprivileged
unprivileged
smtp
client
(local submission)
= root privilege
= postfix privilege
Good Example: Postfix
Compartmentalization
smtpd
local
pickup
smtpdinternet
smtp
server
other
programs
smtpdsmtpd
local
delivery
smtpdsmtpdsmtpclient
internet
mailbox
|command
/file/name
queue
directories
privileged
smtpdsmtpd
to external
transports
uucp
fax
pager
privileged
unprivileged
unprivileged
unprivileged
unprivileged
smtp
client
(local submission)
= root privilege
= postfix privilege
<Implementation>
<Implementation>
<File & Process>
Typical Installation
Process UID:
Plone
File Owner:
Plone
./var
./logs}
Typical Installation
Process UID:
Plone
File Owner:
Plone./parts
*.pyc
./var
./logs}
Why is that so bad?
Why is that so bad?
Daemon can write
into its own code
space.
A Better Way
Process UID:
Plone
File Owner:
Plone
./var
./logs}File Owner:
root./parts
*.py*}
Making it happen
Making it happen
Python-2.4/lib/python2.4/compileall.py
Via buildout:
[precompile]
recipe = plone.recipe.precompiler
Even Better: ZEO
Process UID:
zclient
./var
File Owner:
zeo
Process UID:
zeo
./parts
File Owner:
root
./client-log
File Owner:
zclient
Windows
</File & Process>
</Implementation>
</File & Process>
</Implementation>
</File & Process>
</SteveM>
<Port Security>
Reverse Proxy
Zope
Evil,
Monstrous
Internet
Reverse Proxy
Zope
Evil,
Monstrous
Internet
Reverse Proxy
Zope
Evil,
Monstrous
InternetApache
Reverse Proxy
Zope
Evil,
Monstrous
InternetApache
SSL
Zope
Evil,
Monstrous
InternetApache
SSL
Listen Locally
8080
Zope
Evil,
Monstrous
InternetApache
SSL
zope.conf:
ip-address 127.0.0.1
Listen Locally
8080
Zope
Evil,
Monstrous
InternetApache
SSL
zope.conf:
ip-address 127.0.0.1
Listen Locally
Zope
Evil,
Monstrous
InternetApache
SSL
Listen Locally
ssh -L 3333:127.0.0.1:8080 [email protected] -N
Zope
Evil,
Monstrous
InternetApache
SSL
Listen Locally
ZEO
Zope
Evil,
Monstrous
InternetApache
SSL
Listen Locally
ZEO
8100
Zope
Evil,
Monstrous
InternetApache
SSL
Listen Locally
ZEO
zeo.conf:
address 127.0.0.1:8100
8100
Zope
Evil,
Monstrous
InternetApache
SSL
Listen Locally
ZEO
zeo.conf:
address 127.0.0.1:8100
Zope
Evil,
Monstrous
InternetApache
SSL
Listen Locally
ZEO
Untrusted Local Users
Zope
(81)
ZEO
(8100)
Your Server
Untrusted Local Users
Zope
(81)
ZEO
(8100)
Evil Dude
Your Server
Untrusted Local Users
Zope
(81)
ZEO
(8100)
Evil Dude
Your Server
Untrusted Local Users
Zope
(81)
ZEO
(8100)
Evil Dude
Your Server
iptables -A OUTPUT -p tcp --dport 81 -o lo \ -m owner ! --uid-owner www-data -j REJECT
Untrusted Local Users
Zope
(81)
ZEO
(8100)
Evil Dude
Your Server
iptables -A OUTPUT -p tcp --dport 81 -o lo \ -m owner ! --uid-owner www-data -j REJECT
Untrusted Local Users
Zope
(81)
ZEO
(8100)
Evil Dude
iptables -A OUTPUT -p tcp --dport 8100 -o lo \ -m owner ! --uid-owner zope -j REJECT
Your Server
iptables -A OUTPUT -p tcp --dport 81 -o lo \ -m owner ! --uid-owner www-data -j REJECT
Untrusted Local Users
Zope
(81)
ZEO
(8100)
Evil Dude
iptables -A OUTPUT -p tcp --dport 8100 -o lo \ -m owner ! --uid-owner zope -j REJECT
Your Server
Zope
(8080)
ZEO
(8100)
Your Server
Privileged Ports
Zope
(8080)
ZEO
(8100)
Your Server
Privileged Ports
ZEO
(8100)
Your Server
Privileged Ports
Evil Zope
(also 8080)
ZEO
(8100)
Evil Dude
Your Server
Privileged Ports
Evil Zope
(also 8080)
ZEO
(8100)
Evil Dude
Your Server
Privileged Ports
Evil Zope
(also 8080)
ZEO
(8100)
Evil Dude
Your Server
(2032) DO (1001) NEXT
(2036) PLEASE FORGET #1
DO .5 <- '?.1$.2'~'#0$#65535'
DO .5 <- '?"'&"!2~.5'~'"?'?.5~.
5'$#32768"~"#0$#65535"'"$
".5~.5"'~#1"$#2'~#3
DO (2034) NEXT
DO .5 <- .3
DO (1010) NEXT
PLEASE DO .1 <- .3
DO .3 <- 'V.4$.5'~'#0$#65535'
DO (2035) NEXT
(2034) PLEASE DO (1001) NEXT
(2035) DO FORGET #1
DO .5 <- "?'.4~#1'$#2"~#3
DO (2031) NEXT
DO .2 <- .2~#65534
(3010) PLEASE STASH .1 + .4 +
.5
PLEASE DO (1020) NEXT
DO .2 <- #0
DO .3 <- #2
DO .4 <- .1
DO (3012) NEXT
(3011) DO (1001) NEXT
(3012) PLEASE FORGET #1
DO (3000) NEXT
DO .5 <- '?"?.1~#256"$
#2'~#3
DO (3013) NEXT
DO .5 <- '?"'#65535~"'
?.
1$#10'~#21845"'~#1"$#1
'~#3
DO (3013) NEXT
DO .5 <- .1
DO .1 <- .2
(2536) PLEASE FORGET #1 DO :5 <- "'?":1~'#65535$#0'"$":2~'#65535$#0'"' ~'#0$#65535'"$"'?":1~'#0$#65535'"$":2~'#0$ #65535'"'~'#0$#65535'" DO .5 <- '?"'&"':2~:5'~'"'?"'?":5~:5"~"#65535$ #65535"'~'#65535$#0'"$#32768'~'#0$#65535'" $"'?":5~:5"~"#65535$#65535"'~'#0$#65535'"' "$"':5~:5'~#1"'~#1"$#2'~#3 DO (2534) NEXT DO :5 <- :3
Privileged Ports
</Port Security>
<Within Zope>
PluggableAuthService (PAS)
WebServerAutha PluggableAuthService plugin
WebServerAutha PluggableAuthService plugin
Redirects to HTTPS(Challenge)
WebServerAutha PluggableAuthService plugin
Redirects to HTTPS(Challenge)
Makes Zope believe the username header(Extraction, Authentication)
WebServerAutha PluggableAuthService plugin
Redirects to HTTPS(Challenge)
Makes Zope believe the username header(Extraction, Authentication)
Makes PAS behave(User Enumerator)
WebServerAutha PluggableAuthService plugin
<VirtualHost *:443> ServerName www.example.com # Prompt for authentication: <Location /> SSLRequireSSL AuthType Basic AuthName "My Funky Web Site" AuthUserFile /etc/such-and-such # (etc.) Require valid-user
WebServerAutha PluggableAuthService plugin
# Put the username (stored below) into the HTTP_X_REMOTE_USER # request header. This has to be in the <Location> block for # some Apache auth modules, such as PubCookie, which don't set # REMOTE_USER until very late. RequestHeader set X_REMOTE_USER %{remoteUser}e </Location> # Do the typical VirtualHostMonster rewrite, adding an E= option # that puts the Apache-provided username into the remoteUser # variable. RewriteEngine On RewriteRule ^/(.*)$ http://127.0.0.1:81/VirtualHostBase/https/ %{SERVER_NAME}:443/VirtualHostRoot/ $1 [L,P,E=remoteUser:%{LA-U:REMOTE_USER}]</VirtualHost>
WebServerAutha PluggableAuthService plugin
<VirtualHost *:80> ... RequestHeader unset X_REMOTE_USER ...</VirtualHost>
WebServerAutha PluggableAuthService plugin
LDAP
LDAPPloneLDAP + plone.app.ldap
LDAPPloneLDAP + plone.app.ldap
Users & groups in LDAP
LDAPPloneLDAP + plone.app.ldap
Users & groups in LDAP
Create & delete through Plone
LDAPPloneLDAP + plone.app.ldap
Users & groups in LDAP
Create & delete through Plone
Relax—written by Wiggy
Writing PAS Plugins
Writing PAS Plugins
PAS Reference Manualhttp://plone.org/documentation/manual/pas-reference-manual/referencemanual-all-pages
Writing PAS Plugins
PAS Reference Manualhttp://plone.org/documentation/manual/pas-reference-manual/referencemanual-all-pages
NoGoChallengerhttps://svn.plone.org/svn/collective/PASPlugins/Products.NoGoChallenger/trunk
Writing PAS Plugins
PAS Reference Manualhttp://plone.org/documentation/manual/pas-reference-manual/referencemanual-all-pages
NoGoChallengerhttps://svn.plone.org/svn/collective/PASPlugins/Products.NoGoChallenger/trunk
PASPlugins folderhttps://svn.plone.org/svn/collective/PASPlugins
Writing PAS Plugins
PAS Reference Manualhttp://plone.org/documentation/manual/pas-reference-manual/referencemanual-all-pages
NoGoChallengerhttps://svn.plone.org/svn/collective/PASPlugins/Products.NoGoChallenger/trunk
PASPlugins folderhttps://svn.plone.org/svn/collective/PASPlugins
Plugin interfacesPluggableAuthService/interfaces/plugins.py
Writing PAS Plugins
PAS Reference Manualhttp://plone.org/documentation/manual/pas-reference-manual/referencemanual-all-pages
NoGoChallengerhttps://svn.plone.org/svn/collective/PASPlugins/Products.NoGoChallenger/trunk
PASPlugins folderhttps://svn.plone.org/svn/collective/PASPlugins
Plugin interfacesPluggableAuthService/interfaces/plugins.py
Paster templatepaster create -t plone_pas
Questions?
• Reactor defense in depth:http://www.nea.fr/html/brief/images/br-8-1.gif
• Gate: Nuclear Power Plant Dungeness - Corey Holms 2008, CC Attribution
• Locks on door: Kansir, flikr, CC attribution license
• What me worry? Rev. Voodoo, flikr, CC Attribution, NC
• BSD Daemon: Created by Poul-Henning Kamp
• No Right Turn: greefus groinks' photostream, CC Attribution
• Sendmail and Postfix architecture diagrams: The Postfix mail server as a secure programming example, Wietse VenemaIBM T.J. Watson Research Center
• The Scream: Edvard Munk
• Shrug: spamily, flikr, CC by A
• Zope Pope photo: MrTopf
• PB&J photo: Northern Miniatures
• Other photos: Wikimedia Commons
• INTERCAL Numerical I/O lib: Brian Raiter
• Crown jewels of Denmark: King Christian IV
Image Credits
Steve [email protected]
Erik [email protected]
References
• Slides: svn checkout https://weblion.psu.edu/svn/weblion/users/ewr119/ploneSecurityPresentation/Big,%20Bad%20Internet.key
• https://weblion.psu.edu/wiki/SecureZope
WebServerAuthAdvantages over apachepas + AutoMemberMaker
Redirects to HTTPS
No user clutter
Member and Authenticated roles are distinct
Sets up Log In link for you
Better test coverage; death to doctests
One product, not two