#StackBounty: #users #security #front-end #password Force user to change their password on the frontend at the first login and password…

Bounty: 50

I have 3 users roles on my platform with no access to the WordPress backoffice “external_user1” , “external_user2”, “external_user3”.

I need to force every user with one of this roles to change his password at the first login. by the way i use the WordPress login form.

So if the user enter the correct ID and password he is redirected to : wp-login.php?action=lostpassword for reset the password. as you can see on the picture below :
enter image description here

At this time, he enters again the ID and a reset mail is send to the user.

When the user click to the mail link he is redirected to reset page. and when he tries to change the password i need him to type on the keyboard the old one. after that he can access.

And the last one is about password policy :
8 characters with at last 1 uppercase 1 lowercase 1 Number 1 special character

Thanks.


Get this bounty!!!

#StackBounty: #posts #functions #rest-api #security #json Disable REST API for a user ROLE

Bounty: 50

I’m looking for a way to disable Rest API for a user role called ‘external_user’ (disable wp-json queries.)

This user role can see right now alot of posts and pages information with when we put wp-json on the URL (users, pages, posts…)

I use actually the plugin DISABLE REST API but it prevent only not logged users to see json informations. i need to do the same thing with external_user role.

If it’s not possible, can I redirect this user role (and only external_user role) to 404 pages if he try to put an URL with wp-json ?

Thanks.


Get this bounty!!!

#StackBounty: #google-chrome #security #ssl #certificates #privacy List and remove unofficially installed CA certificates

Bounty: 50

This article expose how around 18% of HTTPS connections are being detected as intercepted by MITM proxies. As the great related paper state:

To circumvent this validation, local software injects a self-signed CA certificate into the client browser’s root store at install time.
[…]
Contrary to widespread belief, public key pinning [19]— an HTTPS feature
that allows websites to restrict connections to a specific key— does not prevent this interception. Chrome, Firefox, and Safari only enforce pinned keys when a certificate chain terminates in an authority shipped with the browser or operating system. The extra validation is skipped when the chain terminates in a locally installed root (i.e., a CA certificate installed by an administrator) [34].

Is pretty common on companies, desktop antivirus and malware/adware to add root CA. Sometimes even with honest reasons. But to make the situation more clear: SSL web browsing is exactly as strong as the weakest CA (this includes DNS if DNS-over-HTTPS).


I want to check if my HTTPS traffic is intercepted at least in three aspects (better if just with CLI):

So the real questions are:

  • How to list unofficially installed CA certificates (doesn’t come with Ubuntu/Firefox/Chrome) to avoid MITM attacks/HTTPS interception?
  • How to reset trusted certificates stores to its default?

Some research

  • checkmyhttps seems old and not trustworthy
  • Chrome: I’m not sure if chrome://settings/certificates is a subset of what return some of these commands:
    # System wide (I)
    awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt

    # System wide (II) (`p11-kit` package)
    trust list

    # For Firefox
    certutil -L -d ~/.mozilla/firefox/*.default*/

Reference


Get this bounty!!!

#StackBounty: #networking #security #network-share #network-attached-storage #synology Synology QuickConnect Relay: Not Secure?

Bounty: 100

I was reading the QuickConnect whitepaper and was overall pretty impressed. But on page 10 it explains how the Relay service works and it’s implied (but not explicitly stated) that packets are decrypted on the Relay Server. They go on to pinky swear they won’t snoop your traffic:

While providing the promised services, QuickConnect makes no use of collected data from registered Synology NAS servers except in delivering such services. For more details, please visit the Privacy Terms on our official website.

As most of you probably are, I can be a little paranoid about Security. My previous setup used a tcp proxy server which allowed for E2E encryption to work natively. That was however somewhat brittle and left a public port exposed. It also added latency. Hole Punching is really cool and does seem to create a encrypted tunnel E2E so that sounds perfect for my needs. A few questions:

  1. Is it correct that QuickConnect relay isn’t encrypted E2E?
  2. Can I modify QuickConnect to fallback to my own relay?
  3. Is my assumption correct that Hole Punching is safer than simply forwarding a public port?
  4. Will hole punching work when putting my Synology in my router’s DMZ?
  5. In which conditions will Hole Punching not work?
  6. Does QuickConnect uses UDP or TCP Hole Punching?


