CVE-2013-7251 (published 2014-01-02T14:59Z)

Multiple cross-site request forgery (CSRF) vulnerabilities in ProjectForge before 5.3 allow remote attackers to hijack the authentication of arbitrary users via vectors related to (1) web/admin/, (2) web/core/, (3) web/dialog/, (4) web/fibu/, (5) web/mobile/, (6) web/task/, or (7) web/wicket/.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)

Weakness information:
cwe_id: CWE-352
cwe_name: Cross-Site Request Forgery (CSRF)
description: The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
extended_description: When a web server is designed to receive a request from a client without any mechanism for verifying that it was intentionally sent, then it might be possible for an attacker to trick a client into making an unintentional request to the web server which will be treated as an authentic request. This can be done via a URL, image load, XMLHttpRequest, etc. and can result in exposure of data or unintended code execution.
         

Fix information:
repo_url: https://github.com/micromata/projectforge-webapp
commit_details: repo_url: https://github.com/micromata/projectforge-webapp
author: Kai Reinhard
author_date: 2013-12-06 00:14:24+01:00
msg: CSRF protection.
repository: repo_url: https://github.com/micromata/projectforge-webapp
repo_name: micromata/projectforge-webapp
description: ProjectForge is a web-based solution for project management including time tracking, team-calendar, financial administration, issue management, controlling and managing work-break-down-structures (e. g. together with JIRA as issue management system).  
repo_language: Java
owner: micromata
file_changes: filename: SetupForm.java
change_type: ModificationType.MODIFY
diff: @@ -40,6 +40,7 @@ import org.projectforge.core.ConfigurationDO;
 import org.projectforge.database.InitDatabaseDao;
 import org.projectforge.user.UserDao;
 import org.projectforge.web.wicket.AbstractForm;
+import org.projectforge.web.wicket.CsrfTokenHandler;
 import org.projectforge.web.wicket.WicketUtils;
 import org.projectforge.web.wicket.bootstrap.GridBuilder;
 import org.projectforge.web.wicket.components.MaxLengthTextField;
@@ -86,9 +87,15 @@ public class SetupForm extends AbstractForm<SetupForm, SetupPage>
 
   private String encryptedPassword;
 
+  /**
+   * Cross site request forgery token.
+   */
+  private final CsrfTokenHandler csrfTokenHandler;
+
   public SetupForm(final SetupPage parentPage)
   {
     super(parentPage, "setupform");
+    csrfTokenHandler = new CsrfTokenHandler(this);
   }
 
   @Override
@@ -227,6 +234,7 @@ public class SetupForm extends AbstractForm<SetupForm, SetupPage>
         @Override
         public final void onSubmit()
         {
+          csrfTokenHandler.onSubmit();
           parentPage.finishSetup();
         }
       };
@@ -237,6 +245,13 @@ public class SetupForm extends AbstractForm<SetupForm, SetupPage>
     }
   }
 
