added: antispam mechanism

each html form has a hidden form_id and counter_id
counter_id on the client side is generated through javascript code
on the server the form_id and counter_id is stored in the session
after sending the html form the server checks the form_id and counter_id




git-svn-id: svn://ttmath.org/publicrep/winix/trunk@1116 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2018-07-02 11:16:36 +00:00
parent 08123fe6ac
commit 1c05c31721
22 changed files with 337 additions and 15 deletions

File diff suppressed because one or more lines are too long

View File

@ -313,6 +313,7 @@ void Config::AssignValues(bool stdout_is_closed)
check_proxy_ip_header = Bool(L"check_proxy_ip_header", false); check_proxy_ip_header = Bool(L"check_proxy_ip_header", false);
proxy_ip_header = Text(L"proxy_ip_header", L"X_Real_IP"); proxy_ip_header = Text(L"proxy_ip_header", L"X_Real_IP");
antispam_list_max_size = Size(L"antispam_list_max_size", 10);
} }

View File

@ -766,6 +766,12 @@ public:
// default: X_Real_IP // default: X_Real_IP
std::wstring proxy_ip_header; std::wstring proxy_ip_header;
// antispam mechanizm
// size of an list for map: form_id to counter_id for anonymous users (each session has such an map)
// this value allowes you to open the same or different html form in the browser more than once
// and each form has its own form_id and counter_id
// default: 10 (max ten forms can be open in different tabs)
size_t antispam_list_max_size;
Config(); Config();

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2008-2014, Tomasz Sowa * Copyright (c) 2008-2018, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -38,6 +38,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <ctime> #include <ctime>
#include <map>
#include "item.h" #include "item.h"
#include "error.h" #include "error.h"
#include "user.h" #include "user.h"
@ -55,6 +56,7 @@ namespace Winix
struct Session struct Session
{ {
Session(); Session();
Session(const Session & ses); Session(const Session & ses);
Session & operator=(const Session & ses); Session & operator=(const Session & ses);
@ -99,13 +101,6 @@ struct Session
bool remember_me; bool remember_me;
// rebus - set by rebus_question(Info & i) from templates
Rebus::Item * rebus_item;
bool rebus_checked;
int spam_score;
// if true then this session will be removed by SessionManager // if true then this session will be removed by SessionManager
// without checking the time expiration // without checking the time expiration
bool remove_me; bool remove_me;
@ -127,6 +122,17 @@ struct Session
// (it can be null) // (it can be null)
IPBan * ip_ban; IPBan * ip_ban;
// rebus - set by rebus_question(Info & i) from templates
Rebus::Item * rebus_item;
bool rebus_checked;
int spam_score;
std::map<long, long> antispan;
}; };

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2008-2014, Tomasz Sowa * Copyright (c) 2008-2018, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -81,6 +81,8 @@ bool Emacs::HasAccess()
// !! IMPROVE ME in functions.cpp there is a similar function
/*
bool Emacs::PostEmacsCheckAbuse(bool adding) bool Emacs::PostEmacsCheckAbuse(bool adding)
{ {
if( !system->rebus.CheckRebus() ) if( !system->rebus.CheckRebus() )
@ -101,6 +103,7 @@ bool Emacs::PostEmacsCheckAbuse(bool adding)
return true; return true;
} }
*/
// !! zmienic nazwy // !! zmienic nazwy
@ -152,7 +155,7 @@ void Emacs::MakePost()
if( adding ) if( adding )
functions->SetUser(cur->request->item); // set user before checking the rebus functions->SetUser(cur->request->item); // set user before checking the rebus
if( !PostEmacsCheckAbuse(adding) ) if( functions->CheckAbuse() )
return; return;
if( adding ) if( adding )

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2010-2014, Tomasz Sowa * Copyright (c) 2010-2018, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -56,7 +56,6 @@ public:
private: private:
bool HasAccess(const Item & item); // !! takie funkcje to nie powinny byc skladowe modelu? bool HasAccess(const Item & item); // !! takie funkcje to nie powinny byc skladowe modelu?
bool PostEmacsCheckAbuse(bool adding);
void DoRedirectIfNeeded(bool adding); void DoRedirectIfNeeded(bool adding);
int NotifyCodeEdit(); int NotifyCodeEdit();
int NotifyCodeAdd(); int NotifyCodeAdd();