Get this bounty!!!

#StackBounty: #javascript #html #security #server-sent-events EventSource / SSE (Server-Sent-Events) – Security

Bounty: 100

I followed This Thread, but I as I have not fully understood the answer in my case, I would like to post again.

I am using EventSource in my Front-End and the Backend is using echo event to stream data relatively to a drone to my application.

var source = new EventSource(`blabla:3000/sse?channel=myProject${projectID}`);
source.addEventListener(`myDrone${droneID}`, function(e){
    console.log('Received an update message:', e.data);
});

In the backend, by default nothing is streaming, and a user on connection will request to the backend to start emitting events. This call is secured using jwt_token. So to make the server start stream, a token is needed.

The question I have is, when a server is already streaming.

Let’s say I am a not connected (so no valid token), and I decided to connect to the SSE stream because I know the channel name and the server is already streaming. If I start a new EventSource on blabla:3000/sse?channel=myProject${projectID}. Would I still be able to see all of the message sent trough this channel? I believe that yes.

How is it possible to secure those event streamed to be only on registered user ?

Ex : (read from top to bottom)

enter image description here

How can I prevent a user that know the channelName to receive all the event stream by the server ?

Since the front end and backend are hosted on the same domain at the moment, but this might change, so I need a broad answer.


Get this bounty!!!

#StackBounty: #mysql #security #pdo Add post to favorite in PDO and mysql

Bounty: 50

After lot of research and couple of questions in https://stackoverflow.com/ i managed to create Favorite System in PDO mysql as database. Am not a developer so there may be security issue or better method with my below code.

config.php

try {
    //create PDO connection 
    $conn = new PDO("mysql:host=" . DBHOST . ";port=3306;dbname=" . DBNAME, DBUSER, DBPASS);
    $conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $conn->exec("SET CHARACTER SET utf8");
} catch (PDOException $e) {
    //show error
    echo '<p class="bg-danger">' . $e->getMessage() . '</p>';
    exit;
}

SQL

