This site is the archived OWASP Foundation Wiki and is no longer accepting Account Requests.
To view the new OWASP Foundation website, please visit https://owasp.org

Difference between revisions of "Germany/Projekte/Top 10 fuer Entwickler-2013/A8-Cross-Site Request Forgery (CSRF)"

From OWASP
Jump to: navigation, search
m
m (Bugfix)
 
(57 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Top_10_2010_Developer_Edition_De:TopTemplate|useprev=PrevLink_Germany_Projekte|usenext=NextLink_Germany_Projekte|next=Top_10_fuer_Entwickler/A2_Cross-Site_Scripting_(XSS)|prev=Top_10_fuer_Entwickler/Risiken}}
+
{{Top_10_2013_DeveloperEdition:TopTemplate
==Testseite in Bearbeitung (BAUSTELLE!!)==
+
    |useprev=2013PrevLinkDeveloperEdition
====die Überschriften kommen z.T noch von den Templates der englischen Top 10, Tbd!!====
+
    |usenext=2013NextLinkDeveloperEdition
----
+
    |prev=A7-{{Top_10_2010:ByTheNumbers
== A5 Cross-Site Request Forgery (CSRF) (untergeschobene Requests) ==
+
              |7
 +
              |year=2013
 +
              |language=de}}
 +
    |next=A9-{{Top_10_2010:ByTheNumbers
 +
              |9
 +
              |year=2013
 +
              |language=de}}
 +
    |year=2013
 +
    |language=de
 +
}}
  
{{Top_10_2010_Developer_Edition_De:SummaryTableHeaderBeginTemplate}}
+
{{Top_10_2010:SubsectionColoredTemplate
{{Top_10_2010:SummaryTableValue-2-Template|Ausnutzbarkeit|DURCHSCHNITTLICH}}
+
    |A8 Cross-Site Request Forgery (CSRF, XSRF, Session Riding)
{{Top_10_2010:SummaryTableValue-1-Template|Verbreitung|SEHR HÄUFIG}}
+
     ||year=2013
{{Top_10_2010:SummaryTableValue-1-Template|Auffindbarkeit|EINFACH}}
+
}}
{{Top_10_2010:SummaryTableValue-2-Template|Auiswirkung|MITTEL}}
 
{{Top_10_2010:SummaryTableHeaderEndTemplate}}
 
    <td {{Template:Top 10 2010:SummaryTableRowStyleTemplate}}>Jeder, der einem Nutzer einer Webanwendung einen nicht beabsichtigten Request für diese Anwendung unterschieben kann. Hierfür kommt jede Website oder jede HTML-Quelle in Betracht, die der Nutzer verwendet.</td>
 
    <td {{Template:Top 10 2010:SummaryTableRowStyleTemplate}}>Durch Image-Tags, XSS oder andere Techniken löst das Opfer unbeabsichtigt einen gefälschten HTTP-Request für eine Anwendung aus. <u>Falls der Nutzer authentisiert ist</u>, wird dieser Angriff Erfolg haben.</td>
 
     <td colspan=2  {{Template:Top 10 2010:SummaryTableRowStyleTemplate}}>[[CSRF]] zielt auf Anwendungen, die es dem Angreifer erlauben, alle Details eines Requests für eine bestimmte Aktion vorherzusagen.
 
  
Da Browser Informationen zum Session-Management automatisch mitsenden, kann ein Angreifer gefälschte Requests auf bösartigen Websites hinterlegen, die von legitimen Requests nicht unterschieden werden können.  
+
{{Top_10_2010:SummaryTableHeaderBeginTemplate|type=images|year=2013|language=de}}
 +
{{Top_10:SummaryTableTemplate|exploitability=2|prevalence=2|detectability=1|impact=2|language=de|year=2013}}
 +
{{Top_10_2010:SummaryTableHeaderEndTemplate|year=2013|language=de}}
 +
    <td {{Template:Top 10 2010:SummaryTableRowStyleTemplate}}>Jeder, der einem Browser Inhalte unterschieben kann, die nicht beabsichtigte Requests auslösen. Hierfür kommt jede Website oder jede HTML-Quelle in Betracht, die der Nutzer verwendet.</td>
 +
    <td {{Template:Top 10 2010:SummaryTableRowStyleTemplate}}>Durch Image-Tags, XSS oder andere Techniken löst das Opfer unbeabsichtigt einen gefälschten HTTP-Request für eine Anwendung aus. <u>Falls der Nutzer authentifiziert ist</u>, wird dieser Angriff Erfolg haben.</td>
 +
    <td colspan=2  {{Template:Top 10 2010:SummaryTableRowStyleTemplate}}>[[CSRF]] nutzt aus, dass es bei den meisten Webanwendungen möglich ist, die Inhalte eines Requests für eine bestimmte Aktion vorherzusagen.
 +
Da Browser Informationen zum Session-Management automatisch mitsenden, kann ein Angreifer gefälschte Requests auf bösartigen Websites hinterlegen, die von autorisierten und gewollten Requests nicht unterschieden werden können.
  
 
CSRF-Schwächen sind leicht durch Penetrationstests oder Quellcode-Analysen auffindbar.</td>
 
CSRF-Schwächen sind leicht durch Penetrationstests oder Quellcode-Analysen auffindbar.</td>
     <td {{Template:Top 10 2010:SummaryTableRowStyleTemplate}}>Der Angreifer kann unbemerkt das Opfer über dessen Browser dazu veranlassen, alle Daten zu ändern oder jede Funktion auszuführen, für die das spezifische Opfer berechtigt ist.</td>
+
     <td {{Template:Top 10 2010:SummaryTableRowStyleTemplate}}>Angreifer können über den Browser des Opfers alle zustandsändernden Aktionen auslösen, für das es berechtigt ist, z.B. Ändern  von Daten, Aufgeben von Bestellungen, Logout und Login, usw.</td>
     <td {{Template:Top 10 2010:SummaryTableRowStyleTemplate}}>Betrachten Sie den Geschäftswert der betroffenen Daten oder Funktionen. Es bleibt die Unsicherheit, ob der Nutzer die Aktion ausführen wollte.
