# HG changeset patch # User František Kučera # Date 1295111655 -3600 # Node ID ca3c7dd220fef56ee7ea1a722ede6103cbd8deea # Parent 2b458ac09044e29ba6d0904d0dbaf271436ee359 CSRF/XSRF ochrana při hlasování. diff -r 2b458ac09044 -r ca3c7dd220fe java/nekurak.net-lib/src/cz/frantovo/nekurak/preklady_cs.properties --- a/java/nekurak.net-lib/src/cz/frantovo/nekurak/preklady_cs.properties Sat Jan 15 14:27:02 2011 +0100 +++ b/java/nekurak.net-lib/src/cz/frantovo/nekurak/preklady_cs.properties Sat Jan 15 18:14:15 2011 +0100 @@ -43,7 +43,7 @@ prihlaseni.tlacitko=P\u0159ihl\u00e1sit se pridatPodnik.nadpis=P\u0159id\u00e1n\u00ed nov\u00e9ho podniku -pridatPodnik.bylPridan=Podnik byl \u00fasp\u011b\u0161n\u011b p\u0159id\u00e1n. +pridatPodnik.bylPridan=Podnik byl \u00fasp\u011b\u0161n\u011b p\u0159id\u00e1n. Zobrazovat se bude po schv\u00e1len\u00ed spr\u00e1vcem. pridatPodnik.nebylPridan=P\u0159i p\u0159id\u00e1v\u00e1n\u00ed podniku do\u0161lo k chyb\u011b. Zkontrolujte pros\u00edm zadan\u00e9 \u00fadaje. pridatPodnik.tlacitko=P\u0159idat podnik @@ -146,4 +146,4 @@ chat.nadpis=Chat chat.anonym=Kolemjdouc\u00ed -chat.tlacitkoOdeslat=Odeslat +chat.tlacitkoOdeslat=Odeslat \ No newline at end of file diff -r 2b458ac09044 -r ca3c7dd220fe java/nekurak.net-lib/src/cz/frantovo/nekurak/xml/HlasXML.java --- a/java/nekurak.net-lib/src/cz/frantovo/nekurak/xml/HlasXML.java Sat Jan 15 14:27:02 2011 +0100 +++ b/java/nekurak.net-lib/src/cz/frantovo/nekurak/xml/HlasXML.java Sat Jan 15 18:14:15 2011 +0100 @@ -12,6 +12,7 @@ private int podnik; private boolean kourit; + private String csrfToken; @XmlElement public int getPodnik() { @@ -30,4 +31,13 @@ public void setKourit(boolean hlas) { this.kourit = hlas; } + + @XmlElement + public String getCsrfToken() { + return csrfToken; + } + + public void setCsrfToken(String csrfToken) { + this.csrfToken = csrfToken; + } } diff -r 2b458ac09044 -r ca3c7dd220fe java/nekurak.net-web/src/java/cz/frantovo/nekurak/posluchac/OchranaProtiCSRF.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/nekurak.net-web/src/java/cz/frantovo/nekurak/posluchac/OchranaProtiCSRF.java Sat Jan 15 18:14:15 2011 +0100 @@ -0,0 +1,23 @@ +package cz.frantovo.nekurak.posluchac; + +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; + +/** + * + * @author fiki + */ +public class OchranaProtiCSRF implements HttpSessionListener { + + public static final String NAZEV_ATRIBUTU = "CSRF_TOKEN"; + + @Override + public void sessionCreated(HttpSessionEvent se) { + String csrfToken = String.valueOf(Math.random()); + se.getSession().setAttribute(NAZEV_ATRIBUTU, csrfToken); + } + + @Override + public void sessionDestroyed(HttpSessionEvent se) { + } +} diff -r 2b458ac09044 -r ca3c7dd220fe java/nekurak.net-web/src/java/cz/frantovo/nekurak/rest/HlasovaniREST.java --- a/java/nekurak.net-web/src/java/cz/frantovo/nekurak/rest/HlasovaniREST.java Sat Jan 15 14:27:02 2011 +0100 +++ b/java/nekurak.net-web/src/java/cz/frantovo/nekurak/rest/HlasovaniREST.java Sat Jan 15 18:14:15 2011 +0100 @@ -1,5 +1,6 @@ package cz.frantovo.nekurak.rest; +import cz.frantovo.nekurak.posluchac.OchranaProtiCSRF; import cz.frantovo.nekurak.util.HttpPozadavek; import cz.frantovo.nekurak.web.HledacSluzby; import cz.frantovo.nekurak.xml.HlasXML; @@ -23,7 +24,16 @@ @Consumes(MIME_XML) @Produces(MIME_TEXT) public String hlasuj(HlasXML xml) { + zkontrolujCSRF(pozadavek, xml); hledac.getPodnikEJB().hlasuj(xml.getPodnik(), xml.isKourit(), HttpPozadavek.getIPadresa(pozadavek)); return "ok"; } + + private static void zkontrolujCSRF(HttpServletRequest pozadavek, HlasXML xml) throws RuntimeException { + String csrfTokenOcekavany = (String) pozadavek.getSession().getAttribute(OchranaProtiCSRF.NAZEV_ATRIBUTU); + String csrfTokenObdrzeny = xml.getCsrfToken(); + if (csrfTokenOcekavany == null || !csrfTokenOcekavany.equals(csrfTokenObdrzeny)) { + throw new RuntimeException("CSRF token zaslaný klientem neodpovídá očekávanému."); + } + } } diff -r 2b458ac09044 -r ca3c7dd220fe java/nekurak.net-web/web/WEB-INF/tags/nekurak/stranka.tag --- a/java/nekurak.net-web/web/WEB-INF/tags/nekurak/stranka.tag Sat Jan 15 14:27:02 2011 +0100 +++ b/java/nekurak.net-web/web/WEB-INF/tags/nekurak/stranka.tag Sat Jan 15 18:14:15 2011 +0100 @@ -43,6 +43,7 @@ +