+  @Override
+  protected void onSubmit()
+  {
+    super.onSubmit();
+    csrfTokenHandler.onSubmit();
+  }
+
   public SetupTarget getSetupMode()
   {
     return setupMode;

programming_language: Java
filename: SetupImportForm.java
change_type: ModificationType.MODIFY
diff: @@ -29,6 +29,7 @@ import org.apache.wicket.markup.repeater.RepeatingView;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.util.lang.Bytes;
 import org.projectforge.web.wicket.AbstractForm;
+import org.projectforge.web.wicket.CsrfTokenHandler;
 import org.projectforge.web.wicket.bootstrap.GridBuilder;
 import org.projectforge.web.wicket.components.SingleButtonPanel;
 import org.projectforge.web.wicket.flowlayout.FieldsetPanel;
@@ -42,10 +43,23 @@ public class SetupImportForm extends AbstractForm<SetupImportForm, SetupPage>
 
   protected String filename;
 
+  /**
+   * Cross site request forgery token.
+   */
+  private final CsrfTokenHandler csrfTokenHandler;
+
   public SetupImportForm(final SetupPage parentPage)
   {
     super(parentPage, "importform");
     initUpload(Bytes.megabytes(100));
+    csrfTokenHandler = new CsrfTokenHandler(this);
+  }
+
+  @Override
+  protected void onSubmit()
+  {
+    super.onSubmit();
+    csrfTokenHandler.onSubmit();
   }
 
   @Override

programming_language: Java
filename: SetupPage.html
change_type: ModificationType.MODIFY
diff: @@ -21,6 +21,7 @@
             <div class="button_bar">
               <wicket:container wicket:id="buttons">[action buttons]</wicket:container>
             </div>
+            <input type="hidden" wicket:id="csrfToken" />
           </form>
         </div>
       </div>
@@ -32,6 +33,7 @@
           <div class="button_bar">
             <wicket:container wicket:id="buttons">[action buttons]</wicket:container>
           </div>
+          <input type="hidden" wicket:id="csrfToken" />
         </form>
       </div>
     </div>

programming_language: HTML
filename: SystemUpdateForm.java
change_type: ModificationType.MODIFY
diff: @@ -38,6 +38,7 @@ import org.projectforge.continuousdb.UpdateEntry;
 import org.projectforge.continuousdb.UpdatePreCheckStatus;
 import org.projectforge.web.HtmlHelper;
 import org.projectforge.web.wicket.AbstractForm;
+import org.projectforge.web.wicket.CsrfTokenHandler;
 import org.projectforge.web.wicket.bootstrap.GridBuilder;
 import org.projectforge.web.wicket.components.SingleButtonPanel;
 import org.projectforge.web.wicket.flowlayout.CheckBoxPanel;
@@ -54,6 +55,11 @@ public class SystemUpdateForm extends AbstractForm<SystemUpdateForm, SystemUpdat
 
   private GridBuilder gridBuilder;
 
+  /**
+   * Cross site request forgery token.
+   */
+  private final CsrfTokenHandler csrfTokenHandler;
+
   /**
    * List to create content menu in the desired order before creating the RepeatingView.
    */
@@ -62,6 +68,7 @@ public class SystemUpdateForm extends AbstractForm<SystemUpdateForm, SystemUpdat
   public SystemUpdateForm(final SystemUpdatePage parentPage)
   {
     super(parentPage);
+    csrfTokenHandler = new CsrfTokenHandler(this);
   }
 
   @Override
@@ -165,4 +172,11 @@ public class SystemUpdateForm extends AbstractForm<SystemUpdateForm, SystemUpdat
     super.onBeforeRender();
     actionButtons.render();
   }
+
+  @Override
+  protected void onSubmit()
+  {
+    super.onSubmit();
+    csrfTokenHandler.onSubmit();
+  }
 }

programming_language: Java
filename: SystemUpdatePage.html
change_type: ModificationType.MODIFY
diff: @@ -47,6 +47,7 @@
       <div class="button_bar">
         <wicket:container wicket:id="buttons">[action buttons]</wicket:container>
       </div>
+      <input type="hidden" wicket:id="csrfToken" />
     </form>
   </wicket:extend>
 </body>

programming_language: HTML
filename: NavTopPanel.html
change_type: ModificationType.MODIFY
diff: @@ -39,6 +39,7 @@
           </div>
           <form class="navbar-search pull-left" wicket:id="searchForm" autocomplete="off">
             <input type="text" class="search-query span2" placeholder="Search" wicket:id="searchField">
+            <input type="hidden" wicket:id="csrfToken" />
           </form>
           <ul class="nav pull-right">
             <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><span wicket:id="user">[Kai Reinhard]</span><b

programming_language: HTML
filename: NavTopPanel.java
change_type: ModificationType.MODIFY
diff: @@ -59,6 +59,7 @@ import org.projectforge.web.mobile.MenuMobilePage;
 import org.projectforge.web.user.ChangePasswordPage;
 import org.projectforge.web.user.MyAccountEditPage;
 import org.projectforge.web.wicket.AbstractSecuredPage;