+
     <td {{Template:Top 10 2010:SummaryTableRowStyleTemplate}}>
 
+
Betrachten Sie den Geschäftswert der betroffenen Daten oder Funktionen. Es bleibt die Unsicherheit, ob der Nutzer die Aktion ausführen wollte.
 
Bedenken Sie mögliche Auswirkungen auf Ihre Reputation.</td>
 
Bedenken Sie mögliche Auswirkungen auf Ihre Reputation.</td>
 
{{Top_10_2010:SummaryTableEndTemplate}}
 
{{Top_10_2010:SummaryTableEndTemplate}}
  
{{Top_10_2010_Developer_Edition_De:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|number=1|risk=5}}
+
{{Top_10:SubsectionTableBeginTemplate|type=main}} {{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=example|position=firstLeft|risk=8|year=2013|language=de}}
Die Anwendung erlaubt es einem Benutzer, einen '''zustandsändernden Request''' auszulösen, der kein geheimes Token beinhaltet, wie z.B.:  
+
Die Anwendung erlaubt es einem Benutzer, einen '''zustandsändernden Request''' auszulösen, der kein geheimes Token beinhaltet, wie z.B.:
 +
{{Top_10_2010:ExampleBeginTemplate|year=2013}}
 +
'''<nowiki>http://example.com/app/transferFunds?amount=1500&amp;destinationAccount=4673243243</nowiki>'''
 +
{{Top_10_2010:ExampleEndTemplate}}
 +
 
 +
Dadurch kann ein Angreifer einen Request erzeugen, der Geld vom Konto des Opfers auf das Konto des Angreifers transferiert. Diesen bettet der Angreifer „unsichtbar“ in ein Image-Tag oder ein Iframe ein und hinterlegt ihn in einer beliebigen Website:
 +
{{Top_10_2010:ExampleBeginTemplate|year=2013}}
 +
'''<nowiki>&lt;img src=&quot;http://example.com/app/transferFunds?</nowiki><span style="color: red;"><nowiki>amount=1500&amp;destinationAccount=attackersAcct#&quot; width=&quot;0&quot; height=&quot;0&quot; /&gt;</nowiki>'''</span>
 +
{{Top_10_2010:ExampleEndTemplate}}
  
: '''<nowiki>http://example.com/app/transferFunds?amount=1500&amp;destinationAccount=4673243243</nowiki>'''
+
Wenn das Opfer eine präparierte Seite besucht, während es bereits auf '''example.com authentifiziert''' ist, werden diese '''untergeschobenen Requests''' automatisch gültige Session-Informationen mit versenden. Die Requests sind somit unbeabsichtigt autorisiert.
  
Dadurch kann ein Angreifer einen Request erzeugen, der Geld vom Konto des Opfers auf das Konto des Angreifers transferiert. Diesen bettet er in einem Image-Tag oder einem Iframe ein und hinterlegt ihn in einer beliebigen Website.  
+
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=howPrevent|position=right|risk=8|year=2013|language=de}}
 +
Um CSRF zu verhindern, sollte jede Eingabeseite einen Token beinhalten. Der Token sollte unvorhersagbar und für jede Session, besser für jedes Formular, einzigartig sein und vom Server geprüft werden.
 +
# Die bevorzugte Methode, das Token einzubetten, ist ein Hidden-Input-Feld. Damit wird der Token-Wert im Body des Requests und nicht im URL übertragen (erleichtert sonst Ausspähung).
 +
# Ein solches Token kann auch direkt in den URL geschrieben oder als URL-Parameter übergeben werden. Jedoch birgt diese Vorgehensweise das Risiko, dass der URL dem Angreifer in die Hände fällt und somit das geheime Token kompromittiert ist.<br/>OWASPs [[CSRFGuard | CSRF Guard]] kann genutzt werden, um automatisch solche Token in Java EE, .NET oder PHP Anwendungen einzubinden. OWASPs [[ESAPI]] beinhaltet Token-Generatoren und Validatoren, die Entwickler einsetzen können, um ihre Transaktionen zu schützen.
 +
# Aktive Rückbestätigung vom Benutzer (erneute Authentifizierung, CAPTCHA-Eingabe, usw.) kann auch vor CSRF schützen.
 +
{{Top_10:SubsectionTableEndTemplate}}
  
: '''<nowiki>&lt;img src=&quot;http://example.com/app/transferFunds?</nowiki><span style="color: red;"><nowiki>amount=1500&amp;destinationAccount=attackersAcct#&quot; width=&quot;0&quot; height=&quot;0&quot; /&gt;</nowiki>'''</span>
+
= '''JAVA''' = 
 +
{{Top_10:SubsectionTableBeginTemplate|type=headertab}} {{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=firstLeft|title=1|risk=8|year=2013|language=de}}
 +
====ESAPI====
 +
{{Top_10_2010:ExampleBeginTemplate|year=2013}}
 +
''' /** (A) CSRF-Token erzeugen **/ '''<br/>
 +
private String csrfToken = resetCSRFToken();<br/>
 +
<br/>
 +
'''/** (B) In zu schützenden FORM-Seiten (B1), oder Urls (B2) das CSRF-Token als 'hidden field' hinzufügen, vgl [http://code.google.com/p/owasp-esapi-java/source/browse/trunk/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java ESAPI DefaultHTTPUtilities.java]**/'''<br/>
 +
<!-------------------------- POST-Request und QS fehlen noch -------------------------------->
 +
<br/>
 +
'''/** (B1) das CSRF-Token als 'hidden field' in den GET-Request hinzufügen **/'''<br/>
 +
example.jsp<br/>
 +
...<br/>
 +
<%
 +