diff -r 2b458ac09044 -r ca3c7dd220fe java/nekurak.net-web/web/WEB-INF/web.xml --- a/java/nekurak.net-web/web/WEB-INF/web.xml Sat Jan 15 14:27:02 2011 +0100 +++ b/java/nekurak.net-web/web/WEB-INF/web.xml Sat Jan 15 18:14:15 2011 +0100 @@ -8,16 +8,19 @@ - + 404 /WEB-INF/chyby/404.jsp - + 500 /WEB-INF/chyby/500.jsp + + cz.frantovo.nekurak.posluchac.OchranaProtiCSRF + atom @@ -70,7 +73,7 @@ /kaptcha.jpg - + REST /zdroje/* @@ -80,7 +83,7 @@ - + javax.servlet.jsp.jstl.fmt.fallbackLocale cs diff -r 2b458ac09044 -r ca3c7dd220fe java/nekurak.net-web/web/js/hlasovani.js --- a/java/nekurak.net-web/web/js/hlasovani.js Sat Jan 15 14:27:02 2011 +0100 +++ b/java/nekurak.net-web/web/js/hlasovani.js Sat Jan 15 18:14:15 2011 +0100 @@ -1,7 +1,8 @@ var hlasovani = {}; hlasovani.hlasuj = function (podnik, hlas) { - var pozadavek = "" + hlas + "" + podnik + ""; + var csrfToken = document.getElementById("csrfToken").innerHTML; + var pozadavek = "" + hlas + "" + podnik + "" + csrfToken + ""; $.ajax({ type: "POST", @@ -10,14 +11,12 @@ contentType: "text/xml", dataType: "text", success: function(odpoved) { - if (odpoved == "ok") { - /** TODO: předělat informaci – nepoužívat alert ale text v SVG */ - /** TODO: Lokalizace */ - alert("Váš hlas byl přijat."); - } else { - /** TODO: předělat ošetřování chyb */ - alert("Při hlasování došlo k chybě."); - } + /** TODO: Lokalizace */ + alert("Váš hlas byl přijat."); + }, + error: function(odpoved) { + /** TODO: Lokalizace */ + alert("Při hlasování došlo k chybě. Zkuste obnovit stránku (F5) a opakujte hlasování."); } }); }; diff -r 2b458ac09044 -r ca3c7dd220fe java/nekurak.net-web/web/styl.css --- a/java/nekurak.net-web/web/styl.css Sat Jan 15 14:27:02 2011 +0100 +++ b/java/nekurak.net-web/web/styl.css Sat Jan 15 18:14:15 2011 +0100 @@ -15,6 +15,10 @@ margin: 0 auto; } +#csrfToken { + display: none; +} + #horniPruh { width: 1000px; border: 1px solid silver;