summaryrefslogtreecommitdiff
path: root/fs_selfservice
diff options
context:
space:
mode:
authorJonathan Prykop <jonathan@freeside.biz>2015-12-02 05:02:17 -0600
committerJonathan Prykop <jonathan@freeside.biz>2015-12-14 20:22:09 -0600
commit8cd6e05d5d906da6b001b36bab5aa87ecdfca944 (patch)
tree4ad1a33fa011bc8a5b84bea69b9afebb6bd5d110 /fs_selfservice
parent4ff9a50fe7f35179314967d71ae66b696ab006c5 (diff)
RT#29354: Password Security in Email [xmlhttp validation for selfservice]
Diffstat (limited to 'fs_selfservice')
-rw-r--r--fs_selfservice/FS-SelfService/SelfService.pm1
-rw-r--r--fs_selfservice/FS-SelfService/cgi/add_password_validation.html36
-rw-r--r--fs_selfservice/FS-SelfService/cgi/change_password.html12
-rwxr-xr-xfs_selfservice/FS-SelfService/cgi/selfservice.cgi11
-rw-r--r--fs_selfservice/FS-SelfService/cgi/send_xmlhttp.html45
-rwxr-xr-xfs_selfservice/FS-SelfService/cgi/signup.cgi28
-rwxr-xr-xfs_selfservice/FS-SelfService/cgi/signup.html14
-rw-r--r--fs_selfservice/FS-SelfService/cgi/validate_password.html9
8 files changed, 151 insertions, 5 deletions
diff --git a/fs_selfservice/FS-SelfService/SelfService.pm b/fs_selfservice/FS-SelfService/SelfService.pm
index f4b47b2..4023aa8 100644
--- a/fs_selfservice/FS-SelfService/SelfService.pm
+++ b/fs_selfservice/FS-SelfService/SelfService.pm
@@ -99,6 +99,7 @@ $socket .= '.'.$tag if defined $tag && length($tag);
'reset_passwd' => 'MyAccount/reset_passwd',
'check_reset_passwd' => 'MyAccount/check_reset_passwd',
'process_reset_passwd' => 'MyAccount/process_reset_passwd',
+ 'validate_passwd' => 'MyAccount/validate_passwd',
'list_tickets' => 'MyAccount/list_tickets',
'create_ticket' => 'MyAccount/create_ticket',
'get_ticket' => 'MyAccount/get_ticket',
diff --git a/fs_selfservice/FS-SelfService/cgi/add_password_validation.html b/fs_selfservice/FS-SelfService/cgi/add_password_validation.html
new file mode 100644
index 0000000..e349fd7
--- /dev/null
+++ b/fs_selfservice/FS-SelfService/cgi/add_password_validation.html
@@ -0,0 +1,36 @@
+<SCRIPT>
+function add_password_validation (fieldid) {
+ var inputfield = document.getElementById(fieldid);
+ inputfield.onchange = function () {
+ var fieldid = this.id+'_result';
+ var resultfield = document.getElementById(fieldid);
+ var svcnum = '';
+ var svcfield = document.getElementById(this.id+'_svcnum');
+ if (svcfield) {
+ svcnum = svcfield.options[svcfield.selectedIndex].value;
+ }
+ if (this.value) {
+ resultfield.innerHTML = '<SPAN STYLE="color: blue;">Validating password...</SPAN>';
+ send_xmlhttp('selfservice.cgi',
+ ['action','validate_password','fieldid',fieldid,'svcnum',svcnum,'check_password',this.value],
+ function (result) {
+ result = JSON.parse(result);
+ var resultfield = document.getElementById(result.fieldid);
+ if (resultfield) {
+ if (result.valid) {
+ resultfield.innerHTML = '<SPAN STYLE="color: green;">Password valid!</SPAN>';
+ } else if (result.error) {
+ resultfield.innerHTML = '<SPAN STYLE="color: red;">'+result.error+'</SPAN>';
+ } else {
+ result.syserror = result.syserror || 'Server error';
+ resultfield.innerHTML = '<SPAN STYLE="color: red;">'+result.syserror+'</SPAN>';
+ }
+ }
+ }
+ );
+ } else {
+ resultfield.innerHTML = '';
+ }
+ };
+}
+</SCRIPT>
diff --git a/fs_selfservice/FS-SelfService/cgi/change_password.html b/fs_selfservice/FS-SelfService/cgi/change_password.html
index 22d8973..ef66554 100644
--- a/fs_selfservice/FS-SelfService/cgi/change_password.html
+++ b/fs_selfservice/FS-SelfService/cgi/change_password.html
@@ -12,7 +12,7 @@
<TR>
<TH ALIGN="right">Change password for account: </TH>
<TD>
- <SELECT NAME="svcnum">
+ <SELECT ID="new_password_svcnum" NAME="svcnum">
<%= foreach my $svc ( @svcs ) {
$OUT .= '<OPTION VALUE="'. $svc->{'svcnum'}. '"'.
( $svc->{'svcnum'} eq $svcnum ? ' SELECTED' : '' ). '>'.
@@ -25,7 +25,15 @@
<TR>
<TH ALIGN="right">New password: </TH>
- <TD><INPUT TYPE="password" NAME="new_password" SIZE="18"></TD>
+ <TD>
+ <INPUT ID="new_password" TYPE="password" NAME="new_password" SIZE="18">
+ <DIV ID="new_password_result"></DIV>
+<%= include('send_xmlhttp') %>
+<%= include('add_password_validation') %>
+<SCRIPT>
+add_password_validation('new_password');
+</SCRIPT>
+ </TD>
</TR>
<TR>
diff --git a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi
index b2ebaef..5845122 100755
--- a/fs_selfservice/FS-SelfService/cgi/selfservice.cgi
+++ b/fs_selfservice/FS-SelfService/cgi/selfservice.cgi
@@ -23,6 +23,7 @@ use FS::SelfService qw(
mason_comp port_graph
start_thirdparty finish_thirdparty
reset_passwd check_reset_passwd process_reset_passwd
+ validate_passwd
billing_history
);
@@ -85,6 +86,7 @@ my @actions = ( qw(
process_suspend_pkg
switch_cust
history
+ validate_password
));
my @nologin_actions = (qw(
@@ -109,7 +111,6 @@ if ( $cgi->param('action') =~ /^process_forgot_password_session_(\w+)$/ ) {
warn "WARNING: unrecognized action '$1'\n";
}
}
-
unless ( $nologin_actions{$action} ) {
my %cookies = CGI::Cookie->fetch;
@@ -1123,6 +1124,14 @@ sub do_process_forgot_password {
);
}
+sub validate_password {
+ validate_passwd(
+ 'session_id' => $session_id,
+ map { $_ => scalar($cgi->param($_)) }
+ qw( fieldid svcnum check_password )
+ )
+}
+
#--
sub do_template {
diff --git a/fs_selfservice/FS-SelfService/cgi/send_xmlhttp.html b/fs_selfservice/FS-SelfService/cgi/send_xmlhttp.html
new file mode 100644
index 0000000..ac85cb2
--- /dev/null
+++ b/fs_selfservice/FS-SelfService/cgi/send_xmlhttp.html
@@ -0,0 +1,45 @@
+<SCRIPT>
+function rs_init_object () {
+ var A;
+ try {
+ A=new ActiveXObject("Msxml2.XMLHTTP");
+ } catch (e) {
+ try {
+ A=new ActiveXObject("Microsoft.XMLHTTP");
+ } catch (oc) {
+ A=null;
+ }
+ }
+ if(!A && typeof XMLHttpRequest != "undefined")
+ A = new XMLHttpRequest();
+ if (!A)
+ alert("Can't create XMLHttpRequest object");
+ return A;
+}
+
+function send_xmlhttp (url,args,callback) {
+ args = args || [];
+ callback = callback || function (data) { return data };
+ var content = '';
+ for (var i = 0; i < args.length; i = i + 2) {
+ content = content + "&" + args[i] + "=" + escape(args[i+1]);
+ }
+ content = content.replace( /[+]/g, '%2B'); // fix unescaped plus signs
+
+ var xmlhttp = rs_init_object();
+ xmlhttp.open("POST", url, true);
+
+ xmlhttp.onreadystatechange = function() {
+ if (xmlhttp.readyState != 4)
+ return;
+ if (xmlhttp.status == 200) {
+ var data = xmlhttp.responseText;
+ callback(data);
+ }
+ };
+
+ xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ xmlhttp.send(content);
+}
+</SCRIPT>
+
diff --git a/fs_selfservice/FS-SelfService/cgi/signup.cgi b/fs_selfservice/FS-SelfService/cgi/signup.cgi
index 817fdd3..072ce96 100755
--- a/fs_selfservice/FS-SelfService/cgi/signup.cgi
+++ b/fs_selfservice/FS-SelfService/cgi/signup.cgi
@@ -508,3 +508,31 @@ use FS::SelfService qw( regionselector expselect popselector domainselector
didselector
);
+sub add_password_validation {
+ my $fieldid = shift;
+ my $out = '';
+ if ((-e './send_xmlhttp.html') && (-e './add_password_validation.html')) {
+ my $template = new Text::Template( TYPE => 'FILE',
+ SOURCE => "./send_xmlhttp.html",
+ DELIMITERS => [ '<%=', '%>' ],
+ UNTAINT => 1,
+ )
+ or die $Text::Template::ERROR;
+ $out .= $template->fill_in( PACKAGE => 'FS::SelfService::_signupcgi' );
+ $template = new Text::Template( TYPE => 'FILE',
+ SOURCE => "./add_password_validation.html",
+ DELIMITERS => [ '<%=', '%>' ],
+ UNTAINT => 1,
+ )
+ or die $Text::Template::ERROR;
+ $out .= $template->fill_in( PACKAGE => 'FS::SelfService::_signupcgi' );
+ $out .= <<ENDOUT;
+<SCRIPT>
+add_password_validation('$fieldid');
+</SCRIPT>
+ENDOUT
+ }
+ return $out;
+}
+
+
diff --git a/fs_selfservice/FS-SelfService/cgi/signup.html b/fs_selfservice/FS-SelfService/cgi/signup.html
index 2bc59ca..5900ba6 100755
--- a/fs_selfservice/FS-SelfService/cgi/signup.html
+++ b/fs_selfservice/FS-SelfService/cgi/signup.html
@@ -336,7 +336,8 @@ HTML::Widgets::SelectLayers->new(
<FORM name="signup_form" action="<%= $self_url %>" METHOD="POST" onsubmit="return fixup_form();"><BR><FONT SIZE="+1"><B>First package</B></FONT>
<INPUT TYPE="hidden" NAME="promo_code" VALUE="<%= $promo_code %>">
<INPUT TYPE="hidden" NAME="reg_code" VALUE="<%= $reg_code %>">
-<TABLE BGCOLOR="<%= $box_bgcolor || '#c0c0c0' %>" BORDER=0 CELLSPACING=0 WIDTH="100%">
+<DIV STYLE="background: <%= $box_bgcolor %>; width: 100%">
+<TABLE BGCOLOR="<%= $box_bgcolor || '#c0c0c0' %>" BORDER=0 CELLSPACING=0>
<TR>
<TD COLSPAN=2><SELECT NAME="pkgpart">
@@ -383,7 +384,15 @@ ENDOUT
$OUT .= <<ENDOUT;
<TR>
<TD ALIGN="right">Password</TD>
- <TD><INPUT TYPE="password" NAME="_password" VALUE="$_password"></TD>
+ <TD>
+ <INPUT ID="new_password" TYPE="password" NAME="_password" VALUE="$_password">
+ <DIV ID="new_password_result"></DIV>
+ENDOUT
+
+ $OUT .= add_password_validation('new_password');
+
+ $OUT .= <<ENDOUT;
+ </TD>
</TR>
<TR>
<TD ALIGN="right">Re-enter Password</TD>
@@ -433,6 +442,7 @@ NOMADIX
%>
</TABLE>
+</DIV>
<%=
if ( @optional_packages ) {
diff --git a/fs_selfservice/FS-SelfService/cgi/validate_password.html b/fs_selfservice/FS-SelfService/cgi/validate_password.html
new file mode 100644
index 0000000..5cc3167
--- /dev/null
+++ b/fs_selfservice/FS-SelfService/cgi/validate_password.html
@@ -0,0 +1,9 @@
+<%= use JSON;
+ encode_json({
+ 'valid' => $password_valid ? 1 : 0,
+ 'error' => $password_invalid,
+ 'syserror' => $error,
+ 'fieldid' => $fieldid,
+ 'password_debug' => $password_debug,
+ }); %>
+