WordPress.org

Make WordPress Core

Opened 7 weeks ago

Closed 5 weeks ago

#53402 closed feature request (maybelater)

Uniform Hashed User Naming Schema for Cross-Domain Interoperability and Transparency in Aggregate Data

Reported by: anonymized_16965431 Owned by:
Milestone: Priority: normal
Severity: normal Version: 5.8
Component: Privacy Keywords: needs-design-feedback needs-testing
Focuses: privacy Cc:

Description

SHA3.org's Single SignOn plugin was presented at the special session on data provenance to amend NSA's hard problems during the Hot Topics on Science of Security (HoTSoS) symposium.

I'm the developer in search of urgent support in adapting existing, critical Internet infrastructure as part of an immediate patch to confront the unfolding consequences of communications monopolization.

Four hundred fifty-five million WordPress installs exist. One core update providing users with the option to hash a passphrase into the username would effectively transform cyberspace into a liquid platform.

Commentary involving specific improvements to code as well as cogent peripheral considerations are welcome.

ABSTRACT: Open-source publishing platforms lack necessary interoperability to counterbalance the security risks of network centralization. The objective aims to bridge the gap between decentralized installs, mixed data and uniform identity verification across multiple domains.

FOSTA-SESTA compliance, the policy debate over 47 U.S.C. § 230, and legal challenges to existing immunities demand urgent solutions to user content accountability and transferability ere massive platform seizure or collapse.

Existing solutions buckle under P.I.I. vulnerabilities in open-source software operated at every level of business and government.

Incorporating an optional hashed passphrase into the username with future software updates could resolve these immediate challenges.

We can restore a sense of user agency and digital trust by distilling the solution space into domain interoperability facilitated by hashed user signatures to provide transparency and privacy within aggregate data.

For additional background on the project, you can see that at https://www.sha3.org.

Components of this plugin have been modified and sourced from the following Questions: Pre-login and pre-registration actions[1], Invalid username special charachters issue[2], Add action that returns modified value[3].

Figure 1: Vector Poster of Secure Single SignOn.
https://i.stack.imgur.com/pAsAE.png

sha3-secure-signon.php