<span style="color: green;">'''String csrfTokenFieldName = org.owasp.esapi.HTTPUtilities.CSRF_TOKEN_NAME;'''</span>
 +
:  <span style="color: green;">'''String csrfToken = ESAPI.httpUtilities().getCSRFToken();'''</span>
 +
%><br/>
 +
<span style="color: green;">'''<nowiki><input type="hidden" id="<%=csrfTokenFieldName%>" value="<%=csrfToken%>"/></nowiki>'''</span><br/>
 +
...<br/>
  
Wenn das Opfer eine präparierte Seite besucht, während es z.B. bereits auf '''example.com authentisiert''' ist, wird der '''untergeschobene Request''' unbemerkt ausgeführt, da der Browser die aktuellen Session-Informationen automatisch mitsendet und somit unbeabsichtigt autorisiert.<!--- Text geändert --->
+
'''/** (B2) das CSRF-Token als URL Parameter in den GET-Request hinzufügen, jedoch **/'''<br/>
 +
'''/** höheres Risiko, dass die URL und damit das Token dem Angreifer in die Hände fällt **/'''<br/>
 +
<%
 +
:  String unprotectedHref = "/main?function=TransferFunds&solution";
 +
:  <span style="color: green;">'''String betterProtectedHref = ESAPI.httpUtilities().addCSRFToken(unprotectedHref);'''</span><br/>
 +
%><br/>
 +
<span style="color: green;">'''<nowiki><a href='<%=betterProtectedHref%>' target="_blank">Transfer Funds</a></nowiki>'''</span><br/>
 +
<br/>
 +
'''/** (C) Beim Empfang der Daten das CSRF-Token prüfen (GET-Request) **/'''<br/>
 +
try {
 +
: <span style="color: green;">'''ESAPI.httpUtilities().verifyCSRFToken(request);'''</span>
 +
: } catch( IntrusionException e ) {<br/>
 +
: // log intrusion exception
 +
: // abort request and deny access
 +
}
 +
<br/>
 +
'''/** (D) Beim Abmelden bzw. Timeout die Session ungültig machen **/'''<br/>
 +
User  user = ESAPI.authenticator().logout;<br/>
 +
{{Top_10_2010:ExampleEndTemplate}}
  
{{Top_10_2010_Developer_Edition_De:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|number=2|risk=5}}  
+
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=right|title=2|risk=8|year=2013|language=de}}
Um CSRF zu verhindern, muss ein unvorhersagbarer Token im Body oder in der URL eines jeden HTTP-Requests eingebettet sein (und geprüft werden). Ein solcher Token sollte für mindestens jede Nutzer-Session, besser noch für jeden Request, einzigartig sein.
+
====CSRF Guard====
# Die bevorzugte Methode, ein solches Token unterzubringen ist ein Hidden-Input-Feld. Damit wird der Token-Wert im Body des HTTP-Requests und nicht im URL übertragen. Eine Übertragung im URL kann leichter ausgespäht werden.
+
{{Top_10_2010:ExampleBeginTemplate|year=2013}}
# Ein solches Token kann auch direkt in den URL geschrieben oder als URL-Parameter übergeben werden. Jedoch birgt diese Vorgehensweise das Risiko, dass der URL dem Angreifer in die Hände fällt und somit das geheime Token kompromittiert ist. OWASPs [[CSRFGuard | CSRF Guard]] kann genutzt werden, um automatisch solche Token in Java EE, .NET oder PHP Anwendungen einzubinden. OWASPs [http://owasp-esapi-java.googlecode.com/svn/trunk_doc/latest/org/owasp/esapi/HTTPUtilities.html ESAPI] / [[OWASP’s ESAPI]] (tbd!!) beinhaltet Token-Generatoren und Validatoren, die Entwickler einsetzen können, um ihre Transaktionen zu schützen.
+
;/** Parameter für CsrfGuard und Java EE-Filter im Deployment **/
</td></tr>
+
;/** Descriptor des Webserver-Containers definieren (web.xml-Datei) **/<br/>
<tr><td>
+
<context-param>
==JAVA== 
+
: <param-name>Owasp.CsrfGuard.Config</param-name>
<!-- z.Z ohne Template --->
+
: <param-value>WEB-INF/Owasp.CsrfGuard.properties</param-value>
----
+
</context-param>
----
+
<br/>
... tbd ...
+
<context-param>
 +
: <param-name>Owasp.CsrfGuard.Config.Print</param-name>
 +
: <param-value>true</param-value>
 +
</context-param>
 +
<br/>
 +
<listener>
 +
: <listener-class>org.owasp.csrfguard.CsrfGuardListener</listener-class>
 +
</listener>
 +
<br/>
 +
<span style="color: green;">'''<nowiki><filter></nowiki>'''</span>
 +
: <span style="color: green;">'''<nowiki><filter-name>CSRFGuard</filter-name></nowiki>'''</span>
 +
: <span style="color: green;">'''<nowiki><filter-class>org.owasp.csrfguard.CsrfGuardFilter</filter-class></nowiki>'''</span>
 +
<span style="color: green;">'''<nowiki></filter></nowiki>'''</span><br/>
 +
<span style="color: green;">'''<nowiki><filter-mapping></nowiki>'''</span>
 +
: <span style="color: green;">'''<nowiki><filter-name>CSRFGuard</filter-name></nowiki>'''</span>
 +
: <span style="color: green;">'''<nowiki><url-pattern>/*</url-pattern></nowiki>'''</span>
 +
<span style="color: green;">'''<nowiki></filter-mapping></nowiki>'''</span>
  