+import org.projectforge.web.wicket.CsrfTokenHandler;
 import org.projectforge.web.wicket.FeedbackPage;
 import org.projectforge.web.wicket.MySession;
 import org.projectforge.web.wicket.WicketUtils;
@@ -82,6 +83,11 @@ public class NavTopPanel extends NavAbstractPanel
 
   private BookmarkDialog bookmarkDialog;
 
+  /**
+   * Cross site request forgery token.
+   */
+  private CsrfTokenHandler csrfTokenHandler;
+
   public NavTopPanel(final String id, final UserXmlPreferencesCache userXmlPreferencesCache, final AccessChecker accessChecker)
   {
     super(id);
@@ -117,6 +123,7 @@ public class NavTopPanel extends NavAbstractPanel
       @Override
       protected void onSubmit()
       {
+        csrfTokenHandler.onSubmit();
         if (StringUtils.isNotBlank(searchString) == true) {
           final SearchPage searchPage = new SearchPage(new PageParameters(), searchString);
           setResponsePage(searchPage);
@@ -124,6 +131,7 @@ public class NavTopPanel extends NavAbstractPanel
         super.onSubmit();
       }
     };
+    csrfTokenHandler = new CsrfTokenHandler(searchForm);
     add(searchForm);
     final TextField<String> searchField = new TextField<String>("searchField", new PropertyModel<String>(searchForm, "searchString"));
     WicketUtils.setPlaceHolderAttribute(searchField, getString("search.search"));

programming_language: Java
filename: ModalDialog.html
change_type: ModificationType.MODIFY
diff: @@ -3,7 +3,9 @@
     <wicket:container wicket:id="mainSubContainer">
       <div class="modal-header">
         <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
-        <h3 id="myModalLabel" wicket:id="titleContainer"><span wicket:id="titleText">[title]</span></h3>
+        <h3 id="myModalLabel" wicket:id="titleContainer">
+          <span wicket:id="titleText">[title]</span>
+        </h3>
       </div>
       <form wicket:id="form" autocomplete="off">
         <div class="modal-body" wicket:id="gridContent">
@@ -13,6 +15,7 @@
         <div class="modal-footer" wicket:id="buttonBar">
           <wicket:container wicket:id="actionButtons" />
         </div>
+        <input type="hidden" wicket:id="csrfToken" />
       </form>
     </wicket:container>
   </div>

programming_language: HTML
filename: ModalDialog.java
change_type: ModificationType.MODIFY
diff: @@ -39,6 +39,7 @@ import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
 import org.projectforge.web.core.NavTopPanel;
+import org.projectforge.web.wicket.CsrfTokenHandler;
 import org.projectforge.web.wicket.WicketUtils;
 import org.projectforge.web.wicket.bootstrap.GridBuilder;
 import org.projectforge.web.wicket.components.SingleButtonPanel;
@@ -97,6 +98,11 @@ public abstract class ModalDialog extends Panel
    */
   protected MyComponentsRepeater<Component> actionButtons;
 
+  /**
+   * Cross site request forgery token.
+   */
+  protected CsrfTokenHandler csrfTokenHandler;
+
   /**
    * @param id
    */
@@ -231,6 +237,7 @@ public abstract class ModalDialog extends Panel
       @Override
       protected void onEvent(final AjaxRequestTarget target)
       {
+        csrfTokenHandler.onSubmit();
         handleCloseEvent(target);
       }
     });
@@ -288,6 +295,7 @@ public abstract class ModalDialog extends Panel
 
   public void close(final AjaxRequestTarget target)
   {
+    csrfTokenHandler.onSubmit();
     target.appendJavaScript("$('#" + getMainContainerMarkupId() + "').modal('hide');");
   }
 