View File

@ -487,7 +487,43 @@ void Functions::CheckGetPostTimes(time_t difference)
// !!uwaga zwracana warto<74><6F> zmieniona (true/false)
bool Functions::CheckAntispamCounter()
{
if( !cur->session->puser )
{
long form_id = Tol(cur->request->PostVar(L"winix_form_id"));
long counter_id = Tol(cur->request->PostVar(L"winix_form_counter"));
auto i = cur->session->antispan.find(form_id);
if( i != cur->session->antispan.end() )
{
if( i->second != counter_id )
{
log << log2 << "AP: you have provided a different counter, expecting: " << i->second << ", given: " << counter_id << logend;
cur->session->antispan.erase(i);
return true;
}
else
{
cur->session->antispan.erase(i);
log << log2 << "AP: provided a correct counter for this form" << logend;
}
}
else
{
log << log2 << "AP: nonexisting form_id" << logend;
return true;
}
}
return false;
}
// !!uwaga zwracana wartosc zmieniona (true/false)
// !! IMPROVE ME in emacs.cpp there is a similar function
bool Functions::CheckAbuse() bool Functions::CheckAbuse()
{ {
if( !system->rebus.CheckRebus() ) if( !system->rebus.CheckRebus() )
@ -496,6 +532,11 @@ bool Functions::CheckAbuse()
return true; return true;
} }
if( CheckAntispamCounter() )
{
return true;
}
CheckGetPostTimes(); CheckGetPostTimes();
if( cur->session->spam_score > 0 ) if( cur->session->spam_score > 0 )

View File

@ -221,6 +221,7 @@ private:
void CheckFunctionFollowDir(bool was_default_function); void CheckFunctionFollowDir(bool was_default_function);
void CheckFunctionFollowSymlink(bool was_default_function); void CheckFunctionFollowSymlink(bool was_default_function);
bool CheckAntispamCounter();
}; };

19
winixd/html/antispam.html Normal file
View File