{{Top_10_2010_Developer_Edition_De:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|number=3|risk=5}}
+
{{Top_10_2010:ExampleEndTemplate}}
====Tbd!!====
+
vgl <u>[https://github.com/esheri3/OWASP-CSRFGuard/tree/master/Owasp.CsrfGuard.Test Owasp.CsrfGuard.Test]</u> <br/>
 +
Die Parameter in der Datei 'Owasp.CsrfGuard.properties' gemäß <u>[[CSRFGuard_3_Configuration | CSRFGuard_3_Configuration]]</u> einstellen.
  
{{Top_10_2010:ExampleBeginTemplate}}Tbd
+
<!--- altes Beispiel ---------------------------------------------------------------------------------
String custname = request.getParameter("customerName"); // This should REALLY be validated too<br>
+
{{Top_10_2010:ExampleBeginTemplate|year=2013}}
// perform input validation to detect attacks<br>
+
;/** Ein sicheres CSRF-Token erzeugen ('size' Bytes, BASE64-kodiert): **/
String query = "SELECT account_balance FROM user_data WHERE <span style="color: green;">'''user_name = ? ";'''</span><br>
+
<br/>
<span style="color: green;">'''PreparedStatement pstmt = connection.prepareStatement( query );<br>pstmt.setString( 1, custname);'''</span><br>
+
private String generateCSRFToken(int size) throws NoSuchAlgorithmException {
<span style="color: green;">'''ResultSet results = pstmt.executeQuery( );'''</span>
+
:    SecureRandom sr = null;
{{Top_10_2010:ExampleEndTemplate}}  
+
:    byte[] random = new byte[size];
 +
:     BASE64Encoder encoder = new BASE64Encoder();
 +
<br/>    
 +
:     sr = SecureRandom.getInstance("SHA1PRNG");
 +
:    sr.nextBytes(random);
 +
:     return encoder.encode(random);
 +
}
 +
<br/>
 +
{{Top_10_2010:ExampleEndTemplate}}
 +
<br/>
 +
;Beim Empfang der Daten das CSRF-Token prüfen
 +
Der OWASP CSRF Java EE Filter prüft, ob der CSRF-Token gültig ist und führt doChain() aus, bzw. gibt eine Fehlerseite bei einem negativen Ergebnis aus.<br/>
  
{{Top_10_2010_Developer_Edition_De:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|number=4|risk=5}}
+
vgl [[How_CSRFGuard_Works | How_CSRFGuard_Works]] ----------------------------------------------------->
 +
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=left|title=3|risk=8|year=2013|language=de}}
 +
====Java Server Faces (JSF)====
 +
JSF sendet ab Version 2.2 automatisch sichere CSRF-Token mit.
 +
<!--------------------
 +
{{Top_10_2010:ExampleBeginTemplate|year=2013}}
 +
...<br/>
 +
Tbd: konfig<br/>
 +
... <br/>
 +
{{Top_10_2010:ExampleEndTemplate}}
 +
--------------------->
 +
<!---------------------
 +
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=userImpact|position=right|risk=8|year=2013|language=de}}
 
====Tbd!!====
 
====Tbd!!====
{{Top_10_2010:ExampleBeginTemplate}}Tbd!!
+
;{Soll so etwas rein?}
String custname = request.getParameter("customerName"); // This should REALLY be validated<br>
+
Z.B. Keine Bookmarks auf ausgefüllte Eingabe-Formulare, Suchergebnisse; Frameworks funktionieren teilweise nicht für Web 2.0
try {<br>
+
----------------------->
:<span style="color: green;">'''CallableStatement cs = connection.prepareCall'''</span><br>
+
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=references|position=right|risk=8|year=2013|language=de}}
:: <span style="color: green;">'''("{call sp_getAccountBalance(?)}");'''</span><br>
+
{{Top_10_2010:SubSubsectionOWASPReferencesTemplate}}
: <span style="color: green;">'''cs.setString(1, custname);ResultSet results = cs.executeQuery();</span><br>  
+
*[[Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet | OWASP CSRF Prevention Cheat Sheet]]
:: <span style="color: green;">'''// … result set handling'''</span><br>
+
*[[CSRF | OWASP CSRF Article]]
<span style="color: green;">'''} catch (SQLException se) {'''</span><br>
+
*[[CSRFGuard | OWASP CSRFGuard - CSRF Defense Tool]]
: <span style="color: green;">'''// … logging and error handling'''</span><br>
+
*[[CSRFGuard_3_Installation | OWASP CSRFGuard - CSRFGuard_3_Installation]] <!-- added -->
<span style="color: green;">'''}'''</span>
+
*[[CSRFGuard_3_Configuration | OWASP CSRFGuard - CSRFGuard_3_Configuration]] <!-- added -->
 +
*[[ESAPI | ESAPI Project Home Page]]
 +
*[http://owasp-esapi-java.googlecode.com/svn/trunk_doc/latest/org/owasp/esapi/HTTPUtilities.html ESAPI HTTPUtilities Class with AntiCSRF Tokens]
 +
*[http://code.google.com/p/owasp-esapi-java/wiki/Welcome ESAPI-Java-Wiki] <!-- added -->  
 +
*[[Testing_for_CSRF_(OWASP-SM-005) | OWASP Testing Guide: Chapter on CSRF Testing]]
 +
*[[CSRFTester | OWASP CSRFTester - CSRF Testing Tool]]
 +
{{Top_10_2010:SubSubsectionExternalReferencesTemplate|language=de}}
 +
*[http://cwe.mitre.org/data/definitions/352.html CWE Entry 352 on CSRF]
 +
*[http://www.jtmelton.com/2010/05/16/the-owasp-top-ten-and-esapi-part-6-cross-site-request-forgery-csrf John Melton's Weblog: The OWASP Top Ten and ESAPI –Part 5–]
 +
{{Top_10:SubsectionTableEndTemplate}}{{Top 10 DeveloperEdition:NavigationByHeadertab
 +
    |headertab=JAVA
 +
    |useprev=2013PrevHeaderTabDeveloperEdition
 +
    |usenext=2013NextHeaderTabDeveloperEdition
 +
    |prev=A7-{{Top_10_2010:ByTheNumbers
 +
              |7
 +
              |year=2013
 +
              |language=de}}
 +
    |next=A9-{{Top_10_2010:ByTheNumbers
 +
              |9
 +
              |year=2013
 +
              |language=de}}
 +
    |year=2013
 +
    |language=de
 +
}}
 +
 
 +
= '''PHP'''
 +
{{taggedSection
 +
    | type=tbd
 +
    | comment=Bitte senden Sie uns weitere gute Beispiele mit PHP für diesen Abschnitt.
 +
}}
 +
{{Top_10:SubsectionTableBeginTemplate|type=headertab}} {{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=firstLeft|title=1|risk=8|year=2013|language=de}}
 +
{{Top_10_2010:ExampleBeginTemplate|year=2013}}
 +
...
 +
: ...
 +
<br/>
 +
...
 
{{Top_10_2010:ExampleEndTemplate}}
 
{{Top_10_2010:ExampleEndTemplate}}
  
{{Top_10_2010_Developer_Edition_De:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|number=7|risk=5}}
+
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=right|title=2|risk=8|year=2013|language=de}}
====Tbd!!====
+
 
Z.B. Bookmarks
+
{{Top_10_2010:ExampleBeginTemplate|year=2013}}
 +
:    ...
 +
<br/>
 +
{{Top_10_2010:ExampleEndTemplate}}
 +
<br/>
 +
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=left|title=3|risk=8|year=2013|language=de}}
 +
{{Top_10_2010:ExampleBeginTemplate|year=2013}}
 +
...<br/>
 +
Tbd: konfig<br/>
 +
... <br/>
 +
{{Top_10_2010:ExampleEndTemplate}}
  
{{Top_10_2010_Developer_Edition_De:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|number=8|risk=5}}
+
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=references|position=right|risk=8|year=2013|language=de}}
 