<?php
/*
Plugin Name: SHA3 Secure SignOn
Plugin URI: https://www.sha3.org/
Description: Updates native wp-login.php with cross-platform SHA3 and DES Secure SignOn.
Version: 1.0
Author: USWWN
Author URI: https://www.uswwn.com/
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

// Add jquery for placeholder text and radio deselect
add_action('login_enqueue_scripts', 'wpse_login_enqueue_scripts', 10);
function wpse_login_enqueue_scripts()
{
    wp_enqueue_script('sha3.js', plugin_dir_url(__FILE__) . 'js/sha3-secure-signon.js', array(
        'jquery'
    ) , 1.0);
}

add_action('register_form', 'use_des_tripcode_login');

//Allow hash sign on register and disallow !username
function wscu_sanitize_user($username, $raw_username, $strict)
{

    if (isset($_POST['user_login']))
    {

        //if hash selected
        if (($_POST['hash'] == "des_tripcode") || ($_POST['hash'] == "sha3_hash"))
        {
            //sanitize_text_field may limit functionality but necessary for database security
            //not sure if we need to sanitize here or if fine with the next action. also possible sanitize_user( $username, false );
            $username = sanitize_text_field($raw_username);
        }
    }
    return $username;
}
add_filter('sanitize_user', 'wscu_sanitize_user', 10, 3);

//REGISTER
add_action('login_form_register', 'custom_user_login');
function custom_user_login()
{

    // make sure regisration form is submitted
    if ($_SERVER['REQUEST_METHOD'] != 'POST') return;

    // base of user_login
    $ulogin = $_POST['user_login'];

    //For DES Tripcode
    if (isset($_POST['user_login']) && ($_POST['hash'] == "des_tripcode"))
    {
        //if hash sign, capture nickname
        if (strpos($ulogin, '#') !== false)
        {
            $trippassword = explode('#', $ulogin);
            $tripcoded = $trippassword[1];
            $name = $trippassword[0];
            $salt = substr($tripcoded . "H.", 1, 2);
            $salt = preg_replace("[^\.-z]", ".", $salt);
            $salt = strtr($salt, ":;<=>?@[\\]^_`", "ABCDEFGabcdef");
            $tripusername = substr(crypt($tripcoded, $salt) , -10);
            $ulogin = $name . '!' . $tripusername;
            //sanitize_text_field may limit functionality but necessary for database security
            $_POST['user_login'] = sanitize_text_field($ulogin);
        }elseif
         (strpos($ulogin, '#') !== true)
        {
            $tripcoded = $ulogin;
            $salt = substr($tripcoded . "H.", 1, 2);
            $salt = preg_replace("[^\.-z]", ".", $salt);
            $salt = strtr($salt, ":;<=>?@[\\]^_`", "ABCDEFGabcdef");
            $tripusername = substr(crypt($tripcoded, $salt) , -10);
            $ulogin = '!' . $tripusername;
            $_POST['user_login'] = sanitize_text_field($ulogin);
        }

    }
    //For SHA3 hash
    if (isset($_POST['user_login']) && ($_POST['hash'] == "sha3_hash"))
    {
        $ulogin = hash('sha3-224', $ulogin);
        $ulogin = '!!' . $ulogin;
        $_POST['user_login'] = sanitize_text_field($ulogin);
    }

}

//adds DES option on login and register
add_action('login_form', 'use_des_tripcode_login');
function use_des_tripcode_login()
{

    echo '<p><input type="radio" name="hash" class="no_option" value="des_tripcode"><label for="des_tripcode">&nbsp;DES Tripcode</label></p>';
    echo '<p><input type="radio" name="hash" class="no_option" value="sha3_hash"><label for="sha3_hash">&nbsp;SHA3 Hash</label></p>';
    echo '<input type="radio" name="hash" class="no_option" value="null" style="display:none">';

}
//LOGIN
remove_action('authenticate', 'wp_authenticate_username_password', 20);
add_filter('authenticate', 'des_tripcode_login', 10, 3);
function des_tripcode_login($user, $username, $password)
{

    if (isset($_POST['hash']) && ($_POST['hash'] == "des_tripcode"))
    {
        //pound sign
        if (strpos($username, '#') !== false)
        {
            $trippassword = explode('#', $username);
            $tripcoded = $trippassword[1];
            $name = $trippassword[0];
            $salt = substr($tripcoded . "H.", 1, 2);
            $salt = preg_replace("[^\.-z]", ".", $salt);
            $salt = strtr($salt, ":;<=>?@[\\]^_`", "ABCDEFGabcdef");
            $tripusername = substr(crypt($tripcoded, $salt) , -10);
            $username = $name . '!' . $tripusername;;
            $username = sanitize_text_field($username);
        }
        //no pound sign
        elseif (strpos($username, '#') !== true)
        {
            $tripcoded = $username;
            $salt = substr($tripcoded . "H.", 1, 2);
            $salt = preg_replace("[^\.-z]", ".", $salt);
            $salt = strtr($salt, ":;<=>?@[\\]^_`", "ABCDEFGabcdef");
            $tripusername = substr(crypt($tripcoded, $salt) , -10);
            $username = '!' . $tripusername;
            $username = sanitize_text_field($username);

        }

    }

    //For SHA3 hash
    if (isset($_POST['hash']) && $_POST['hash'] == "sha3_hash")
    {
        $username = hash('sha3-224', $username);
        $username = '!!' . $username;
        $username = sanitize_text_field($username);
    }

    if (is_a($user, 'WP_User'))
    {
        return $user;
    }

    if (empty($username) || empty($password))
    {
        $error = new WP_Error();

        if (empty($username)) $error->add('empty_username', __('<strong>ERROR</strong>: The username field is empty.'));

        if (empty($password)) $error->add('empty_password', __('<strong>ERROR</strong>: The password field is empty.'));

        return $error;
    }

    $user = get_user_by('login', $username);

    if (!$user) return new WP_Error('invalid_username', sprintf(__('<strong>ERROR</strong>: Invalid username. <a href="%s" title="Password Lost and Found">Lost your password</a>?') , wp_lostpassword_url()));

    if (is_multisite())
    {
        // Is user marked as spam?
        if (1 == $user->spam) return new WP_Error('spammer_account', __('<strong>ERROR</strong>: Your account has been marked as a spammer.'));

        // Is a user's blog marked as spam?
        if (!is_super_admin($user->ID) && isset($user->primary_blog))
        {
            $details = get_blog_details($user->primary_blog);
            if (is_object($details) && $details->spam == 1) return new WP_Error('blog_suspended', __('Site Suspended.'));
        }
    }

    $user = apply_filters('wp_authenticate_user', $user, $password);
    if (is_wp_error($user)) return $user;

    if (!wp_check_password($password, $user->user_pass, $user->ID)) return new WP_Error('incorrect_password', sprintf(__('<strong>ERROR</strong>: The password you entered for the username <strong>%1$s</strong> is incorrect. <a href="%2$s" title="Password Lost and Found">Lost your password</a>?') , $username, wp_lostpassword_url()));

    return $user;
}

//Reserve exclamations to identify hash - nicknames
add_filter('pre_user_display_name', 'my_displayname_block');

function my_displayname_block($user_display_name)
{

    $current_user = wp_get_current_user();
	
	//buddypress optional name filter for exclamation
	//if (strpos($_POST['field_1'], "!") !== false)
    //    {
    //        wp_die(sprintf(__('<strong>ERROR</strong>: Exclamation points are reserved to identify SHA3 and DES hashes.&nbsp;<a href="%2$s" title="Go Back">Go back to profile</a>.') , $username, wp_get_referer()));
    //    }
	
	$current_usernick = $current_user->nickname;

    if (strpos($_POST['nickname'], "!") !== false && ($_POST['nickname'] != $current_usernick))
    {
        wp_die(sprintf(__('<strong>ERROR</strong>: Exclamation points are reserved to identify SHA3 and DES hashes.&nbsp;<a href="%2$s" title="Go Back">Go back to profile</a>.') , $username, wp_get_referer()));
    }
    return $user_display_name;

}

//Reserve exclamations to identify hash - first/last names
add_filter('insert_user_meta', function ($meta, $user, $update)
{

    if ($update)
    {
		
        if (strpos($_POST['first_name'], "!") !== false)
        {
            wp_die(sprintf(__('<strong>ERROR</strong>: Exclamation points are reserved to identify SHA3 and DES hashes.&nbsp;<a href="%2$s" title="Go Back">Go back to profile</a>.') , $username, wp_get_referer()));
        }
        if (strpos($_POST['last_name'], "!") !== false)
        {
            wp_die(sprintf(__('<strong>ERROR</strong>: Exclamation points are reserved to identify SHA3 and DES hashes.&nbsp;<a href="%2$s" title="Go Back">Go back to profile</a>.') , $username, wp_get_referer()));
        }

    }

    return $meta;
}
, 10, 3);

//edit login text
add_filter('gettext', 'sha3_text');
add_filter('ngettext', 'sha3_text');
function sha3_text($translated)
{
    $translated = str_ireplace('Username', 'Secure SignOn', $translated);
    return $translated;
}

//add usage info to footer
add_action('login_footer', 'sha3_footer');

function sha3_footer()
{
    echo '<div id="login"><p id="nav">For Secure SignOn usage, visit <a href="https://www.sha3.org">sha3.org</a>.</p></div>';
}

//disable registration bp
function my_disable_bp_registration() {
  remove_action( 'bp_init',    'bp_core_wpsignup_redirect' );
  remove_action( 'bp_screens', 'bp_core_screen_signup' );
}
add_action( 'bp_loaded', 'my_disable_bp_registration' );

add_filter( 'bp_get_signup_page', "firmasite_redirect_bp_signup_page");
    function firmasite_redirect_bp_signup_page($page ){
        return bp_get_root_domain() . '/wp-login.php?action=register'; 
    }

//disallow editing of bp name field since
function bpfr_hide_profile_field_group( $retval ) {
	if ( bp_is_active( 'xprofile' ) ) :	
	
	// hide profile group/field to all except admin	
	if ( !is_super_admin() ) {		
		//exlude fields, separated by comma
		$retval['exclude_fields'] = '1';  
		//exlude groups, separated by comma
		$retval['exclude_groups'] = '1'; 			
	} 
	return $retval;		
	
	endif;
}
add_filter( 'bp_after_has_profile_parse_args', 'bpfr_hide_profile_field_group' );
sha3-secure-signon.js

/**
 * Custom js file.
 */