DROP TABLE IF EXISTS `allpostdata`;
CREATE TABLE IF NOT EXISTS `allpostdata` (
  `id` int(9) NOT NULL AUTO_INCREMENT,
  `pid` varchar(12) NOT NULL DEFAULT '',
  ....
  ....
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;



DROP TABLE IF EXISTS `members`;
CREATE TABLE IF NOT EXISTS `members` (
  `memberID` int(11) NOT NULL AUTO_INCREMENT,
  `Oauth_pro` varchar(10) DEFAULT NULL,
  `username` varchar(255) NOT NULL,
  ....
  ....

  PRIMARY KEY (`memberID`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


CREATE TABLE `favorite` (
  `memberID` int(9) NOT NULL,
  `id` int(9) NOT NULL,
  PRIMARY KEY (`memberID`,`id`),
  KEY `fk_favorite_post1_idx` (`memberID`),
  CONSTRAINT `fk_favorite_user` FOREIGN KEY (`memberID`) REFERENCES `members` (`memberID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `fk_favorite_post1` FOREIGN KEY (`id`) REFERENCES `allpostdata` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Post page

<?php
$email = 'user@mail.com';
// Query to get the user_id
$stmt = $conn->prepare('SELECT memberID FROM members WHERE email = :email AND active="Yes" ');
$stmt->execute(array(':email' => $email));
$row = $stmt->fetch();
$mbid = $row['memberID'];

$pid = '4';
// Query to Get the Director ID
$stmt = $conn->prepare('SELECT * FROM allpostdata WHERE id =:id');
$stmt->execute(array(':id' => $pid));
$result = $stmt->fetchAll();
foreach ($result as $row) {

    echo "<p>Director: " . $row['tit'] . "</p> ";
    $fav_image = checkFavorite($mbid, $pid, $conn);
    echo "Favorite? : " . $fav_image . "";
}

function checkFavorite($mbid, $pid, $conn) {
    $stmt = $conn->prepare("SELECT * FROM favorite WHERE memberID=:mid AND id=:id");
    $stmt->execute(array(':mid' => $mbid, ':id' => $pid));
    $count = $stmt->rowCount();
    if ($count == 0) {
        echo "<div class = 'button' method = 'Like'  data-user = " . $mbid . " data-post = " . $pid . "> <i class='mi mi_sml' id=" . $pid . ">favorite_border</i>Add Favorite</div>";
    } else {
        echo "<div class = 'button' method = 'Unlike'  data-user = " . $mbid . " data-post = " . $pid . "> <i class='mi mi_sml text-danger txt_sha' id=" . $pid . ">favorite</i>Remove Favorite </div>";
    }
}
?>
    https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js
https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js
<script>

    $(document).ready(function ($) {
        $(".button").click(function (e) {
            e.preventDefault();
            const user_id = $(this).attr('data-user'); // Get the parameter user_id from the button
            const director_id = $(this).attr('data-post'); // Get the parameter director_id from the button
            const method = $(this).attr('method'); // Get the parameter method from the button
            if (method === "Like") {
                $(this).attr('method', 'Unlike'); // Change the div method attribute to Unlike
                $(this).html('<i class="mi mi_sml text-danger" id="' + director_id + '">favorite</i>Remove Favorite').toggleClass('button mybtn'); // Replace the image with the liked button
            } else {
                $(this).attr('method', 'Like');
                $(this).html('<i class="mi mi_sml" id="' + director_id + '">favorite_border</i>Add Favorite').toggleClass('mybtn button');
            }
            $.ajax({
                url: 'favs.php', // Call favs.php to update the database
                type: 'GET',
                data: {user_id: user_id, director_id: director_id, method: method},
                cache: false,
                success: function (data) {
                }
            });
        });
    });
</script>

Favs.php

<?php
include("$_SERVER[DOCUMENT_ROOT]/include/config.php");

$method = clean_input($_GET['method']);
$user_id = clean_input($_GET['user_id']);
$director_id = clean_input($_GET['director_id']);

if ($method == "Like") {
    $stmt = $conn->prepare('INSERT INTO favorite (memberID, id) VALUES (:mID, :pID)');
    $stmt->bindParam(':mID', $user_id, PDO::PARAM_INT, 12);
    $stmt->bindParam(':pID', $director_id, PDO::PARAM_INT, 12);
    $stmt->execute();
} elseif ($method == "Unlike") {
    $stmt = $conn->prepare('DELETE FROM favorite WHERE memberID=:mID and id=:pID');
    $stmt->bindParam(':mID', $user_id, PDO::PARAM_INT, 12);
    $stmt->bindParam(':pID', $director_id, PDO::PARAM_INT, 12);
    $stmt->execute();
} else {
    //do nothing
}

function clean_input($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
}

Correct me if there are any security flaw


Get this bounty!!!

#StackBounty: #htaccess #security #membership Strange behaviour of is_user_logged_in() and get_current_user_id()

Bounty: 150

I have an issue where is_user_logged_in() appears to alternate between being true and false.

Additionally, get_current_user_id() gives the correct user ID if is_user_logged_in() is true.

Here’s my code:

.htaccess:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]

RewriteCond %{REQUEST_FILENAME} -s
RewriteRule ^wp-content/uploads/(.*)$ file-access.php?file=$1 [QSA,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

file-access.php:

require_once('wp-load.php');

if ( is_user_logged_in() ) {
    // User is logged in, proceed.
} else {
    // User is a guest, block.
}

I’ve verified the alternating status and user id using some error logging in the file-access.php conditionals.

Do I need to call something other than wp-load.php perhaps? Just seems strange to me that it alternates between true and false, rather than always being false…


Get this bounty!!!