{{Top_10_2010:SubSubsectionOWASPReferencesTemplate}}
 
{{Top_10_2010:SubSubsectionOWASPReferencesTemplate}}
 +
*[[Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet | OWASP CSRF Prevention Cheat Sheet]]
 
*[[CSRF | OWASP CSRF Article]]
 
*[[CSRF | OWASP CSRF Article]]
 +
*[[CSRFGuard | OWASP CSRFGuard - CSRF Defense Tool]]
 +
*[[ESAPI | ESAPI Project Home Page]]
 +
*[[Testing_for_CSRF_(OWASP-SM-005) | OWASP Testing Guide: Chapter on CSRF Testing]]
 +
*[[CSRFTester | OWASP CSRFTester - CSRF Testing Tool]]
 +
{{Top_10_2010:SubSubsectionExternalReferencesTemplate|language=de}}
 +
*[http://cwe.mitre.org/data/definitions/352.html CWE Entry 352 on CSRF]
 +
*[http://www.jtmelton.com/2010/05/16/the-owasp-top-ten-and-esapi-part-6-cross-site-request-forgery-csrf John Melton's Weblog: The OWASP Top Ten and ESAPI –Part 5–]
 +
{{Top_10:SubsectionTableEndTemplate}}{{Top 10 DeveloperEdition:NavigationByHeadertab
 +
    |headertab=PHP
 +
    |useprev=2013PrevHeaderTabDeveloperEdition
 +
    |usenext=2013NextHeaderTabDeveloperEdition
 +
    |prev=A7-{{Top_10_2010:ByTheNumbers
 +
              |7
 +
              |year=2013
 +
              |language=de}}
 +
    |next=A9-{{Top_10_2010:ByTheNumbers
 +
              |9
 +
              |year=2013
 +
              |language=de}}
 +
    |year=2013
 +
    |language=de
 +
}}
 +
 +
= '''.NET''' =
 +
{{taggedSection
 +
    | type=tbd
 +
    | comment=Bitte senden Sie uns weitere gute Beispiele mit PHP für diesen Abschnitt.
 +
}}
 +
{{Top_10:SubsectionTableBeginTemplate|type=headertab}} {{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=firstLeft|title=1|risk=8|year=2013|language=de}}
 +
====ASP.NET Web Formulare====
 +
(noch unbearbeitet => tbd)<br/>
 +
If you don't use Viewstate, then look to the default master page of the ASP.NET Web Forms default template for a manual anti-CSRF token.<br/>
 +
{{Top_10_2010:ExampleBeginTemplate|year=2013}}
 +
private const string AntiXsrfTokenKey = "__AntiXsrfToken";<br/>
 +
private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";<br/>
 +
private string _antiXsrfTokenValue;<br/>
 +
protected void Page_Init(object sender, EventArgs e)<br/>
 +
{<br/>
 +
:  // The code below helps to protect against XSRF attacks
 +
:  var requestCookie = Request.Cookies[AntiXsrfTokenKey];
 +
:  Guid requestCookieGuidValue;
 +
:  if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
 +
:  {
 +
::      // Use the Anti-XSRF token from the cookie
 +
::      _antiXsrfTokenValue = requestCookie.Value;
 +
::      Page.ViewStateUserKey = _antiXsrfTokenValue;
 +
:  } else {
 +
::    // Generate a new Anti-XSRF token and save to the cookie
 +
::    _antiXsrfTokenValue = Guid.NewGuid().ToString("N");
 +
::    Page.ViewStateUserKey = _antiXsrfTokenValue;
 +
::    var responseCookie = new HttpCookie(AntiXsrfTokenKey)
 +
::    {
 +
:::        HttpOnly = true,
 +
:::        Value = _antiXsrfTokenValue
 +
::    };
 +
::    if (FormsAuthentication.RequireSSL && Request.IsSecureConnection)
 +
::    {
 +
:::        responseCookie.Secure = true;
 +
::    }
 +
::    Response.Cookies.Set(responseCookie);
 +
:  }
 +
:  Page.PreLoad += master_Page_PreLoad;
 +
}
 +
{{Top_10_2010:ExampleEndTemplate}}
 +
[[.NET_Security_Cheat_Sheet|'''Quelle: .NET Security Cheat Sheet''']]<br/>
 +
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=right|title=2|risk=8|year=2013|language=de}}
 +
{{Top_10_2010:ExampleBeginTemplate|year=2013}}
 +
