protecting plone from the big, bad internet

Post on 29-Nov-2014

3.237 Views

Category:

Technology

4 Downloads

Preview:

Click to see full reader

DESCRIPTION

Steve McMahon and Erik Rose’s presentation on Plone security from Plone Conference 2008 in Washington, D.C.

TRANSCRIPT

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 fred@example.com -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

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 McMahonSteve@dcn.org

Erik RoseErikRose@psu.edu

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

top related