@@ -366,6 +374,7 @@ public abstract class ModalDialog extends Panel
   protected void init(final Form< ? > form)
   {
     this.form = form;
+    csrfTokenHandler = new CsrfTokenHandler(form);
     mainSubContainer.add(form);
     form.add(gridContentContainer);
     form.add(buttonBarContainer);
@@ -374,6 +383,7 @@ public abstract class ModalDialog extends Panel
         @Override
         public void callback(final AjaxRequestTarget target)
         {
+          csrfTokenHandler.onSubmit();
           onCancelButtonSubmit(target);
           close(target);
         }
@@ -385,6 +395,7 @@ public abstract class ModalDialog extends Panel
       @Override
       public void callback(final AjaxRequestTarget target)
       {
+        csrfTokenHandler.onSubmit();
         if (onCloseButtonSubmit(target)) {
           close(target);
         }
@@ -393,6 +404,7 @@ public abstract class ModalDialog extends Panel
       @Override
       public void onError(final AjaxRequestTarget target, final Form< ? > form)
       {
+        csrfTokenHandler.onSubmit();
         ModalDialog.this.onError(target, form);
       }
     }, closeButtonLabel != null ? closeButtonLabel : getString("close"), SingleButtonPanel.NORMAL);
@@ -416,6 +428,7 @@ public abstract class ModalDialog extends Panel
 
   protected void ajaxError(final String error, final AjaxRequestTarget target)
   {
+    csrfTokenHandler.onSubmit();
     form.error(error);
     target.add(formFeedback);
   }
@@ -427,6 +440,7 @@ public abstract class ModalDialog extends Panel
    */
   protected void handleCloseEvent(final AjaxRequestTarget target)
   {
+    csrfTokenHandler.onSubmit();
   }
 
   /**
@@ -505,6 +519,7 @@ public abstract class ModalDialog extends Panel
       @Override
       protected void onSubmit(final AjaxRequestTarget target, final Form< ? > form)
       {
+        csrfTokenHandler.onSubmit();
         ajaxCallback.callback(target);
       }
 

programming_language: Java
filename: RechnungCostEditTablePanel.html
change_type: ModificationType.MODIFY
diff: @@ -32,7 +32,10 @@
         </tbody>
       </table>
       <div>
-      <wicket:message key="rest" />: <span wicket:id="restValue">[-1234,00]</span></div>
+        <wicket:message key="rest" />
+        : <span wicket:id="restValue">[-1234,00]</span>
+      </div>
+      <input type="hidden" wicket:id="csrfToken" />
     </form>
   </wicket:panel>
 </body>

programming_language: HTML
filename: RechnungCostEditTablePanel.java
change_type: ModificationType.MODIFY
diff: @@ -54,6 +54,7 @@ import org.projectforge.fibu.kost.Kost2DO;
 import org.projectforge.fibu.kost.Kost2Dao;
 import org.projectforge.fibu.kost.KostZuweisungDO;
 import org.projectforge.fibu.kost.KostZuweisungenCopyHelper;
+import org.projectforge.web.wicket.CsrfTokenHandler;
 import org.projectforge.web.wicket.WicketAjaxUtils;
 import org.projectforge.web.wicket.WicketUtils;
 import org.projectforge.web.wicket.components.MinMaxNumberField;
@@ -85,17 +86,31 @@ public class RechnungCostEditTablePanel extends Panel
 
   MyAjaxComponentHolder ajaxComponents = new MyAjaxComponentHolder();
 
+  /**
+   * Cross site request forgery token.
+   */
+  private final CsrfTokenHandler csrfTokenHandler;
+
   /**
    * @param id
    */