tbd
 +
Text
 +
{{Top_10_2010:ExampleEndTemplate}}
 +
 +
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=whole|title=3|risk=8|year=2013|language=de}}
 +
tbd
 +
Text
 +
 +
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=userImpact|position=left|risk=8|year=2013|language=de}}
 +
;{Soll so etwas rein?}
 +
Z.B. Keine Bookmarks auf ausgefüllte Eingabe-Formulare, Suchergebnisse; Frameworks funktionieren teilweise nicht für Web 2.0
 +
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=references|position=right|risk=8|year=2013|language=de}}
 +
{{Top_10_2010:SubSubsectionOWASPReferencesTemplate}}
 +
{{Top_10_2010:SubSubsectionExternalReferencesTemplate|language=de}}
 +
{{Top_10_2010:SubSubsectionOWASPReferencesTemplate}}
 
*[[Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet | OWASP CSRF Prevention Cheat Sheet]]
 
*[[Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet | OWASP CSRF Prevention Cheat Sheet]]
 +
*[[CSRF | OWASP CSRF Article]]
 
*[[CSRFGuard | OWASP CSRFGuard - CSRF Defense Tool]]
 
*[[CSRFGuard | OWASP CSRFGuard - CSRF Defense Tool]]
 +
*[[CSRFGuard_3_Installation | OWASP CSRFGuard - CSRFGuard_3_Installation]] <!-- added -->
 
*[[CSRFGuard_3_Configuration | OWASP CSRFGuard - CSRFGuard_3_Configuration]] <!-- added -->
 
*[[CSRFGuard_3_Configuration | OWASP CSRFGuard - CSRFGuard_3_Configuration]] <!-- added -->
 
*[[ESAPI | ESAPI Project Home Page]]
 
*[[ESAPI | ESAPI Project Home Page]]
 
*[http://owasp-esapi-java.googlecode.com/svn/trunk_doc/latest/org/owasp/esapi/HTTPUtilities.html ESAPI HTTPUtilities Class with AntiCSRF Tokens]
 
*[http://owasp-esapi-java.googlecode.com/svn/trunk_doc/latest/org/owasp/esapi/HTTPUtilities.html ESAPI HTTPUtilities Class with AntiCSRF Tokens]
 +
*[http://code.google.com/p/owasp-esapi-java/wiki/Welcome ESAPI-Java-Wiki] <!-- added -->
 
*[[Testing_for_CSRF_(OWASP-SM-005) | OWASP Testing Guide: Chapter on CSRF Testing]]
 
*[[Testing_for_CSRF_(OWASP-SM-005) | OWASP Testing Guide: Chapter on CSRF Testing]]
 
*[[CSRFTester | OWASP CSRFTester - CSRF Testing Tool]]
 
*[[CSRFTester | OWASP CSRFTester - CSRF Testing Tool]]
{{Top_10_2010:SubSubsectionExternalReferencesTemplate}}
+
*[[.NET Security Cheat Sheet| .NET Security Cheat Sheet]]
 +
{{Top_10_2010:SubSubsectionExternalReferencesTemplate|language=de}}
 
*[http://cwe.mitre.org/data/definitions/352.html CWE Entry 352 on CSRF]
 
*[http://cwe.mitre.org/data/definitions/352.html CWE Entry 352 on CSRF]
 +
*[http://asafaweb.com/OWASP%20Top%2010%20for%20.NET%20developers.pdf OWASP Top 10 for .NET developers (Troy Hunt)]
 +
{{Top_10:SubsectionTableEndTemplate}}{{Top 10 DeveloperEdition:NavigationByHeadertab
 +
    |headertab=.NET
 +
    |useprev=2013PrevHeaderTabDeveloperEdition
 +
    |usenext=2013NextHeaderTabDeveloperEdition
 +
    |prev=A7-{{Top_10_2010:ByTheNumbers
 +
              |7
 +
              |year=2013
 +
              |language=de}}
 +
    |next=A9-{{Top_10_2010:ByTheNumbers
 +
              |9
 +
              |year=2013
 +
              |language=de}}
 +
    |year=2013
 +
    |language=de
 +
}}
 +
 +
<!-- weitere Programmiersprachen oder evtl Anti-Beispiele --- >
 +
= '''Test''' =
 +
{{Top_10:SubsectionTableBeginTemplate|type=headertab}} {{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=firstLeft|title=1|risk=5|year=2013|language=de}}
 +
{{Top_10_2010:ExampleBeginTemplate|year=2013}}
 +
tbd
 +
Text
 +
{{Top_10_2010:ExampleEndTemplate}}
 +
 +
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=right|title=2|risk=5|year=2013|language=de}}
 +
{{Top_10_2010:ExampleBeginTemplate|year=2013}}
 +
tbd
 +
Text
 +
{{Top_10_2010:ExampleEndTemplate}}
 +
 +
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=defOp|position=whole|title=3|risk=8|year=2013|language=de}}
 +
(ganze Breite)
 +
Text
 +
 +
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=howPrevent|position=whole|risk=8|year=2013|language=de}}
 +
Text
  
{{Top_10_2010_Developer_Edition_De:BottomAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|usenext=NextLink_Germany_Projekte|next=Top_10_fuer_Entwickler/A6_Security_Misconfiguration|useprev=PrevLink_Germany_Projekte|prev=Top_10_fuer_Entwickler/A4_Insecure_Direct_Object_References}}
+
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=userImpact|position=left|risk=8|year=2013|language=de}}
 +
Text
  