@ -0,0 +1,19 @@
<input type="hidden" name="winix_form_id" value="[antispam_create_new_form_id_for_this_session]">
<input type="hidden" name="winix_form_counter" value="" class="winix_form_counter">
<script>
[# call antispam_create_new_form_id_for_this_session before antispam_loop]
function winix_calc_me()\{var counter = 0;[for antispam_loop]counter [antispam_loop_operator] [antispam_counter];[end]return counter;\}
var el = document.getElementsByClassName("winix_form_counter");
var val = winix_calc_me();
for(var i=0 ; i<el.length ; ++i)
\{
console.log(el\[i\]);
el\[i\].value = val;
\}
</script>

View File

@ -52,6 +52,8 @@
<label for="winix_rebus_id">{rebus_how_is_it} [rebus_question]?</p> <label for="winix_rebus_id">{rebus_how_is_it} [rebus_question]?</p>
<input id="winix_rebus_id" type="text" name="rebus"> <input id="winix_rebus_id" type="text" name="rebus">
</div> </div>
[include "antispam.html"]
[end] [end]

View File

@ -24,6 +24,8 @@
<p class="withnext">{rebus_how_is_it} [rebus_question]?</p> <p class="withnext">{rebus_how_is_it} [rebus_question]?</p>
<input class="edit" type="text" name="rebus"> <input class="edit" type="text" name="rebus">
[include "antispam.html"]
[end] [end]
[if winix_function_param_is "postredirect"] [if winix_function_param_is "postredirect"]

View File

@ -119,6 +119,8 @@
<label for="winix_rebus_id">{rebus_how_is_it} [rebus_question]?</p> <label for="winix_rebus_id">{rebus_how_is_it} [rebus_question]?</p>
<input id="winix_rebus_id" type="text" name="rebus"> <input id="winix_rebus_id" type="text" name="rebus">
</div> </div>
[include "antispam.html"]
[end] [end]

View File

@ -28,6 +28,8 @@
<label for="winix_rebus_id">{rebus_how_is_it} [rebus_question]?</label> <label for="winix_rebus_id">{rebus_how_is_it} [rebus_question]?</label>
<input id="winix_rebus_id" type="text" name="rebus"> <input id="winix_rebus_id" type="text" name="rebus">
</div> </div>
[include "antispam.html"]
[end] [end]
[if winix_function_param_is "postredirect"] [if winix_function_param_is "postredirect"]

View File

@ -48,6 +48,8 @@
<p class="withnext">{rebus_how_is_it} [rebus_question]?</p> <p class="withnext">{rebus_how_is_it} [rebus_question]?</p>
<input class="edit" type="text" name="rebus"> <input class="edit" type="text" name="rebus">
[include "antispam.html"]
[end] [end]
[if winix_function_param_is "postredirect"] [if winix_function_param_is "postredirect"]

View File

@ -47,6 +47,8 @@
<label for="">{rebus_how_is_it} [rebus_question]?</p> <label for="">{rebus_how_is_it} [rebus_question]?</p>
<input type="text" name="rebus"> <input type="text" name="rebus">
</div> </div>
[include "antispam.html"]
[end] [end]
[if winix_function_param_is "postredirect"] [if winix_function_param_is "postredirect"]

View File

@ -39,6 +39,8 @@
<p class="withnext">{rebus_how_is_it} [rebus_question]?</p> <p class="withnext">{rebus_how_is_it} [rebus_question]?</p>
<input class="edit" type="text" name="rebus"> <input class="edit" type="text" name="rebus">
[include "antispam.html"]
[end] [end]
[if winix_function_param_is "postredirect"] [if winix_function_param_is "postredirect"]

View File

@ -41,6 +41,8 @@
<p class="withnext">{rebus_how_is_it} [rebus_question]?</p> <p class="withnext">{rebus_how_is_it} [rebus_question]?</p>
<input class="edit" type="text" name="rebus"> <input class="edit" type="text" name="rebus">
[include "antispam.html"]
[end] [end]
[if winix_function_param_is "postredirect"] [if winix_function_param_is "postredirect"]

View File

@ -85,6 +85,94 @@ adduser.o: ../../../winix/winixd/core/sessionidmanager.h
adduser.o: ../../../tito/src/base64.h ../../../tito/src/aes.h adduser.o: ../../../tito/src/base64.h ../../../tito/src/aes.h
adduser.o: ../../../winix/winixd/core/htmlfilter.h adduser.o: ../../../winix/winixd/core/htmlfilter.h
adduser.o: ../../../winix/winixd/core/request.h adduser.o: ../../../winix/winixd/core/request.h
antispam.o: templates.h ../../../ezc/src/ezc.h ../../../ezc/src/generator.h
antispam.o: ../../../ezc/src/blocks.h ../../../ezc/src/item.h
antispam.o: ../../../ezc/src/cache.h ../../../ezc/src/functions.h
antispam.o: ../../../pikotools/utf8/utf8.h ../../../ezc/src/funinfo.h
antispam.o: ../../../ezc/src/objects.h ../../../ezc/src/pattern.h
antispam.o: ../../../ezc/src/outstreams.h ../../../ezc/src/patternparser.h
antispam.o: misc.h localefilter.h locale.h
antispam.o: ../../../pikotools/space/spaceparser.h
antispam.o: ../../../pikotools/space/space.h
antispam.o: ../../../pikotools/textstream/types.h
antispam.o: ../../../pikotools/textstream/textstream.h
antispam.o: ../../../pikotools/space/space.h ../../../pikotools/date/date.h
antispam.o: ../../../pikotools/convert/convert.h
antispam.o: ../../../pikotools/convert/inttostr.h
antispam.o: ../../../pikotools/convert/strtoint.h
antispam.o: ../../../pikotools/convert/text.h
antispam.o: ../../../pikotools/membuffer/membuffer.h
antispam.o: ../../../pikotools/textstream/types.h htmltextstream.h
antispam.o: ../../../winix/winixd/core/textstream.h patterncacher.h
antispam.o: ../../../winix/winixd/core/item.h indexpatterns.h patterns.h
antispam.o: changepatterns.h ../../../winix/winixd/core/config.h
antispam.o: ../../../winix/winixd/core/htmlfilter.h
antispam.o: ../../../winix/winixd/core/cur.h
antispam.o: ../../../winix/winixd/core/request.h
antispam.o: ../../../winix/winixd/core/requesttypes.h
antispam.o: ../../../winix/winixd/core/error.h
antispam.o: ../../../winix/winixd/core/config.h
antispam.o: ../../../winix/winixd/core/textstream.h
antispam.o: ../../../winix/winixd/templates/htmltextstream.h
antispam.o: ../../../pikotools/space/spacetojson.h
antispam.o: ../../../winix/winixd/core/session.h
antispam.o: ../../../winix/winixd/core/user.h
antispam.o: ../../../winix/winixd/core/plugindata.h
antispam.o: ../../../winix/winixd/core/rebus.h
antispam.o: ../../../winix/winixd/core/ipban.h
antispam.o: ../../../winix/winixd/core/mount.h
antispam.o: ../../../winix/winixd/core/system.h
antispam.o: ../../../winix/winixd/core/job.h
antispam.o: ../../../winix/winixd/core/basethread.h
antispam.o: ../../../winix/winixd/core/synchro.h
antispam.o: ../../../winix/winixd/core/dirs.h
antispam.o: ../../../winix/winixd/core/dircontainer.h
antispam.o: ../../../winix/winixd/db/db.h ../../../winix/winixd/db/dbbase.h
antispam.o: ../../../winix/winixd/db/dbconn.h
antispam.o: ../../../winix/winixd/db/dbtextstream.h
antispam.o: ../../../winix/winixd/core/error.h
antispam.o: ../../../winix/winixd/db/dbitemquery.h
antispam.o: ../../../winix/winixd/db/dbitemcolumns.h
antispam.o: ../../../winix/winixd/core/user.h
antispam.o: ../../../winix/winixd/core/group.h
antispam.o: ../../../winix/winixd/core/dircontainer.h
antispam.o: ../../../winix/winixd/core/ugcontainer.h
antispam.o: ../../../winix/winixd/core/log.h
antispam.o: ../../../winix/winixd/core/logmanipulators.h
antispam.o: ../../../winix/winixd/core/slog.h
antispam.o: ../../../winix/winixd/core/cur.h
antispam.o: ../../../winix/winixd/templates/locale.h
antispam.o: ../../../winix/winixd/notify/notify.h
antispam.o: ../../../winix/winixd/notify/notifypool.h
antispam.o: ../../../winix/winixd/templates/patterns.h
antispam.o: ../../../winix/winixd/notify/notifythread.h
antispam.o: ../../../winix/winixd/core/basethread.h
antispam.o: ../../../winix/winixd/notify/templatesnotify.h
antispam.o: ../../../winix/winixd/core/users.h
antispam.o: ../../../winix/winixd/core/ugcontainer.h
antispam.o: ../../../winix/winixd/core/lastcontainer.h
antispam.o: ../../../winix/winixd/core/mounts.h
antispam.o: ../../../winix/winixd/core/mountparser.h
antispam.o: ../../../winix/winixd/core/crypt.h
antispam.o: ../../../winix/winixd/core/run.h
antispam.o: ../../../winix/winixd/core/users.h
antispam.o: ../../../winix/winixd/core/groups.h
antispam.o: ../../../winix/winixd/core/group.h
antispam.o: ../../../winix/winixd/core/loadavg.h
antispam.o: ../../../winix/winixd/core/image.h
antispam.o: ../../../winix/winixd/core/threadmanager.h
antispam.o: ../../../winix/winixd/core/timezones.h
antispam.o: ../../../winix/winixd/core/timezone.h
antispam.o: ../../../winix/winixd/core/sessionmanager.h
antispam.o: ../../../winix/winixd/core/sessioncontainer.h
antispam.o: ../../../winix/winixd/core/ipbancontainer.h
antispam.o: ../../../winix/winixd/core/system.h
antispam.o: ../../../winix/winixd/core/sessionidmanager.h
antispam.o: ../../../tito/src/base64.h ../../../tito/src/aes.h
antispam.o: ../../../winix/winixd/core/htmlfilter.h
antispam.o: ../../../winix/winixd/core/request.h
antispam.o: ../../../winix/winixd/core/misc.h
antispam.o: ../../../winix/winixd/core/winix_const.h
changepatterns.o: changepatterns.h patterns.h locale.h changepatterns.o: changepatterns.h patterns.h locale.h
changepatterns.o: ../../../pikotools/space/spaceparser.h changepatterns.o: ../../../pikotools/space/spaceparser.h
changepatterns.o: ../../../pikotools/space/space.h changepatterns.o: ../../../pikotools/space/space.h

View File

@ -1 +1 @@
o = adduser.o changepatterns.o config.o currentdate.o dir.o doc.o env.o filters.o generic.o htmltextstream.o indexpatterns.o insert.o ipban.o item.o last.o locale.o localefilter.o login.o ls.o man.o misc.o miscspace.o mount.o passwd.o patterncacher.o patterns.o priv.o rebus.o server.o slog.o stat.o sys.o template.o templates.o textextstream.o upload.o uptime.o user.o who.o winix.o o = adduser.o antispam.o changepatterns.o config.o currentdate.o dir.o doc.o env.o filters.o generic.o htmltextstream.o indexpatterns.o insert.o ipban.o item.o last.o locale.o localefilter.o login.o ls.o man.o misc.o miscspace.o mount.o passwd.o patterncacher.o patterns.o priv.o rebus.o server.o slog.o stat.o sys.o template.o templates.o textextstream.o upload.o uptime.o user.o who.o winix.o

View File

@ -0,0 +1,125 @@
/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* Copyright (c) 2018, Tomasz Sowa
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "templates.h"
#include "core/request.h"
#include "core/misc.h"
namespace Winix
{
namespace TemplatesFunctions
{
static const int ANTISPAM_OPERATOR_PLUS = 0;
static const int ANTISPAM_OPERATOR_MINUS = 1;
static int last_operator = 0;
static size_t last_form_id;
void antispam_create_new_form_id_for_this_session(Info & i)
{
if( cur->session->id != 0 )
{
if( cur->session->antispan.size() > config->antispam_list_max_size )
{
log << log2 << "AS: antispam table exceeds size limit, clearing the whole list" << logend;
cur->session->antispan.clear();
}
last_form_id = cur->session->antispan.size();
i.out << last_form_id;
cur->session->antispan[last_form_id] = 0;
}
}
void antispam_loop(Info & i)
{
if( i.res == 0 )
{
last_operator = 0;
}
i.res = i.iter < 10;
}
void antispam_loop_operator(Info & i)
{
last_operator = rand() % 2;
switch( last_operator )
{
case ANTISPAM_OPERATOR_PLUS:
i.out << "+=";
break;
case ANTISPAM_OPERATOR_MINUS:
i.out << "-=";
break;
}
}
void antispam_counter(Info & i)
{
if( !cur->session->antispan.empty() )
{
int val = rand() % 200;
switch( last_operator )
{
case ANTISPAM_OPERATOR_PLUS:
cur->session->antispan[last_form_id] += val;
break;
case ANTISPAM_OPERATOR_MINUS:
cur->session->antispan[last_form_id] -= val;
break;
}
i.out << val;
}
}
} // namespace TemplatesFunctions
} // namespace Winix

View File

@ -208,6 +208,14 @@ void Templates::CreateFunctions()
ezc_functions.Insert("adduser_last_email", adduser_last_email); ezc_functions.Insert("adduser_last_email", adduser_last_email);
/*
antispam
*/
ezc_functions.Insert("antispam_create_new_form_id_for_this_session", antispam_create_new_form_id_for_this_session);
ezc_functions.Insert("antispam_loop", antispam_loop);
ezc_functions.Insert("antispam_loop_operator", antispam_loop_operator);
ezc_functions.Insert("antispam_counter", antispam_counter);
/* /*
config config
*/ */

View File

@ -100,6 +100,15 @@ namespace TemplatesFunctions
void adduser_last_email(Info & i); void adduser_last_email(Info & i);
/*
antispam
*/
void antispam_create_new_form_id_for_this_session(Info & i);
void antispam_loop(Info & i);
void antispam_loop_operator(Info & i);
void antispam_counter(Info & i);
/* /*
config config
*/ */