summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2014-08-29 09:43:00 +0200
committerYorhel <git@yorhel.nl>2014-08-29 09:45:15 +0200
commitc27d4e6b509a655d81e36469bb881afc287596e8 (patch)
treec7a42b5226edaab2e3356592130a6db7caa13a9e
parent9475bf8ccf1b422402ab70b6cb2276dc3c61e5c6 (diff)
Strengthen formcode for non-logged-in visitors + CSRF protect login form
formcode is strengthened by including the IP (-prefix) into the hash, ensuring that the code can't be obtained by someone on a different network. I also removed the login form of every page. Felt kinda pointless.
-rw-r--r--data/lang.txt57
-rw-r--r--lib/VNDB/Handler/Users.pm1
-rw-r--r--lib/VNDB/Util/Auth.pm2
-rw-r--r--lib/VNDB/Util/LayoutHTML.pm18
-rw-r--r--lib/VNDB/Util/Misc.pm22
5 files changed, 62 insertions, 38 deletions
diff --git a/data/lang.txt b/data/lang.txt
index aa5d8971..ea3b3a30 100644
--- a/data/lang.txt
+++ b/data/lang.txt
@@ -3260,7 +3260,18 @@ tr : Çıkış
uk : Вийти
it : Esci
-# used for both the box title and submit button
+:_menu_user
+en : User menu
+ru*:
+cs*:
+hu*:
+nl : Gebruikersmenu
+de*:
+es*:
+tr*:
+uk*:
+it*:
+
:_menu_login
en : Login
ru : Вход
@@ -3273,27 +3284,29 @@ tr : Giriş
uk : Увійти
it : Accedi
-:_menu_loginmsg
-en : Need to [url,_1,register],[br]
- or [url,_2,forgot your password]?
-ru : Нужна [url,_1,регистрация],[br]
- или [url,_2,забыли свой пароль]?
-cs : Potřebujete se [url,_1,přihlásit],[br]
- nebo jste [url,_2,zapomněli heslo]?
-hu : Ha még nem [url,_1,regisztráltál], akkor most megteheted,[br]
- vagy netán [url,_2,elfelejtetted a jelszavad]?
-nl : Nog geen [url,_1,account],[br]
- of [url,_2,wachtwoord vergeten]?
-de : Noch [url,_1,kein Benutzerkonto],[br]
- oder [url,_2,das Passwort vergessen]?
-es : Necesitas [url,_1,registrarte],[br]
- o ¿[url,_2,has olvidado tu contraseña]?
-tr : [url,_1,Kayıt] olmak mı istemiştiniz?[br]
- [url,_2,Şifrenizi] mi unuttunuz?
-uk : Тобі потрібна [url,_1,реєстрація],[br]
- чи [url,_2,ти забув пароль]?
-it : Hai bisogno di [url,_1,registrarti],[br]
- o [url,_2,hai dimenticato la tua password]?
+:_menu_newpass
+en : Password reset
+ru*:
+cs*:
+hu*:
+nl : Wachtwoord vergeten
+de*:
+es*:
+tr*:
+uk*:
+it*:
+
+:_menu_register
+en : Register
+ru*:
+cs*:
+hu*:
+nl : Registreren
+de*:
+es*:
+tr*:
+uk*:
+it*:
# database statistics
diff --git a/lib/VNDB/Handler/Users.pm b/lib/VNDB/Handler/Users.pm
index 5738d964..eb7e03ab 100644
--- a/lib/VNDB/Handler/Users.pm
+++ b/lib/VNDB/Handler/Users.pm
@@ -142,6 +142,7 @@ sub login {
my $frm;
if($self->reqMethod eq 'POST') {
+ return if !$self->authCheckCode;
$frm = $self->formValidate(
{ post => 'usrname', required => 1, minlength => 2, maxlength => 15 },
{ post => 'usrpass', required => 1, minlength => 4, maxlength => 64, template => 'asciiprint' },
diff --git a/lib/VNDB/Util/Auth.pm b/lib/VNDB/Util/Auth.pm
index c7e8b973..a1fa9b4d 100644
--- a/lib/VNDB/Util/Auth.pm
+++ b/lib/VNDB/Util/Auth.pm
@@ -165,7 +165,7 @@ sub authGetCode {
my $self = shift;
my $id = shift;
my $time = (shift || time)/3600; # accuracy of an hour
- my $uid = pack('N', $self->{_auth} ? $self->{_auth}{id} : 0);
+ my $uid = encode_utf8($self->{_auth} ? $self->{_auth}{id} : $self->normIP());
return lc substr sha1_hex($self->{form_salt} . $uid . encode_utf8($id||'') . pack('N', int $time)), 0, 16;
}
diff --git a/lib/VNDB/Util/LayoutHTML.pm b/lib/VNDB/Util/LayoutHTML.pm
index 7507d682..6471e8b1 100644
--- a/lib/VNDB/Util/LayoutHTML.pm
+++ b/lib/VNDB/Util/LayoutHTML.pm
@@ -110,21 +110,11 @@ sub _menu {
a href => "$uid/logout", mt '_menu_logout';
end;
} else {
- h2;
- a href => '/u/login', mt '_menu_login';
- end;
+ h2 mt '_menu_user';
div;
- form action => '/nospam?/u/login', id => 'loginform', method => 'post';
- fieldset;
- legend 'Login';
- input type => 'text', class => 'text', id => 'username', name => 'usrname';
- input type => 'password', class => 'text', id => 'userpass', name => 'usrpass';
- input type => 'submit', class => 'submit', value => mt '_menu_login';
- end;
- end;
- p;
- lit mt '_menu_loginmsg', '/u/register', '/u/newpass';
- end;
+ a href => '/u/login', mt '_menu_login'; br;
+ a href => '/u/newpass', mt '_menu_newpass'; br;
+ a href => '/u/register', mt '_menu_register'; br;
end;
}
end 'div'; # /menubox
diff --git a/lib/VNDB/Util/Misc.pm b/lib/VNDB/Util/Misc.pm
index 04114483..7ee0701b 100644
--- a/lib/VNDB/Util/Misc.pm
+++ b/lib/VNDB/Util/Misc.pm
@@ -6,8 +6,9 @@ use warnings;
use Exporter 'import';
use TUWF ':html';
use VNDB::Func;
+use Socket 'inet_pton', 'inet_ntop', 'AF_INET6';
-our @EXPORT = qw|filFetchDB ieCheck|;
+our @EXPORT = qw|filFetchDB ieCheck normIP|;
my %filfields = (
@@ -143,5 +144,24 @@ sub ieCheck {
}
+# Normalized IP address to use for duplicate detection/throttling. For IPv4
+# this is just the normal address, but for IPv6 this is the /48 subnet, with
+# the rest of the address zero'd.
+sub normIP {
+ my $s = shift;
+ my $ip = $s->reqIP();
+ return $ip if $ip !~ /:/;
+
+ # There's a whole bunch of IPv6 manipulation modules on CPAN, but many seem
+ # quite bloated and still don't offer the functionality to return an IP
+ # with its mask applied (admittedly not a common operation). The libc
+ # socket functions will do fine in parsing and formatting IPv6 addresses,
+ # and the actual masking is quite trivial in binary form.
+ $ip = inet_pton AF_INET6, $ip;
+ return '::' if !$ip;
+ $ip =~ s/^(.{6}).+$/$1 . "\0"x10/e;
+ return inet_ntop AF_INET6, $ip;
+}
+
1;