[[Category:OWASP Top 10 fuer Entwickler]]
+
{{Top_10_2010:SubsectionAdvancedTemplate|type={{Top_10_2010:StyleTemplate}}|subsection=references|position=right|risk=8|year=2013|language=de}}
 +
{{Top_10:SubsectionTableEndTemplate}}{{Top 10 DeveloperEdition:NavigationByHeadertab
 +
    |headertab=Test
 +
    |useprev=2013PrevHeaderTabDeveloperEdition
 +
    |usenext=2013NextHeaderTabDeveloperEdition
 +
    |prev=A7-{{Top_10_2010:ByTheNumbers
 +
              |7
 +
              |year=2013
 +
              |language=de}}
 +
    |next=A9-{{Top_10_2010:ByTheNumbers
 +
              |9
 +
              |year=2013
 +
              |language=de}}
 +
    |year=2013
 +
    |language=de
 +
}}
 +
------------------------------>
 +
<headertabs />
 +
{{Top_10_2013_DeveloperEdition:BottomAdvancedTemplate
 +
    |type=0
 +
    |useprev=2013PrevLinkDeveloperEdition
 +
    |usenext=2013NextLinkDeveloperEdition
 +
    |prev=A7-{{Top_10_2010:ByTheNumbers
 +
              |7
 +
              |year=2013
 +
              |language=de}}
 +
    |next=A9-{{Top_10_2010:ByTheNumbers
 +
              |9
 +
              |year=2013
 +
              |language=de}}
 +
    |year=2013
 +
    |language=de
 +
}}

Latest revision as of 20:15, 23 March 2016

← A7-Fehlerhafte Autorisierung auf Anwendungsebene
Top 10 fuer Entwickler-2013: Inhaltsverzeichnis

Die Top-10-Risiken

A9-Nutzung von Komponenten mit bekannten Schwachstellen →
A8 Cross-Site Request Forgery (CSRF, XSRF, Session Riding)


Bedrohungsquellen
Angriffsvektoren
Schwachstellen
Technische Auswirkung
Auswirkung auf das Unternehmen
Anwendungs-
spezifisch
Ausnutzbarkeit
DURCHSCHNITTLICH
Verbreitung
HÄUFIG
Auffindbarkeit
EINFACH
Auswirkung
MITTEL
Anwendungs-/
Geschäftsspezifisch
Jeder, der einem Browser Inhalte unterschieben kann, die nicht beabsichtigte Requests auslösen. Hierfür kommt jede Website oder jede HTML-Quelle in Betracht, die der Nutzer verwendet. Durch Image-Tags, XSS oder andere Techniken löst das Opfer unbeabsichtigt einen gefälschten HTTP-Request für eine Anwendung aus. Falls der Nutzer authentifiziert ist, wird dieser Angriff Erfolg haben. CSRF nutzt aus, dass es bei den meisten Webanwendungen möglich ist, die Inhalte eines Requests für eine bestimmte Aktion vorherzusagen.

Da Browser Informationen zum Session-Management automatisch mitsenden, kann ein Angreifer gefälschte Requests auf bösartigen Websites hinterlegen, die von autorisierten und gewollten Requests nicht unterschieden werden können.

CSRF-Schwächen sind leicht durch Penetrationstests oder Quellcode-Analysen auffindbar.
Angreifer können über den Browser des Opfers alle zustandsändernden Aktionen auslösen, für das es berechtigt ist, z.B. Ändern von Daten, Aufgeben von Bestellungen, Logout und Login, usw.

Betrachten Sie den Geschäftswert der betroffenen Daten oder Funktionen. Es bleibt die Unsicherheit, ob der Nutzer die Aktion ausführen wollte.

Bedenken Sie mögliche Auswirkungen auf Ihre Reputation.
Mögliche Angriffsszenarien

Die Anwendung erlaubt es einem Benutzer, einen zustandsändernden Request auszulösen, der kein geheimes Token beinhaltet, wie z.B.:

http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243

Dadurch kann ein Angreifer einen Request erzeugen, der Geld vom Konto des Opfers auf das Konto des Angreifers transferiert. Diesen bettet der Angreifer „unsichtbar“ in ein Image-Tag oder ein Iframe ein und hinterlegt ihn in einer beliebigen Website:

<img src="http://example.com/app/transferFunds?amount=1500&destinationAccount=attackersAcct#" width="0" height="0" />

Wenn das Opfer eine präparierte Seite besucht, während es bereits auf example.com authentifiziert ist, werden diese untergeschobenen Requests automatisch gültige Session-Informationen mit versenden. Die Requests sind somit unbeabsichtigt autorisiert.

Wie kann ich 'Cross-Site Request Forgery (CSRF)' verhindern?

Um CSRF zu verhindern, sollte jede Eingabeseite einen Token beinhalten. Der Token sollte unvorhersagbar und für jede Session, besser für jedes Formular, einzigartig sein und vom Server geprüft werden.

  1. Die bevorzugte Methode, das Token einzubetten, ist ein Hidden-Input-Feld. Damit wird der Token-Wert im Body des Requests und nicht im URL übertragen (erleichtert sonst Ausspähung).
  2. Ein solches Token kann auch direkt in den URL geschrieben oder als URL-Parameter übergeben werden. Jedoch birgt diese Vorgehensweise das Risiko, dass der URL dem Angreifer in die Hände fällt und somit das geheime Token kompromittiert ist.
    OWASPs CSRF Guard kann genutzt werden, um automatisch solche Token in Java EE, .NET oder PHP Anwendungen einzubinden. OWASPs ESAPI beinhaltet Token-Generatoren und Validatoren, die Entwickler einsetzen können, um ihre Transaktionen zu schützen.
  3. Aktive Rückbestätigung vom Benutzer (erneute Authentifizierung, CAPTCHA-Eingabe, usw.) kann auch vor CSRF schützen.
Verteidigungs-Option 1 gegen 'Cross-Site Request Forgery (CSRF)':

ESAPI

/** (A) CSRF-Token erzeugen **/
private String csrfToken = resetCSRFToken();