jQuery(document).ready(function() {
    jQuery('#user_login').attr('placeholder', 'User#Passphrase');
    jQuery('#user_email').attr('placeholder', 'User Email');
    jQuery('#user_pass').attr('placeholder', 'Site Password');

    var checked_val = "null";
    jQuery(".no_option").on("click", function() {
        if (jQuery(this).val() == checked_val) {
            jQuery('input[name=hash][value=null]').prop("checked", true);
            checked_val = "null";
        } else {
            checked_val = jQuery(this).val();
            jQuery('input[name=hash][value=null]').propRemove("checked");
        }
    });


});



[1]: https://wordpress.stackexchange.com/questions/138951/what-hooks-should-i-use-for-pre-login-and-pre-registration-actions
[2]: https://wordpress.stackexchange.com/questions/189121/wordpress-4-invalid-username-special-charachters-issue
[3]: https://wordpress.stackexchange.com/questions/119273/add-action-which-returns-modified-value

Attachments (2)

pAsAE.png (315.1 KB) - added by anonymized_16965431 7 weeks ago.
Figure 1: Vector Poster of Secure Single SignOn.
uVYFSl9.png (54.5 KB) - added by anonymized_16965431 5 weeks ago.

Download all attachments as: .zip

Change History (13)

@anonymized_16965431
7 weeks ago

