Top Banner
Security Ruins everything on the Internet since 1920*
45
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: WordPress Security @ Vienna WordPress + Drupal Meetup

SecurityRuins everything on the Internet since 1920*

Page 2: WordPress Security @ Vienna WordPress + Drupal Meetup

About me

● Veselin Nikolov

● Automattic

● WP since 1.2

● PHP + MySQL since 3.0

Page 3: WordPress Security @ Vienna WordPress + Drupal Meetup

About me

● Veselin Nikolov

● Automattic

● WP since 1.2

● PHP + MySQL since 3.0

● IRC since 1998

Page 4: WordPress Security @ Vienna WordPress + Drupal Meetup

Acid Burn

● Controls traffic lights

● Owns 686

Page 5: WordPress Security @ Vienna WordPress + Drupal Meetup

90s

● mIRC, ircops

● MSIE hacks

● Malware

● DoS, botnets

● Proxies, shells, bots, irc servers

Page 6: WordPress Security @ Vienna WordPress + Drupal Meetup

● Confidentiality

● Integrity

● Availability

Security

Page 7: WordPress Security @ Vienna WordPress + Drupal Meetup

● Prevention

● Identification

● Reaction

Security

Page 8: WordPress Security @ Vienna WordPress + Drupal Meetup

● Hardware

● Internet

● Servers

● Passwords and Private Keys

● Plugins & Themes

● Our code

● Meatware

It's not about WordPress

Page 9: WordPress Security @ Vienna WordPress + Drupal Meetup

● Evil Maid, Trojans

● Antivirus

Hardware

Page 10: WordPress Security @ Vienna WordPress + Drupal Meetup

● MITM, routers, Wi-Fi, Poodle, http

● VPN, Proxy, Software Update

Internet

Page 11: WordPress Security @ Vienna WordPress + Drupal Meetup

Passwords

Your password is OK, as long as it's 6 caracters and ends with 123.

I recommend qwe123 :D

Page 12: WordPress Security @ Vienna WordPress + Drupal Meetup

● 30%+ of the services use plain texthttp://plaintextoffenders.com/about/

● Phishing, Social Engineering, Brute Force, MITM, keyloggers, human errors, password databases

Passwords

Page 13: WordPress Security @ Vienna WordPress + Drupal Meetup

Somebody somewhere knows many of your passwords.

Passwords

Page 14: WordPress Security @ Vienna WordPress + Drupal Meetup

Password Manager

Unfortunately, many of your clients will have their accounts compromised.

Page 15: WordPress Security @ Vienna WordPress + Drupal Meetup

The Super Admin

Page 16: WordPress Security @ Vienna WordPress + Drupal Meetup

The Super Admin

Page 17: WordPress Security @ Vienna WordPress + Drupal Meetup

'my secret password' ->

● phpass:

● $P$BXT7cDEtQXkAVarv7mh8WZux1euzwI/

md5:

● a7303f3eee5f3ff1942bfbb1797ea0af

Storing Passwords

Page 18: WordPress Security @ Vienna WordPress + Drupal Meetup

● Use strong hashing algorythms. Phpass is ok, md5 is not.

● Be careful with logs and emails, they might contain sensitive information

Storing Passwords

Page 19: WordPress Security @ Vienna WordPress + Drupal Meetup

2FA

● https://wordpress.org/plugins/two-factor-auth/

● 2FA everything!

Page 20: WordPress Security @ Vienna WordPress + Drupal Meetup

Plugins and Themes

● Use reputable sources

● Don't use free versions of paid plugins

Page 21: WordPress Security @ Vienna WordPress + Drupal Meetup

Detection

● VaultPress

● Sucuri

● ?

You need between 0 and 1

Page 22: WordPress Security @ Vienna WordPress + Drupal Meetup

Response

● You need proper backups

● Logs

● Stay calm, it happens.

Page 23: WordPress Security @ Vienna WordPress + Drupal Meetup

Code Review

Reverse Q & A.

Topics covered:

XSS, Open Redirect, XXE, SQL Injection, Remote Code Execution

Page 24: WordPress Security @ Vienna WordPress + Drupal Meetup

What's wrong with that?

<?php

echo $_GET['hi'];

Page 25: WordPress Security @ Vienna WordPress + Drupal Meetup

Cross Site Scripting - XSS

GET ?hi=<script>alert('hi')</script>

<?php

echo $_GET['hi'];

Must be

echo esc_html( $_GET['hi'] );

Page 26: WordPress Security @ Vienna WordPress + Drupal Meetup

...let's fix it.

<?php

echo esc_html( printf( 'hi, %s', $_GET['name'] ) );

Page 27: WordPress Security @ Vienna WordPress + Drupal Meetup