/** (B) In zu schützenden FORM-Seiten (B1), oder Urls (B2) das CSRF-Token als 'hidden field' hinzufügen, vgl ESAPI DefaultHTTPUtilities.java**/

/** (B1) das CSRF-Token als 'hidden field' in den GET-Request hinzufügen **/
example.jsp
...
<%

String csrfTokenFieldName = org.owasp.esapi.HTTPUtilities.CSRF_TOKEN_NAME;
String csrfToken = ESAPI.httpUtilities().getCSRFToken();

%>
<input type="hidden" id="<%=csrfTokenFieldName%>" value="<%=csrfToken%>"/>
...

/** (B2) das CSRF-Token als URL Parameter in den GET-Request hinzufügen, jedoch **/
/** höheres Risiko, dass die URL und damit das Token dem Angreifer in die Hände fällt **/
<%

String unprotectedHref = "/main?function=TransferFunds&solution";
String betterProtectedHref = ESAPI.httpUtilities().addCSRFToken(unprotectedHref);

%>
<a href='<%=betterProtectedHref%>' target="_blank">Transfer Funds</a>

/** (C) Beim Empfang der Daten das CSRF-Token prüfen (GET-Request) **/
try {

ESAPI.httpUtilities().verifyCSRFToken(request);
} catch( IntrusionException e ) {
// log intrusion exception
// abort request and deny access

}
/** (D) Beim Abmelden bzw. Timeout die Session ungültig machen **/
User user = ESAPI.authenticator().logout;

Verteidigungs-Option 2 gegen 'Cross-Site Request Forgery (CSRF)':

CSRF Guard

/** Parameter für CsrfGuard und Java EE-Filter im Deployment **/
/** Descriptor des Webserver-Containers definieren (web.xml-Datei) **/

<context-param>

<param-name>Owasp.CsrfGuard.Config</param-name>
<param-value>WEB-INF/Owasp.CsrfGuard.properties</param-value>

</context-param>
<context-param>

<param-name>Owasp.CsrfGuard.Config.Print</param-name>
<param-value>true</param-value>

</context-param>
<listener>

<listener-class>org.owasp.csrfguard.CsrfGuardListener</listener-class>

</listener>
<filter>

<filter-name>CSRFGuard</filter-name>
<filter-class>org.owasp.csrfguard.CsrfGuardFilter</filter-class>

</filter>
<filter-mapping>

<filter-name>CSRFGuard</filter-name>
<url-pattern>/*</url-pattern>

</filter-mapping>

vgl Owasp.CsrfGuard.Test
Die Parameter in der Datei 'Owasp.CsrfGuard.properties' gemäß CSRFGuard_3_Configuration einstellen.

Verteidigungs-Option 3 gegen 'Cross-Site Request Forgery (CSRF)':

Java Server Faces (JSF)

JSF sendet ab Version 2.2 automatisch sichere CSRF-Token mit.

Referenzen

OWASP

Andere

This section is under construction. Please help OWASP to add missing content!
Comment: Bitte senden Sie uns weitere gute Beispiele mit PHP für diesen Abschnitt.
Verteidigungs-Option 1 gegen 'Cross-Site Request Forgery (CSRF)':

...

...


...

Verteidigungs-Option 2 gegen 'Cross-Site Request Forgery (CSRF)':
...



Verteidigungs-Option 3 gegen 'Cross-Site Request Forgery (CSRF)':

...
Tbd: konfig
...

Referenzen

OWASP

Andere

This section is under construction. Please help OWASP to add missing content!
Comment: Bitte senden Sie uns weitere gute Beispiele mit PHP für diesen Abschnitt.
Verteidigungs-Option 1 gegen 'Cross-Site Request Forgery (CSRF)':

ASP.NET Web Formulare

(noch unbearbeitet => tbd)
If you don't use Viewstate, then look to the default master page of the ASP.NET Web Forms default template for a manual anti-CSRF token.

private const string AntiXsrfTokenKey = "__AntiXsrfToken";
private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
private string _antiXsrfTokenValue;
protected void Page_Init(object sender, EventArgs e)
{

// The code below helps to protect against XSRF attacks
var requestCookie = Request.Cookies[AntiXsrfTokenKey];
Guid requestCookieGuidValue;
if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
{
// Use the Anti-XSRF token from the cookie
_antiXsrfTokenValue = requestCookie.Value;
Page.ViewStateUserKey = _antiXsrfTokenValue;
} else {
// Generate a new Anti-XSRF token and save to the cookie
_antiXsrfTokenValue = Guid.NewGuid().ToString("N");
Page.ViewStateUserKey = _antiXsrfTokenValue;
var responseCookie = new HttpCookie(AntiXsrfTokenKey)
{
HttpOnly = true,
Value = _antiXsrfTokenValue
};
if (FormsAuthentication.RequireSSL && Request.IsSecureConnection)
{
responseCookie.Secure = true;
}
Response.Cookies.Set(responseCookie);
}
Page.PreLoad += master_Page_PreLoad;

}

Quelle: .NET Security Cheat Sheet

Verteidigungs-Option 2 gegen 'Cross-Site Request Forgery (CSRF)':

tbd Text

Verteidigungs-Option 3 gegen 'Cross-Site Request Forgery (CSRF)':

tbd Text

Auswirkung(en) auf den Benutzer
{Soll so etwas rein?}

Z.B. Keine Bookmarks auf ausgefüllte Eingabe-Formulare, Suchergebnisse; Frameworks funktionieren teilweise nicht für Web 2.0

Referenzen

OWASP Andere OWASP

Andere

← A7-Fehlerhafte Autorisierung auf Anwendungsebene
Top 10 fuer Entwickler-2013: Inhaltsverzeichnis

Die Top-10-Risiken

A9-Nutzung von Komponenten mit bekannten Schwachstellen →

© 2002-2017 OWASP Foundation This document is licensed under the Creative Commons Attribution-ShareAlike 3.0 license. Some rights reserved. CC-by-sa-3 0-88x31.png