summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSavetheinternet <savetheinternet@n0v4.com>2011-03-26 22:50:03 +1100
committerSavetheinternet <savetheinternet@n0v4.com>2011-03-26 22:50:03 +1100
commitd40c6aefc6d18ae488b4163970f28c92e14bbc53 (patch)
tree2ced467a16e85d449789f84e39e5d9d05715d215
parentb64604ca30c391f015cb077dca140ad65338fb8b (diff)
custom flood filters
-rw-r--r--inc/config.php25
-rw-r--r--post.php54
2 files changed, 79 insertions, 0 deletions
diff --git a/inc/config.php b/inc/config.php
index 38468f57..e6e81da3 100644
--- a/inc/config.php
+++ b/inc/config.php
@@ -371,6 +371,31 @@
'raw'
);
+ // Custom flood filters. Detect flood attacks and reject new posts if there's a positive match.
+ //$config['flood_filters'] = Array(
+ // Array(
+ // 'condition' => Array(
+ // // 100 posts in the past 5 minutes (~20 p/m)
+ // 'posts_in_past_x_minutes' => Array(100, 5)
+ // ),
+ // // Don't allow the user to post
+ // 'action' => 'reject',
+ // // Display this message
+ // 'message' => 'Your post has been rejected on the suspicion of a flood attack on this board.'
+ // ),
+ // // Another filter
+ // Array(
+ // 'condition' => Array(
+ // // 10 new empty threads in the past 2 minutes
+ // 'threads_with_no_replies_in_past_x_minutes' => Array(10, 2),
+ // // Allow replies, but not new threads (ie. reject topics only).
+ // 'OP' => true
+ // ),
+ // 'action' => 'reject',
+ // 'message' => 'Your post has been rejected on the suspicion of a flood attack on this board (too many new threads); post a reply instead.'
+ // )
+ //);
+
// A small file in the main directory indicating that the script has been ran and the board(s) have been generated.
// This keeps the script from querying the database and causing strain when not needed.
$config['has_installed'] = '.installed';
diff --git a/post.php b/post.php
index 3306a58e..af592ae8 100644
--- a/post.php
+++ b/post.php
@@ -161,6 +161,8 @@
if(!isset($_SERVER['HTTP_REFERER']) || !preg_match($config['url_match'], $_SERVER['HTTP_REFERER'])) error($config['error']['bot']);
}
+ file_put_contents('test_a47.txt', print_r($_SERVER, true) . "\n" . print_r($_POST, true). "\n\n\n", FILE_APPEND);
+
// TODO: Since we're now using static HTML files, we can't give them cookies on their first page view
// Find another anti-spam method.
@@ -300,6 +302,58 @@
error($config['error']['flood']);
}
+ // Custom anti-spam filters
+ if(isset($config['flood_filters'])) {
+ foreach($config['flood_filters'] as &$filter) {
+ // Set up default stuff
+ if(!isset($filter['action']))
+ $filter['action'] = 'reject';
+ if(!isset($filter['message']))
+ $filter['message'] = 'Posting throttled by flood filter.';
+
+ foreach($filter['condition'] as $condition=>$value) {
+ if($condition == 'posts_in_past_x_minutes' && isset($value[0]) && isset($value[1])) {
+ // Check if there's been X posts in the past X minutes (on this board)
+
+ $query = prepare(sprintf("SELECT COUNT(*) AS `posts` FROM `posts_%s` WHERE `time` >= :time", $board['uri']));
+ $query->bindValue(':time', time() - ($value[1] * 60), PDO::PARAM_INT);
+ $query->execute() or error(db_error($query));
+ if(($count = $query->fetch()) && $count['posts'] >= $value[0]) {
+ // Matched filter
+ continue;
+ }
+ } elseif($condition == 'threads_with_no_replies_in_past_x_minutes' && isset($value[0]) && isset($value[1])) {
+ // Check if there's been X new empty threads posted in the past X minutes (on this board)
+
+ // Confusing query. I couldn't think of anything simpler...
+ $query = prepare(sprintf("SELECT ((SELECT COUNT(*) FROM `posts_%s` WHERE `thread` IS NULL AND `time` >= :time) - COUNT(DISTINCT(`threads`.`id`))) AS `posts` FROM `posts_%s` AS `threads` INNER JOIN `posts_%s` AS `replies` ON `replies`.`thread` = `threads`.`id` WHERE `threads`.`thread` IS NULL AND `threads`.`time` >= :time", $board['uri'], $board['uri'], $board['uri']));
+ $query->bindValue(':time', time() - ($value[1] * 60), PDO::PARAM_INT);
+ $query->execute() or error(db_error($query));
+ if(($count = $query->fetch()) && $count['posts'] >= $value[0]) {
+ // Matched filter
+ continue;
+ }
+ } elseif($condition == 'OP') {
+ // Am I OP?
+ if($OP)
+ continue;
+ } else {
+ // Unknown block
+ continue;
+ }
+
+ $did_not_match = true;
+ break;
+ }
+ if(!isset($did_not_match)) {
+ // Matched filter!
+ if($filter['action'] == 'reject') {
+ error($filter['message']);
+ }
+ }
+ }
+ }
+
if($post['has_file']) {
// Just trim the filename if it's too long
if(strlen($post['filename']) > 30) $post['filename'] = substr($post['filename'], 0, 27).'…';