Figure 1: Vector Poster of Secure Single SignOn.

This ticket was mentioned in Slack in #accessibility by ryokuhi. View the logs.


7 weeks ago

#2 @ryokuhi
7 weeks ago

  • Focuses accessibility removed

Hello @411c3, and welcome on WordPress Trac!
We reviewed this issue today during the Accessibility Team's weekly bug-scrub.
I don't think that the issue you are reporting is an accessibility issue (that is, a problem that impacts in particular users with a disability), so I'm removing the related focus.

#3 follow-ups: @johnbillion
7 weeks ago

  • Focuses coding-standards removed
  • Milestone Awaiting Review deleted
  • Resolution set to maybelater
  • Severity changed from blocker to normal
  • Status changed from new to closed

@411c3 It's not clear what is being proposed here or what problem it solves. This sounds like something at the initial idea stage which needs a lot more work before it can be considered for inclusion in other software. As an example, what happens when the user forgets or changes their pass phrase?

It would be a good idea to release this as a plugin first to gauge interest.

#4 in reply to: ↑ 3 @anonymized_16965431
6 weeks ago

  • Resolution maybelater deleted
  • Status changed from closed to reopened

Replying to johnbillion:

@411c3 It's not clear what is being proposed here or what problem it solves. This sounds like something at the initial idea stage which needs a lot more work before it can be considered for inclusion in other software. As an example, what happens when the user forgets or changes their pass phrase?

It would be a good idea to release this as a plugin first to gauge interest.