+  @SuppressWarnings("serial")
   public RechnungCostEditTablePanel(final String id)
   {
     super(id);
     feedbackPanel = new FeedbackPanel("feedback");
     ajaxComponents.register(feedbackPanel);
     add(feedbackPanel);
-    this.form = new Form<AbstractRechnungsPositionDO>("form");
+    this.form = new Form<AbstractRechnungsPositionDO>("form") {
+      @Override
+      protected void onSubmit()
+      {
+        super.onSubmit();
+        csrfTokenHandler.onSubmit();
+      }
+    };
     add(form);
+    csrfTokenHandler = new CsrfTokenHandler(form);
     rows = new RepeatingView("rows");
     form.add(rows);
   }

programming_language: Java
filename: AbstractMobileEditForm.java
change_type: ModificationType.MODIFY
diff: @@ -28,6 +28,7 @@ import org.apache.wicket.markup.html.form.SubmitLink;
 import org.apache.wicket.markup.html.panel.FeedbackPanel;
 import org.apache.wicket.markup.repeater.RepeatingView;
 import org.projectforge.core.AbstractBaseDO;
+import org.projectforge.web.wicket.CsrfTokenHandler;
 import org.projectforge.web.wicket.mobileflowlayout.MobileGridBuilder;
 
 public abstract class AbstractMobileEditForm<O extends AbstractBaseDO< ? >, P extends AbstractMobileEditPage< ? , ? , ? >> extends
@@ -39,10 +40,23 @@ AbstractMobileForm<O, P>
 
   protected MobileGridBuilder gridBuilder;
 
+  /**
+   * Cross site request forgery token.
+   */
+  private final CsrfTokenHandler csrfTokenHandler;
+
   public AbstractMobileEditForm(final P parentPage, final O data)
   {
     super(parentPage);
     this.data = data;
+    csrfTokenHandler = new CsrfTokenHandler(this);
+  }
+
+  @Override
+  protected void onSubmit()
+  {
+    super.onSubmit();
+    csrfTokenHandler.onSubmit();
   }
 
   public O getData()

programming_language: Java
filename: AbstractMobileEditPage.html
change_type: ModificationType.MODIFY
diff: @@ -19,6 +19,7 @@
         <p>
           <a wicket:id="submitButton" rel="external" data-role="button"><wicket:container wicket:id="label">[create or update]</wicket:container></a>
         </p>
+        <input type="hidden" wicket:id="csrfToken" />
       </form>
     </div>
   </wicket:extend>

programming_language: HTML
filename: AbstractMobileListForm.java
change_type: ModificationType.MODIFY
diff: @@ -27,6 +27,7 @@ import org.apache.wicket.AttributeModifier;
 import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.model.PropertyModel;
 import org.projectforge.core.BaseSearchFilter;
+import org.projectforge.web.wicket.CsrfTokenHandler;
 
 public abstract class AbstractMobileListForm<F extends BaseSearchFilter, P extends AbstractMobileListPage< ? , ? , ? >> extends
 AbstractMobileForm<AbstractMobileListForm< ? , ? >, AbstractMobileListPage< ? , ? , ? >>
@@ -37,6 +38,11 @@ AbstractMobileForm<AbstractMobileListForm< ? , ? >, AbstractMobileListPage< ? ,
 
   protected F filter;
 
+  /**
+   * Cross site request forgery token.
+   */
+  private final CsrfTokenHandler csrfTokenHandler;
+
   @SuppressWarnings("unchecked")
   public AbstractMobileListForm(final AbstractMobileListPage< ? , ? , ? > parentPage)
   {
@@ -51,6 +57,14 @@ AbstractMobileForm<AbstractMobileListForm< ? , ? >, AbstractMobileListPage< ? ,
       filter = newFilter();
       parentPage.putUserPrefEntry(userPrefFilterKey, filter, true);
     }
+    csrfTokenHandler = new CsrfTokenHandler(this);
+  }
+
+  @Override
+  protected void onSubmit()
+  {
+    super.onSubmit();
+    csrfTokenHandler.onSubmit();
   }
 
   protected void init()

programming_language: Java
filename: AbstractMobileListPage.html
change_type: ModificationType.MODIFY
diff: @@ -6,12 +6,15 @@
 </head>
 
 <body>