Typo :(

<?php

echo esc_html( printf( 'hi, %s', $_GET['name'] ) );

Late escaping OR sprintf!

Page 28: WordPress Security @ Vienna WordPress + Drupal Meetup

What's wrong?

<?php

$youtube_widget = $_REQUEST['src'];

?>

<script src="<?php

echo esc_url( $youtube_widget ); ?>">

</script>

Page 29: WordPress Security @ Vienna WordPress + Drupal Meetup

XSS

<?php

$youtube_widget = $_REQUEST['src'];

?>

<script src="<?php

echo esc_url( $youtube_widget ); ?>">

</script>

GET ?src=http://my-evil-site.com/hack.js

Page 30: WordPress Security @ Vienna WordPress + Drupal Meetup

Let's add validation...

<?php

$src = $_REQUEST['src'];

if ( ! preg_match( '#https?://youtube.com/#', $src ) ) {

die( 'Invalid Source!' );

}

?>

<script src="<?php echo esc_url( $src ); ?>">

</script>

Page 31: WordPress Security @ Vienna WordPress + Drupal Meetup

Wrong REGEXP.

'#https?://youtube.com/#'

Will match

http://dzver.com/js?http://youtube.com/

Page 32: WordPress Security @ Vienna WordPress + Drupal Meetup

Let's fix it.

<?php

$src = $_REQUEST['src'];

if ( ! preg_match( '!^https?://(www.)?youtube.com/!', $src ) ) {

die( 'Invalid Source!' );

}

?>

<script src="<?php echo esc_url( $src ); ?>">

</script>

Page 33: WordPress Security @ Vienna WordPress + Drupal Meetup

'.' is a wilcard

'!^https?://(www.)?youtube.com/!'

Will match

'http://wwwayoutube.com/'

Page 34: WordPress Security @ Vienna WordPress + Drupal Meetup

?

<?php

$domain = esc_url( $_GET['domain'] );

$user_host = `host $domain`;

echo esc_html( $user_host );

Page 35: WordPress Security @ Vienna WordPress + Drupal Meetup

Remote Code Execution

<?php

$domain = esc_url( $_GET['domain'] );

$user_host = `host $domain`;

echo esc_html( $user_host );

What if

$_GET['domain'] = '| echo "hi!"';

Page 36: WordPress Security @ Vienna WordPress + Drupal Meetup

Remote Code Execution

● eval();

● assert();

● ``; //backticks

● system()

● create_function()

● preg_replace( '.../e', $_GET )

Page 37: WordPress Security @ Vienna WordPress + Drupal Meetup

?

<?php

// @mdawaffe's example

$xml = simplexml_load_file( $uploaded_file );

?>

<h1><?php printf(

"%s Uploaded!",

esc_html( $xml->title )

); ?></h1>

Page 38: WordPress Security @ Vienna WordPress + Drupal Meetup

XML External Entity XXE

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE something

[<!ENTITY awesome SYSTEM

"file:///home/www/public_html/db-config.php"

>]

>

<something>

<title>&awesome;</title>

</something>

Page 39: WordPress Security @ Vienna WordPress + Drupal Meetup

XML External Entity XXE

Missing:

libxml_disable_entity_loader(true);

Be careful with XML parsers, careless use is associated with many vulnerabilities.

Page 40: WordPress Security @ Vienna WordPress + Drupal Meetup

?

<?php

$id = $_GET['id'];

if ( intval( $id ) ) {

$result = $wpdb->query(

"DELETE FROM wp_usermeta WHERE user_id = $id"

);

}

Page 41: WordPress Security @ Vienna WordPress + Drupal Meetup

SQL Injection

<?php

$id = $_GET['id'];

if ( intval( $id ) ) {

$result = $wpdb->query(

"DELETE FROM wp_usermeta WHERE user_id = $id"

);

}

$id = '5 or 1 = 1'; ->

DELETE FROM wp_usermeta WHERE user_id = 5 or 1 = 1

Page 42: WordPress Security @ Vienna WordPress + Drupal Meetup

SQL Injection

<?php

$id = (int) $_GET['id'];

$result = $wpdb->query( $wpdb->prepare(

"DELETE FROM wp_usermeta WHERE user_id = %d",

$id )

);

Or use $wpdb->delete();

Page 43: WordPress Security @ Vienna WordPress + Drupal Meetup

?

<?php

$url = $_GET['url'];

if ( preg_match( '!^https?://[^\.]+\.whatever\.com/.+$!i', $url ) ) {

wp_redirect( $url );

} else {

wp_die( 'hacker :(' );

}

Page 44: WordPress Security @ Vienna WordPress + Drupal Meetup

Open Redirect

<?php

// http://3254656436/or.whatever.com/spam

if ( preg_match( '!^https?://[^\.]+\.whatever\.com/.+$!i', $url ) ) {

wp_redirect( $url );

} else {

wp_die( 'hacker :(' );

}

Page 45: WordPress Security @ Vienna WordPress + Drupal Meetup

Thanks

AMA :-)