Hi John, this solves both identity theft AND more immediately, cyber centralization and impending network collapse — which WordPress, by design, is a natural response to. WordPress gets the job done, except for the inability to seamlessly and safely pollinate user identity crossdomain (ie, identifying users from one site to another). Gravatar functioned towards solving this issue, but poses serious security risks by revealing PII, which have been well-documented (and yet it's shockingly still used at every level of business and government).

The method proposed here is already wrapped into a plugin but can be added as an option into core, similar to Gravatar, only much safer than Gravatar. The question of forgetting the passphrase evinces a misunderstanding of the function of the hashed passphrase. This naming schema is widely used in other open source software to sign posts. As incorporated here, into Wordpress, the hashed passphrase functions as a converted username. If you forget your username, then what? You can use your email. Or, you can click forget password, and your username is sent to your email, same as here. And, as WordPress currently operates, we already can not change our usernames out of the box. Nothing changes there.

Please reconsider. It appears this ticket was given a cursory glance without any serious consideration. Thanks.

Last edited 6 weeks ago by anonymized_16965431 (previous) (diff)

#5 in reply to: ↑ 3 @anonymized_16965431
6 weeks ago

Replying to johnbillion:

@411c3 It's not clear what is being proposed here or what problem it solves. This sounds like something at the initial idea stage which needs a lot more work before it can be considered for inclusion in other software. As an example, what happens when the user forgets or changes their pass phrase?

It would be a good idea to release this as a plugin first to gauge interest.

If you forget your passphrase, use your email to login instead or your hashed username can be sent to your email by clicking forgot password, and you can log in using the hashed username. You can see it in action here: https://www.sha3.org/wp-login.php?action=register

"For additional background on the project, you can see that at https://www.sha3.org."

https://i.imgur.com/uVYFSl9.png

Last edited 6 weeks ago by anonymized_16965431 (previous) (diff)

This ticket was mentioned in Slack in #core by 411c3. View the logs.


5 weeks ago

This ticket was mentioned in Slack in #core by 411c3. View the logs.


5 weeks ago

#9 @Clorith
5 weeks ago

I've got some concerns with this proposal, most notably the over-engineering of the login screen, which feels incredibly confusing judging by the proposal screenshots, and I'm a fairly technical user, imagine how this would look to the average user, which is the vast majority of WordPress' userbase?

This would make it go against one of the core (https://wordpress.org/about/philosophy/ philosophies of WordPress), "Decisions, not options".

I'm also not sure how single-signon would benefit a majority of users, most WordPress sites are not going to be sites encouraging registrations from interested parties, but are standalone sites or services.

I also do not believe a comparison to Gravatar is appropriate, that being a user avatar service for re-using avatars on multiple sites, if you so wish, but is not intended for user identification or verification.

In light of these things, I'd say this feels rather niche, and probably fits much better in as a standalone plugin, but am more than happy to hear your thoughts on the above remarks, and maybe some more details on what sort of problem this solves for the average WordPress user.

#10 @desrosj
5 weeks ago

  • Resolution set to maybelater
  • Status changed from reopened to closed

It looks like the original reporting user has deactivated and anonymized their account. Without someone to have a dialogue with, this will not be able to move forward.

Though I agree with the assessment above that a standalone plugin is probably best to build out this feature, and if demand can be demonstrated there, it can be considered for Core.

#11 @helloworld3
5 weeks ago

  • Resolution maybelater deleted
  • Status changed from closed to reopened

@desrosj The project was anonymized because I did not anticipate this level of creative hostility to the idea. For example, @Clorith points to the interface design as revealing a "technical choice," violating core philosophy. It's not a "technical choice." It's a big decision. It's the decision to use a persistent Internet identity across multiple platforms.

The UX/UI could definitely be improved to reach a wider audience. The design reflects its current real world usage with other software, but is perhaps too technical to be grasped by this demographic, developers included.

@Clorith No, most sites are not standalone. Most users have multiple points of web presence and a sprawling digital footprint across multiple platforms, including social media. WordPress users are no different. A uniform hashed username would be one way to confirm the validity of transactions between platforms.

Further, the idea that an email-hashed avatar has no relationship to user identity whatsoever, is... interesting.

Last edited 5 weeks ago by helloworld3 (previous) (diff)

#12 @jorbin
5 weeks ago

  • Resolution set to maybelater
  • Status changed from reopened to closed

Discussion is always welcome to continue and the goal of maybelater as a resolution status is to make it clear that this requested new feature isn't a priority in the near term. There is no need to reopen the ticket in order to comment and attempt to pursued others.

If you would like to increase the buy-in, the best way to do so is to demonstrate the value. Releasing a plugin on https://wordpress.org/plugins/ and showing that this is a feature that many users want will show me and other maintainers that this is something should consider with a higher priority.

Note: See TracTickets for help on using tickets.