-<wicket:extend>
-  <form wicket:id="form" autocomplete="off">
-  <div data-role="fieldcontain" id="searchfield"><input type="text" data-type="search" wicket:id="searchField" id="search" placeholder="Suche" /></div>
-  </form>
-  <wicket:container wicket:id="listViewPage">
-  </wicket:container>
-</wicket:extend>
+  <wicket:extend>
+    <form wicket:id="form" autocomplete="off">
+      <div data-role="fieldcontain" id="searchfield">
+        <input type="text" data-type="search" wicket:id="searchField" id="search" placeholder="Suche" />
+      </div>
+      <input type="hidden" wicket:id="csrfToken" />
+    </form>
+    <wicket:container wicket:id="listViewPage">
+    </wicket:container>
+  </wicket:extend>
 </body>
 </html>

programming_language: HTML
filename: TaskTreeForm.java
change_type: ModificationType.MODIFY
diff: @@ -31,6 +31,7 @@ import org.apache.wicket.model.Model;
 import org.apache.wicket.model.PropertyModel;
 import org.projectforge.task.TaskFilter;
 import org.projectforge.web.wicket.AbstractForm;
+import org.projectforge.web.wicket.CsrfTokenHandler;
 import org.projectforge.web.wicket.WebConstants;
 import org.projectforge.web.wicket.WicketUtils;
 import org.projectforge.web.wicket.bootstrap.GridBuilder;
@@ -65,6 +66,11 @@ public class TaskTreeForm extends AbstractForm<TaskFilter, TaskTreePage>
 
   protected GridBuilder gridBuilder;
 
+  /**
+   * Cross site request forgery token.
+   */
+  private final CsrfTokenHandler csrfTokenHandler;
+
   @Override
   @SuppressWarnings("serial")
   protected void init()
@@ -131,7 +137,8 @@ public class TaskTreeForm extends AbstractForm<TaskFilter, TaskTreePage>
         }
       };
 
