|
From: <gem...@li...> - 2011-11-21 11:22:21
|
Revision: 251
http://gemstracker.svn.sourceforge.net/gemstracker/?rev=251&view=rev
Author: michieltcs
Date: 2011-11-21 11:22:10 +0000 (Mon, 21 Nov 2011)
Log Message:
-----------
Refs #454 - introduce throttling in AskAction
Modified Paths:
--------------
trunk/library/classes/Gems/Default/AskAction.php
trunk/library/classes/Gems/Project/ProjectSettings.php
Modified: trunk/library/classes/Gems/Default/AskAction.php
===================================================================
--- trunk/library/classes/Gems/Default/AskAction.php 2011-11-21 10:58:55 UTC (rev 250)
+++ trunk/library/classes/Gems/Default/AskAction.php 2011-11-21 11:22:10 UTC (rev 251)
@@ -215,9 +215,35 @@
$form->addElement($element);
if ($this->_request->isPost()) {
- if ($form->isValid($_POST)) {
+ $throttleSettings = $this->project->getAskThrottleSettings();
+
+ // Prune the database for (very) old attempts
+ $this->db->query("DELETE FROM gems__token_attempts WHERE gta_datetime < DATE_SUB(NOW(), INTERVAL ? second)",
+ $throttleSettings['period'] * 20);
+
+ // Retrieve the number of failed attempts that occurred within the specified window
+ $attemptData = $this->db->fetchRow("SELECT COUNT(1) AS attempts, UNIX_TIMESTAMP(MAX(gta_datetime)) AS last " .
+ "FROM gems__token_attempts WHERE gta_datetime > DATE_SUB(NOW(), INTERVAL ? second)", $throttleSettings['period']);
+
+ $remainingDelay = ($attemptData['last'] + $throttleSettings['delay']) - time();
+
+ if ($attemptData['attempts'] > $throttleSettings['threshold'] && $remainingDelay > 0) {
+ $this->escort->logger->log("Possible token brute force attack, throttling for $remainingDelay seconds", Zend_Log::ERR);
+
+ $this->addMessage($this->_('The server is currently busy, please wait a while and try again.'));
+ } else if ($form->isValid($_POST)) {
$this->_forward('forward');
return;
+ } else {
+ if (isset($_POST[MUtil_Model::REQUEST_ID])) {
+ $this->db->insert(
+ 'gems__token_attempts',
+ array(
+ 'gta_id_token' => $_POST[MUtil_Model::REQUEST_ID],
+ 'gta_ip_address' => $this->getRequest()->getClientIp()
+ )
+ );
+ }
}
} elseif ($id = $this->_getParam(MUtil_Model::REQUEST_ID)) {
$form->populate(array(MUtil_Model::REQUEST_ID => $id));
Modified: trunk/library/classes/Gems/Project/ProjectSettings.php
===================================================================
--- trunk/library/classes/Gems/Project/ProjectSettings.php 2011-11-21 10:58:55 UTC (rev 250)
+++ trunk/library/classes/Gems/Project/ProjectSettings.php 2011-11-21 11:22:10 UTC (rev 251)
@@ -236,6 +236,30 @@
return $this->defaultSessionTimeout;
}
}
+
+ /**
+ * Returns an array with throttling settings for the ask
+ * controller
+ *
+ * @return array
+ */
+ public function getAskThrottleSettings()
+ {
+ // Check for the 'askThrottle' config section
+ if (!empty($this->askThrottle)) {
+ return $this->askThrottle;
+ } else {
+ // Set some sensible defaults
+ // Detection window: 15 minutes
+ // Threshold: 20 requests per minute
+ // Delay: 10 seconds
+ $throttleSettings = array(
+ 'period' => 15 * 60,
+ 'threshold' => 15 * 20,
+ 'delay' => 10
+ );
+ }
+ }
/**
* Returns the super admin name, if any
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|