-      listViewButtonPanel = new SingleButtonPanel(actionButtons.newChildId(), listViewButton, getString("listView"), SingleButtonPanel.NORMAL);
+      listViewButtonPanel = new SingleButtonPanel(actionButtons.newChildId(), listViewButton, getString("listView"),
+          SingleButtonPanel.NORMAL);
       actionButtons.add(listViewButtonPanel);
     }
     {
@@ -153,6 +160,7 @@ public class TaskTreeForm extends AbstractForm<TaskFilter, TaskTreePage>
   public TaskTreeForm(final TaskTreePage parentPage)
   {
     super(parentPage);
+    csrfTokenHandler = new CsrfTokenHandler(this);
   }
 
   @Override
@@ -198,6 +206,7 @@ public class TaskTreeForm extends AbstractForm<TaskFilter, TaskTreePage>
   protected void onSubmit()
   {
     super.onSubmit();
+    csrfTokenHandler.onSubmit();
     parentPage.refresh();
   }
 

programming_language: Java
filename: TaskTreePage.html
change_type: ModificationType.MODIFY
diff: @@ -23,6 +23,7 @@
         <wicket:container wicket:id="actionButtons">[cancel] [search]</wicket:container>
       </div>
       <div wicket:id="tree">[tree]</div>
+      <input type="hidden" wicket:id="csrfToken" />
     </form>
     <div class="alert alert-info" wicket:id="info">[Click on row to select one task.]</div>
   </wicket:extend>

programming_language: HTML
filename: CsrfTokenHandler.java
change_type: ModificationType.MODIFY
diff: @@ -29,7 +29,7 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.wicket.Session;
 import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.HiddenField;
-import org.apache.wicket.model.Model;
+import org.apache.wicket.model.PropertyModel;
 import org.projectforge.core.InternalErrorException;
 
 /**
@@ -43,7 +43,7 @@ public class CsrfTokenHandler implements Serializable
 
   private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(CsrfTokenHandler.class);
 
-  private HiddenField<String> csrfTokenField;
+  private final String csrfToken;
 
   /**
    * The given form should contain a hidden field named 'csrfToken'.
@@ -51,7 +51,8 @@ public class CsrfTokenHandler implements Serializable
    */
   public CsrfTokenHandler(final Form< ? > form)
   {
-    form.add(csrfTokenField = new HiddenField<String>("csrfToken", Model.of(getCsrfSessionToken())));
+    csrfToken = getCsrfSessionToken();
+    form.add(new HiddenField<String>("csrfToken", new PropertyModel<String>(this, "csrfToken")));
   }
 
   /**
@@ -71,12 +72,11 @@ public class CsrfTokenHandler implements Serializable
   public void onSubmit()
   {
     final String sessionCsrfToken = getCsrfSessionToken();
-    final String postedCsrfToken = this.csrfTokenField.getInput();
-    if (StringUtils.equals(sessionCsrfToken, postedCsrfToken) == false) {
+    if (StringUtils.equals(sessionCsrfToken, csrfToken) == false) {
       log.error("Cross site request forgery alert. csrf token doesn't match! session csrf token="
           + sessionCsrfToken
           + ", posted csrf token="
-          + postedCsrfToken);
+          + csrfToken);
       throw new InternalErrorException("errorpage.csrfError");
     }
   }

programming_language: Java
filename: DropFileContainer.html
change_type: ModificationType.MODIFY
diff: @@ -1,11 +1,13 @@
 <wicket:panel xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
   <div class="pf_dnd" wicket:id="main">
     <input type="file" id="fileselect" class="pf_fileselect" />
-    <div class="pf_filedrag"><wicket:message key="drop" /></div>
+    <div class="pf_filedrag">
+      <wicket:message key="drop" />
+    </div>
     <form wicket:id="hiddenForm" class="pf_hiddenForm">
       <textarea class="pf_text" wicket:id="importString"></textarea>
       <textarea class="pf_name" wicket:id="importFileName"></textarea>
-      <input type="submit" class="pf_submit" wicket:id="submitButton" />
+      <input type="submit" class="pf_submit" wicket:id="submitButton" /> <input type="hidden" wicket:id="csrfToken" />
     </form>
   </div>
 </wicket:panel>

programming_language: HTML
filename: DropFileContainer.java
change_type: ModificationType.MODIFY
diff: @@ -33,6 +33,7 @@ import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.markup.html.form.TextArea;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.CompoundPropertyModel;
+import org.projectforge.web.wicket.CsrfTokenHandler;
 import org.projectforge.web.wicket.WicketUtils;
 
 /**
@@ -47,8 +48,14 @@ public abstract class DropFileContainer extends Panel
   private static final long serialVersionUID = 3622467918922963503L;
 
   private final WebMarkupContainer main;
+
   private final String mimeType;
 
+  /**
+   * Cross site request forgery token.
+   */
+  private  CsrfTokenHandler csrfTokenHandler;
+
   /**
    * @param id
    */
@@ -57,7 +64,8 @@ public abstract class DropFileContainer extends Panel
     this(id, null);
   }
 
-  public DropFileContainer(final String id, final String mimeType) {
+  public DropFileContainer(final String id, final String mimeType)
+  {
     super(id);
     this.mimeType = mimeType;
     main = new WebMarkupContainer("main");
@@ -82,6 +90,7 @@ public abstract class DropFileContainer extends Panel
       @Override
       protected void onSubmit(final AjaxRequestTarget target, final Form< ? > form)
       {
+        csrfTokenHandler.onSubmit();
         final FormBean modelObject = hiddenForm.getModel().getObject();
         onStringImport(target, modelObject.importFileName, modelObject.importString);
       }
@@ -93,6 +102,7 @@ public abstract class DropFileContainer extends Panel
       }
 
     });
+    csrfTokenHandler = new CsrfTokenHandler(hiddenForm);
   }
 
   /**

programming_language: Java