fixing some security issues and harderning service
Deploy / deploy (push) Successful in 38s

This commit is contained in:
2026-05-06 08:51:51 +02:00
parent 4d8ce1da43
commit 7ae7df0a11
30 changed files with 328 additions and 124 deletions
+2 -2
View File
@@ -1,5 +1,6 @@
<?php <?php
session_start(); include "../api/utils/security.php";
secure_session_start();
// Check if the user is logged in // Check if the user is logged in
if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true) { if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true) {
@@ -625,4 +626,3 @@ function generate2FAQRCode(issuer, accountName, secret) {
</body> </body>
</html> </html>
+4 -3
View File
@@ -1,13 +1,14 @@
<?php <?php
// Simulate fetching user data from a database // Simulate fetching user data from a database
session_start(); include "../utils/security.php";
secure_session_start();
header('Content-Type: application/json'); header('Content-Type: application/json');
if($_SESSION["logged_in"]!==true){ if(!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"]!==true){
$data=[ $data=[
'status' => 'error', 'status' => 'error',
'message' => 'not logged in' 'message' => 'not logged in'
]; ];
echo json_encode($user_data); echo json_encode($data);
exit(); exit();
} }
+8 -9
View File
@@ -1,15 +1,11 @@
<?php <?php
session_start(); include "../utils/security.php";
secure_session_start();
require_same_origin_request();
header('Content-Type: application/json'); header('Content-Type: application/json');
// Check if the user is logged in // Check if the user is logged in
if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true) { require_logged_in();
echo json_encode([
'success' => false,
'message' => 'Not logged in'
]);
exit();
}
// Include database configuration // Include database configuration
include "../../config/config.php"; include "../../config/config.php";
@@ -34,6 +30,10 @@ $username = $_SESSION["username"];
// Get the raw POST data (JSON) // Get the raw POST data (JSON)
$data = json_decode(file_get_contents("php://input")); $data = json_decode(file_get_contents("php://input"));
if(!isset($data->enable_2fa) || !is_bool($data->enable_2fa)){
echo json_encode(['success' => false, 'message' => 'Missing required fields.']);
exit();
}
if($data->enable_2fa==true){ if($data->enable_2fa==true){
//create 2fa secret key //create 2fa secret key
$twofa_secret=generateBase32Secret(); $twofa_secret=generateBase32Secret();
@@ -68,4 +68,3 @@ if($data->enable_2fa==false){
} }
?> ?>
+8 -9
View File
@@ -1,15 +1,11 @@
<?php <?php
session_start(); include "../utils/security.php";
secure_session_start();
require_same_origin_request();
header('Content-Type: application/json'); header('Content-Type: application/json');
// Check if the user is logged in // Check if the user is logged in
if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true) { require_logged_in();
echo json_encode([
'success' => false,
'message' => 'Not logged in'
]);
exit();
}
// Include database configuration // Include database configuration
include "../../config/config.php"; include "../../config/config.php";
@@ -32,6 +28,10 @@ $username = $_SESSION["username"];
// Get the raw POST data (JSON) // Get the raw POST data (JSON)
$data = json_decode(file_get_contents("php://input")); $data = json_decode(file_get_contents("php://input"));
if(!isset($data->enable_message) || !is_bool($data->enable_message)){
echo json_encode(['success' => false, 'message' => 'Missing required fields.']);
exit();
}
if($data->enable_message==true){ if($data->enable_message==true){
$sql="UPDATE users SET login_message=1 WHERE id = ?"; $sql="UPDATE users SET login_message=1 WHERE id = ?";
if ($update_stmt = $conn->prepare($sql)) { if ($update_stmt = $conn->prepare($sql)) {
@@ -64,4 +64,3 @@ if($data->enable_message==false){
} }
?> ?>
+3 -2
View File
@@ -3,6 +3,9 @@
header('Content-Type: application/json'); header('Content-Type: application/json');
include "../utils/security.php";
secure_session_start();
require_same_origin_request();
require_once 'WebAuthn.php'; require_once 'WebAuthn.php';
@@ -15,7 +18,6 @@ if ($conn->connect_error) {
} }
try { try {
session_start();
if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true) { if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true) {
echo json_encode([ echo json_encode([
'success' => false, 'success' => false,
@@ -168,4 +170,3 @@ try {
print(json_encode($return)); print(json_encode($return));
} }
?> ?>
+4 -10
View File
@@ -1,15 +1,11 @@
<?php <?php
session_start(); include "../utils/security.php";
secure_session_start();
require_same_origin_request();
header('Content-Type: application/json'); header('Content-Type: application/json');
// Check if the user is logged in // Check if the user is logged in
if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true) { require_logged_in();
echo json_encode([
'success' => false,
'message' => 'Not logged in'
]);
exit();
}
// Include database configuration // Include database configuration
include "../../config/config.php"; include "../../config/config.php";
@@ -36,7 +32,6 @@ $data = json_decode(file_get_contents("php://input"));
// Check if the required fields are present // Check if the required fields are present
if (isset($data->old_password) && isset($data->new_password)) { if (isset($data->old_password) && isset($data->new_password)) {
// Get the user ID (this should be taken from the session or JWT token) // Get the user ID (this should be taken from the session or JWT token)
session_start();
$user_id = $_SESSION['id']; // Assuming user_id is stored in session $user_id = $_SESSION['id']; // Assuming user_id is stored in session
// Sanitize inputs // Sanitize inputs
@@ -95,4 +90,3 @@ if (isset($data->old_password) && isset($data->new_password)) {
echo json_encode(['success' => false, 'message' => 'Missing required fields.']); echo json_encode(['success' => false, 'message' => 'Missing required fields.']);
} }
?> ?>
+12 -9
View File
@@ -1,15 +1,11 @@
<?php <?php
session_start(); include "../utils/security.php";
secure_session_start();
require_same_origin_request();
header('Content-Type: application/json'); header('Content-Type: application/json');
// Check if the user is logged in // Check if the user is logged in
if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true) { require_logged_in();
echo json_encode([
'success' => false,
'message' => 'Not logged in'
]);
exit();
}
// Include database configuration // Include database configuration
include "../../config/config.php"; include "../../config/config.php";
@@ -47,7 +43,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Sanitize and validate the input // Sanitize and validate the input
$name = preg_replace("/[^a-zA-Z0-9_]/", "", $data['name']); // Allow only letters, numbers, and underscores $name = preg_replace("/[^a-zA-Z0-9_]/", "", $data['name']); // Allow only letters, numbers, and underscores
$email = filter_var($data['email'], FILTER_SANITIZE_EMAIL); // Sanitize email $email = trim((string) $data['email']);
if ($email !== "" && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo json_encode([
'success' => false,
'message' => 'Invalid email address'
]);
exit();
}
$telegram_id = htmlspecialchars($data['telegram_id'], ENT_QUOTES, 'UTF-8'); // Escape special characters $telegram_id = htmlspecialchars($data['telegram_id'], ENT_QUOTES, 'UTF-8'); // Escape special characters
//check if username is allready taken //check if username is allready taken
+3 -4
View File
@@ -2,14 +2,14 @@
header('Content-Type: application/json'); header('Content-Type: application/json');
include "../../config/config.php"; include "../../config/config.php";
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE); $conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE);
$now=time();
$sql="DELETE FROM auth_tokens WHERE valid_until < ?;"; $sql="DELETE FROM auth_tokens WHERE valid_until < ?;";
$stmt = mysqli_prepare($conn, $sql); $stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, 'i',$now); mysqli_stmt_bind_param($stmt, 'i',$now);
mysqli_stmt_execute($stmt); mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt); mysqli_stmt_close($stmt);
$auth_key=$_GET["auth_token"]; $auth_key=$_GET["auth_token"] ?? "";
$now=time();
$sql="SELECT user_id FROM auth_tokens WHERE auth_token = ? AND valid_until > ?;"; $sql="SELECT user_id FROM auth_tokens WHERE auth_token = ? AND valid_until > ?;";
$stmt = mysqli_prepare($conn, $sql); $stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, 'si', $auth_key,$now); mysqli_stmt_bind_param($stmt, 'si', $auth_key,$now);
@@ -54,8 +54,7 @@ if(mysqli_stmt_num_rows($stmt) == 1){
}else{ }else{
$data=[ $data=[
'status' => 'failure', 'status' => 'failure',
'msg'=>'invalid auth key', 'msg'=>'invalid auth key'
'auth_key'=>$auth_key
]; ];
echo(json_encode($data)); echo(json_encode($data));
} }
+6 -3
View File
@@ -1,5 +1,7 @@
<?php <?php
session_start(); include "../utils/security.php";
secure_session_start();
require_same_origin_request();
header('Content-Type: application/json'); header('Content-Type: application/json');
$send_to=$_SESSION["end_url"]; $send_to=$_SESSION["end_url"];
@@ -17,10 +19,11 @@ $twofa_secret="";
mysqli_stmt_bind_result($stmt, $twofa_secret); mysqli_stmt_bind_result($stmt, $twofa_secret);
mysqli_stmt_fetch($stmt); mysqli_stmt_fetch($stmt);
mysqli_stmt_close($stmt); mysqli_stmt_close($stmt);
$twofa_pin=$_POST["twofa_pin"]; $twofa_pin=$_POST["twofa_pin"] ?? "";
if(generateTOTP($twofa_secret)===$twofa_pin){ if($twofa_secret !== "" && hash_equals(generateTOTP($twofa_secret), $twofa_pin)){
$_SESSION["mfa_authenticated"]=1; $_SESSION["mfa_authenticated"]=1;
session_regenerate_id(true);
$data = [ $data = [
'status' => 'success' 'status' => 'success'
]; ];
+4 -2
View File
@@ -1,5 +1,8 @@
<?php <?php
header('Content-Type: application/json'); header('Content-Type: application/json');
include "../utils/security.php";
secure_session_start();
require_same_origin_request();
require_once 'WebAuthn.php'; require_once 'WebAuthn.php';
include "../../config/config.php"; include "../../config/config.php";
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD,$DB_DATABASE); $conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD,$DB_DATABASE);
@@ -9,8 +12,6 @@ if ($conn->connect_error) {
} }
try { try {
session_start();
// read get argument and post body // read get argument and post body
$fn = filter_input(INPUT_GET, 'fn'); $fn = filter_input(INPUT_GET, 'fn');
$requireResidentKey = !!filter_input(INPUT_GET, 'requireResidentKey'); $requireResidentKey = !!filter_input(INPUT_GET, 'requireResidentKey');
@@ -144,6 +145,7 @@ try {
$_SESSION["mfa_authenticated"]=1; $_SESSION["mfa_authenticated"]=1;
$_SESSION["pw_authenticated"]=1; $_SESSION["pw_authenticated"]=1;
$_SESSION["passkey_authenticated"]=1; $_SESSION["passkey_authenticated"]=1;
session_regenerate_id(true);
$return = new stdClass(); $return = new stdClass();
$return->success = true; $return->success = true;
+6 -3
View File
@@ -1,5 +1,7 @@
<?php <?php
session_start(); include "../utils/security.php";
secure_session_start();
require_same_origin_request();
header('Content-Type: application/json'); header('Content-Type: application/json');
$send_to=$_SESSION["end_url"]; $send_to=$_SESSION["end_url"];
@@ -17,10 +19,11 @@ $pepper="";
mysqli_stmt_bind_result($stmt, $pw,$pepper); mysqli_stmt_bind_result($stmt, $pw,$pepper);
mysqli_stmt_fetch($stmt); mysqli_stmt_fetch($stmt);
mysqli_stmt_close($stmt); mysqli_stmt_close($stmt);
$password=$_POST["password"]; $password=$_POST["password"] ?? "";
if(password_verify($password.$pepper,$pw)){ if($pw !== "" && password_verify($password.$pepper,$pw)){
$_SESSION["pw_authenticated"]=1; $_SESSION["pw_authenticated"]=1;
session_regenerate_id(true);
$data = [ $data = [
'status' => 'success' 'status' => 'success'
]; ];
+4 -1
View File
@@ -1,7 +1,10 @@
<?php <?php
session_start(); include "../utils/security.php";
secure_session_start();
require_same_origin_request();
header('Content-Type: application/json'); header('Content-Type: application/json');
$send_to=$_SESSION["end_url"]; $send_to=$_SESSION["end_url"];
require_logged_in();
include "../../config/config.php"; include "../../config/config.php";
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE); $conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE);
+11 -5
View File
@@ -1,24 +1,30 @@
<?php <?php
session_start(); include "../utils/security.php";
secure_session_start();
require_same_origin_request();
header('Content-Type: application/json'); header('Content-Type: application/json');
$send_to=$_SESSION["end_url"]; $send_to=$_SESSION["end_url"];
include "../../config/config.php"; include "../../config/config.php";
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE); $conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE);
$keepmeloggedin=$_POST["keepmeloggedin"]; $keepmeloggedin=$_POST["keepmeloggedin"] ?? "false";
if($keepmeloggedin=="true"){ if($keepmeloggedin=="true"){
if (empty($_SESSION["id"]) || empty($_SESSION["pw_authenticated"]) || empty($_SESSION["mfa_authenticated"])) {
json_response(['status' => 'failure', 'message' => 'Not fully authenticated'], 401);
}
$_SESSION["keepmeloggedin_asked"]=true; $_SESSION["keepmeloggedin_asked"]=true;
$user_id=$_SESSION["id"]; $user_id=$_SESSION["id"];
//create a login token //create a login token
$login_token=bin2hex(random_bytes(128)); $login_token=bin2hex(random_bytes(128));
$agent=$_SERVER['HTTP_USER_AGENT']; $login_token_hash=remember_token_hash($login_token);
$agent=$_SERVER['HTTP_USER_AGENT'] ?? "";
$sql="INSERT INTO keepmeloggedin (auth_token,user_id,agent) VALUES (?,?,?);"; $sql="INSERT INTO keepmeloggedin (auth_token,user_id,agent) VALUES (?,?,?);";
$stmt = mysqli_prepare($conn, $sql); $stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, 'sis', $login_token,$user_id,$agent); mysqli_stmt_bind_param($stmt, 'sis', $login_token_hash,$user_id,$agent);
mysqli_stmt_execute($stmt); mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt); mysqli_stmt_close($stmt);
setcookie("auth_token", $login_token, time() + (30 * 24 * 60 * 60), "/", "", true, true); set_secure_cookie("auth_token", $login_token, time() + (30 * 24 * 60 * 60));
$data = [ $data = [
'status' => 'success' 'status' => 'success'
]; ];
+8 -6
View File
@@ -1,11 +1,12 @@
<?php <?php
session_start(); include "../utils/security.php";
secure_session_start();
header('Content-Type: application/json'); header('Content-Type: application/json');
include "../utils/get_location.php"; include "../utils/get_location.php";
$send_to=$_SESSION["end_url"]; $send_to=normalize_redirect_target($_SESSION["end_url"] ?? "/account/");
$send_to = htmlspecialchars(str_replace([';', 'script', 'java','(',')'],'',$send_to)); $_SESSION["end_url"] = $send_to;
include "../../config/config.php"; include "../../config/config.php";
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE); $conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE);
@@ -56,7 +57,7 @@ else if ($_SESSION["needs_auth"]===false && $_SESSION["mfa_authenticated"]==1 &&
if(!empty($send_to)){ if(!empty($send_to)){
$data=[ $data=[
'message' => 'done', 'message' => 'done',
'redirect' => $send_to."?auth=$auth_token" 'redirect' => append_auth_token_to_redirect($send_to, $auth_token)
]; ];
}else{ }else{
$data=[ $data=[
@@ -65,7 +66,8 @@ else if ($_SESSION["needs_auth"]===false && $_SESSION["mfa_authenticated"]==1 &&
]; ];
} }
//update last login //update last login
$ip=trim(explode(",",$_SERVER["HTTP_X_FORWARDED_FOR"])[0]); $forwarded_for = $_SERVER["HTTP_X_FORWARDED_FOR"] ?? $_SERVER["REMOTE_ADDR"] ?? "";
$ip=trim(explode(",",$forwarded_for)[0]);
$date=date('Y-m-d H:i:s'); $date=date('Y-m-d H:i:s');
$last_login_msg=$date." from ".$ip; $last_login_msg=$date." from ".$ip;
$sql="UPDATE users SET last_login = ? WHERE id = ?"; $sql="UPDATE users SET last_login = ? WHERE id = ?";
@@ -75,7 +77,7 @@ else if ($_SESSION["needs_auth"]===false && $_SESSION["mfa_authenticated"]==1 &&
mysqli_stmt_close($stmt); mysqli_stmt_close($stmt);
//send login message //send login message
if($_SESSION["login_message"] && $_SESSION["logged_in"]!==true){ if($_SESSION["login_message"] && $_SESSION["logged_in"]!==true){
$device = $_SERVER['HTTP_USER_AGENT']; $device = $_SERVER['HTTP_USER_AGENT'] ?? "";
$location=get_location_from_ip($ip); $location=get_location_from_ip($ip);
$message = "⚠️ *Login Warning*\n\n" $message = "⚠️ *Login Warning*\n\n"
. "We noticed a login attempt with your account.\n\n" . "We noticed a login attempt with your account.\n\n"
+18 -5
View File
@@ -1,9 +1,15 @@
<?php <?php
session_start(); include "../utils/security.php";
secure_session_start();
require_same_origin_request();
header('Content-Type: application/json'); header('Content-Type: application/json');
include "../../config/config.php"; include "../../config/config.php";
include "../utils/get_location.php"; include "../utils/get_location.php";
$username=$_SESSION["username"]; $username=$_SESSION["username"] ?? "";
if ($username === "") {
echo json_encode(['success' => false, 'message' => 'Missing username.']);
exit;
}
$sql="SELECT id, email, telegram_id FROM users WHERE username = ?;"; $sql="SELECT id, email, telegram_id FROM users WHERE username = ?;";
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE); $conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE);
$mail=""; $mail="";
@@ -15,11 +21,17 @@ mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt); mysqli_stmt_store_result($stmt);
mysqli_stmt_bind_result($stmt,$id, $mail,$telegram_id); mysqli_stmt_bind_result($stmt,$id, $mail,$telegram_id);
mysqli_stmt_fetch($stmt); mysqli_stmt_fetch($stmt);
$user_found = mysqli_stmt_num_rows($stmt) === 1;
mysqli_stmt_close($stmt); mysqli_stmt_close($stmt);
if (!$user_found) {
echo json_encode(['success' => true, 'message' => 'If the account has reset methods configured, a reset link has been sent.']);
exit;
}
//send telegram message //send telegram message
$device = $_SERVER['HTTP_USER_AGENT']; $device = $_SERVER['HTTP_USER_AGENT'] ?? "";
//$ip=$_SERVER["REMOTE_ADDR"]; //$ip=$_SERVER["REMOTE_ADDR"];
$ip=trim(explode(",",$_SERVER["HTTP_X_FORWARDED_FOR"])[0]); $forwarded_for = $_SERVER["HTTP_X_FORWARDED_FOR"] ?? $_SERVER["REMOTE_ADDR"] ?? "";
$ip=trim(explode(",",$forwarded_for)[0]);
$location=get_location_from_ip($ip); $location=get_location_from_ip($ip);
$date=date('Y-m-d H:i:s'); $date=date('Y-m-d H:i:s');
$token=bin2hex(random_bytes(128)); $token=bin2hex(random_bytes(128));
@@ -628,11 +640,12 @@ if(!empty($mail)){
//insert the token into our db //insert the token into our db
$valid_until=time()+(8600/2); $valid_until=time()+(12 * 60 * 60);
$sql="INSERT INTO reset_tokens (auth_token, user_id,valid_until) VALUES (?,?,?);"; $sql="INSERT INTO reset_tokens (auth_token, user_id,valid_until) VALUES (?,?,?);";
$stmt = mysqli_prepare($conn, $sql); $stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, 'sii', $token,$id,$valid_until); mysqli_stmt_bind_param($stmt, 'sii', $token,$id,$valid_until);
mysqli_stmt_execute($stmt); mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt); mysqli_stmt_close($stmt);
echo json_encode(['success' => true, 'message' => 'If the account has reset methods configured, a reset link has been sent.']);
?> ?>
+6 -2
View File
@@ -1,6 +1,10 @@
<?php <?php
session_start(); include "../utils/security.php";
secure_session_start();
require_same_origin_request();
$_SESSION["needs_auth"]=true; $_SESSION["needs_auth"]=true;
$_SESSION["logged_in"]=false; $_SESSION["logged_in"]=false;
$_SESSION["username"]=preg_replace("/[^a-z0-9_]/","",$_POST["username"]); $username = strtolower((string) ($_POST["username"] ?? ""));
$_SESSION["username"]=preg_replace("/[^a-z0-9_]/","",$username);
session_regenerate_id(true);
?> ?>
+4 -2
View File
@@ -1,8 +1,10 @@
<?php <?php
header('Content-Type: application/json'); header('Content-Type: application/json');
session_start(); include "../utils/security.php";
secure_session_start();
require_same_origin_request();
//check for permisisons //check for permisisons
if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true || $_SESSION["permissions"][0]!=="1" ) { if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true || !is_admin_session() ) {
echo(json_encode(['success' => false, 'message'=>'not authenticated'])); echo(json_encode(['success' => false, 'message'=>'not authenticated']));
exit(); exit();
} }
+3 -2
View File
@@ -1,8 +1,9 @@
<?php <?php
header('Content-Type: application/json'); header('Content-Type: application/json');
session_start(); include "../utils/security.php";
secure_session_start();
//check for permisisons //check for permisisons
if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true || $_SESSION["permissions"][0]!=="1" ) { if (!isset($_SESSION["logged_in"]) || $_SESSION["logged_in"] !== true || !is_admin_session() ) {
echo(json_encode(['success' => false, 'message'=>'not authenticated'])); echo(json_encode(['success' => false, 'message'=>'not authenticated']));
exit(); exit();
} }
+25 -5
View File
@@ -1,5 +1,8 @@
<?php <?php
// Set response headers to return JSON // Set response headers to return JSON
include "../utils/security.php";
secure_session_start();
require_same_origin_request();
header('Content-Type: application/json'); header('Content-Type: application/json');
include "../../config/config.php"; include "../../config/config.php";
@@ -22,7 +25,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$data = json_decode($input, true); $data = json_decode($input, true);
// Validate input // Validate input
if (!isset($data['username']) || !isset($data['password'])) { if (!is_array($data) || !isset($data['username']) || !isset($data['password'])) {
echo json_encode([ echo json_encode([
'success' => false, 'success' => false,
'message' => 'Invalid input. Username and password are required.' 'message' => 'Invalid input. Username and password are required.'
@@ -30,10 +33,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
exit; exit;
} }
$username = trim($data['username']); $username = strtolower(trim((string) $data['username']));
$email = trim($data['email']); $username = preg_replace("/[^a-z0-9_]/", "", $username);
$password = trim($data['password']); $email = trim((string) ($data['email'] ?? ""));
$telegram_id = trim($data['telegram']); $password = (string) $data['password'];
$telegram_id = trim((string) ($data['telegram'] ?? ""));
// Check for empty fields // Check for empty fields
if (empty($username) || empty($password)) { if (empty($username) || empty($password)) {
@@ -44,6 +48,22 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
exit; exit;
} }
if (strlen($password) < 12) {
echo json_encode([
'success' => false,
'message' => 'Password must be at least 12 characters.'
]);
exit;
}
if ($email !== "" && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo json_encode([
'success' => false,
'message' => 'Invalid email address.'
]);
exit;
}
// Check if the username already exists // Check if the username already exists
$sql = "SELECT id FROM users WHERE username = ?"; $sql = "SELECT id FROM users WHERE username = ?";
$stmt = mysqli_prepare($conn, $sql); $stmt = mysqli_prepare($conn, $sql);
+7 -1
View File
@@ -5,17 +5,22 @@
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE); $conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE);
if (isset($_COOKIE['auth_token'])) { if (isset($_COOKIE['auth_token'])) {
$auth_token=$_COOKIE['auth_token']; $auth_token=$_COOKIE['auth_token'];
$auth_token_hash=remember_token_hash($auth_token);
$sql="SELECT user_id,agent FROM keepmeloggedin WHERE auth_token = ?"; $sql="SELECT user_id,agent FROM keepmeloggedin WHERE auth_token = ?";
$user_id=0; $user_id=0;
$agent=""; $agent="";
$stmt = mysqli_prepare($conn, $sql); $stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, 's',$auth_token); mysqli_stmt_bind_param($stmt, 's',$auth_token_hash);
mysqli_stmt_execute($stmt); mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt); mysqli_stmt_store_result($stmt);
if(mysqli_stmt_num_rows($stmt) == 1){ if(mysqli_stmt_num_rows($stmt) == 1){
mysqli_stmt_bind_result($stmt, $user_id,$agent); mysqli_stmt_bind_result($stmt, $user_id,$agent);
mysqli_stmt_fetch($stmt); mysqli_stmt_fetch($stmt);
mysqli_stmt_close($stmt); mysqli_stmt_close($stmt);
if (!hash_equals($agent, $_SERVER['HTTP_USER_AGENT'] ?? "")) {
delete_cookie("auth_token");
return $ret;
}
//load user data //load user data
$sql="SELECT auth_method_required_pw, auth_method_required_2fa, auth_method_required_passkey, username, user_token,last_login, login_message,telegram_id, permissions FROM users WHERE id = ?"; $sql="SELECT auth_method_required_pw, auth_method_required_2fa, auth_method_required_passkey, username, user_token,last_login, login_message,telegram_id, permissions FROM users WHERE id = ?";
@@ -52,6 +57,7 @@
$_SESSION["keepmeloggedin_asked"]=true; $_SESSION["keepmeloggedin_asked"]=true;
$_SESSION["logged_in"]=true; $_SESSION["logged_in"]=true;
$_SESSION["needs_auth"]=false; $_SESSION["needs_auth"]=false;
session_regenerate_id(true);
$ret="success"; $ret="success";
} }
mysqli_stmt_close($stmt); mysqli_stmt_close($stmt);
+128
View File
@@ -0,0 +1,128 @@
<?php
function secure_session_start(): void
{
if (session_status() === PHP_SESSION_ACTIVE) {
return;
}
$is_https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| (isset($_SERVER['SERVER_PORT']) && (int) $_SERVER['SERVER_PORT'] === 443);
session_set_cookie_params([
'lifetime' => 0,
'path' => '/',
'domain' => '',
'secure' => $is_https,
'httponly' => true,
'samesite' => 'Lax',
]);
session_start();
}
function json_response(array $data, int $status_code = 200): void
{
http_response_code($status_code);
header('Content-Type: application/json');
echo json_encode($data);
exit;
}
function require_same_origin_request(): void
{
if (!in_array($_SERVER['REQUEST_METHOD'] ?? 'GET', ['POST', 'PUT', 'PATCH', 'DELETE'], true)) {
return;
}
$host = $_SERVER['HTTP_HOST'] ?? '';
$source = $_SERVER['HTTP_ORIGIN'] ?? $_SERVER['HTTP_REFERER'] ?? '';
if ($source === '') {
return;
}
$source_host = parse_url($source, PHP_URL_HOST);
$source_port = parse_url($source, PHP_URL_PORT);
if ($source_host && $source_port) {
$source_host .= ':' . $source_port;
}
if (!$source_host || !hash_equals(strtolower($host), strtolower($source_host))) {
json_response(['success' => false, 'message' => 'Invalid request origin.'], 403);
}
}
function require_logged_in(): void
{
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true || empty($_SESSION['id'])) {
json_response(['success' => false, 'message' => 'Not logged in'], 401);
}
}
function is_admin_session(): bool
{
return !empty($_SESSION['permissions'])
&& is_string($_SESSION['permissions'])
&& isset($_SESSION['permissions'][0])
&& $_SESSION['permissions'][0] === '1';
}
function remember_token_hash(string $token): string
{
return hash('sha256', $token);
}
function set_secure_cookie(string $name, string $value, int $expires): void
{
$is_https = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| (isset($_SERVER['SERVER_PORT']) && (int) $_SERVER['SERVER_PORT'] === 443);
setcookie($name, $value, [
'expires' => $expires,
'path' => '/',
'secure' => $is_https,
'httponly' => true,
'samesite' => 'Lax',
]);
}
function delete_cookie(string $name): void
{
set_secure_cookie($name, '', time() - 3600);
}
function normalize_redirect_target(?string $target): string
{
$target = trim((string) $target);
if ($target === '') {
return '/account/';
}
if (preg_match('/[\r\n]/', $target)) {
return '/account/';
}
if (str_starts_with($target, '/') && !str_starts_with($target, '//')) {
return $target;
}
$parts = parse_url($target);
if (!$parts || empty($parts['scheme']) || empty($parts['host'])) {
return '/account/';
}
if (!in_array(strtolower($parts['scheme']), ['http', 'https'], true)) {
return '/account/';
}
return $target;
}
function append_auth_token_to_redirect(string $redirect, string $auth_token): string
{
$separator = str_contains($redirect, '?') ? '&' : '?';
return $redirect . $separator . 'auth=' . rawurlencode($auth_token);
}
?>
+17 -15
View File
@@ -1,3 +1,20 @@
<?php
include "api/utils/security.php";
include "api/utils/check_keepmeloggedin.php";
secure_session_start();
$_SESSION["end_url"]=normalize_redirect_target($_GET["send_to"] ?? "/account/");
if (isset($_SESSION["logged_in"]) && $_SESSION["logged_in"] === true && !isset($_GET["donotsend"]) /*also check for keepmeloggedin here*/) {
header("LOCATION:/login/account_selector.php");
exit();
}
if(isset($_GET["donotsend"])){
delete_cookie("auth_token");
}
if(logmein()==="success"){
header("LOCATION:/login/account_selector.php");
exit();
}
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" data-bs-theme="dark"> <html lang="en" data-bs-theme="dark">
<head> <head>
@@ -8,20 +25,6 @@
<title>Jakach Login</title> <title>Jakach Login</title>
<?php <?php
include "assets/components.php"; include "assets/components.php";
include "api/utils/check_keepmeloggedin.php";
session_start();
$_SESSION["end_url"]=$_GET["send_to"];
if (isset($_SESSION["logged_in"]) && $_SESSION["logged_in"] === true && !isset($_GET["donotsend"]) /*also check for keepmeloggedin here*/) {
header("LOCATION:/login/account_selector.php");
exit();
}
if(isset($_GET["donotsend"])){
setcookie("auth_token", "", time() - 3600, "/");
}
if(logmein()==="success"){
header("LOCATION:/login/account_selector.php");
exit();
}
?> ?>
</head> </head>
<body> <body>
@@ -135,4 +138,3 @@
?> ?>
</body> </body>
</html> </html>
+6 -4
View File
@@ -1,3 +1,7 @@
<?php
include "../api/utils/security.php";
secure_session_start();
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" data-bs-theme="dark"> <html lang="en" data-bs-theme="dark">
<head> <head>
@@ -6,7 +10,6 @@
<title>Jakach Login</title> <title>Jakach Login</title>
<?php <?php
include "../assets/components.php"; include "../assets/components.php";
session_start();
?> ?>
</head> </head>
<body> <body>
@@ -22,8 +25,8 @@
<!-- Submit Button --> <!-- Submit Button -->
<div class="d-grid gap-2"> <div class="d-grid gap-2">
<!-- Login Button --> <!-- Login Button -->
<a href="/login/" class="btn btn-primary btn-lg" id="continueLink">Continue as <?php echo($_SESSION["username"]); ?></a> <a href="/login/" class="btn btn-primary btn-lg" id="continueLink">Continue as <?php echo(htmlspecialchars($_SESSION["username"] ?? "", ENT_QUOTES, "UTF-8")); ?></a>
<a class="btn btn-outline-primary btn-lg" href="/?donotsend&send_to=<?php echo($_SESSION["end_url"]); ?>">Use another account</a> <a class="btn btn-outline-primary btn-lg" href="/?donotsend&send_to=<?php echo(rawurlencode($_SESSION["end_url"] ?? "/account/")); ?>">Use another account</a>
</div> </div>
</form> </form>
</div> </div>
@@ -43,4 +46,3 @@ document.addEventListener("keydown", function(event) {
</script> </script>
</body> </body>
</html> </html>
+4 -2
View File
@@ -1,3 +1,7 @@
<?php
include "../api/utils/security.php";
secure_session_start();
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" data-bs-theme="dark"> <html lang="en" data-bs-theme="dark">
<head> <head>
@@ -6,7 +10,6 @@
<title>Jakach Login</title> <title>Jakach Login</title>
<?php <?php
include "../assets/components.php"; include "../assets/components.php";
session_start();
?> ?>
</head> </head>
<body> <body>
@@ -66,4 +69,3 @@
</script> </script>
</body> </body>
</html> </html>
+3 -2
View File
@@ -1,7 +1,8 @@
<?php <?php
session_start(); include "../api/utils/security.php";
secure_session_start();
session_unset(); session_unset();
session_destroy(); session_destroy();
setcookie("auth_token", "", time() - 3600, "/"); delete_cookie("auth_token");
header("LOCATION:/"); header("LOCATION:/");
?> ?>
+4 -2
View File
@@ -1,3 +1,7 @@
<?php
include "../api/utils/security.php";
secure_session_start();
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" data-bs-theme="dark"> <html lang="en" data-bs-theme="dark">
<head> <head>
@@ -6,7 +10,6 @@
<title>Jakach Login</title> <title>Jakach Login</title>
<?php <?php
include "../assets/components.php"; include "../assets/components.php";
session_start();
?> ?>
</head> </head>
<body> <body>
@@ -112,4 +115,3 @@
</script> </script>
</body> </body>
</html> </html>
+4 -2
View File
@@ -1,3 +1,7 @@
<?php
include "../api/utils/security.php";
secure_session_start();
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" data-bs-theme="dark"> <html lang="en" data-bs-theme="dark">
<head> <head>
@@ -6,7 +10,6 @@
<title>Jakach Login</title> <title>Jakach Login</title>
<?php <?php
include "../assets/components.php"; include "../assets/components.php";
session_start();
?> ?>
</head> </head>
<body> <body>
@@ -256,4 +259,3 @@ async function checkRegistration() {
</script> </script>
</body> </body>
</html> </html>
+4 -2
View File
@@ -1,3 +1,7 @@
<?php
include "../api/utils/security.php";
secure_session_start();
?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" data-bs-theme="dark"> <html lang="en" data-bs-theme="dark">
<head> <head>
@@ -6,7 +10,6 @@
<title>Jakach Login</title> <title>Jakach Login</title>
<?php <?php
include "../assets/components.php"; include "../assets/components.php";
session_start();
?> ?>
</head> </head>
<body> <body>
@@ -142,4 +145,3 @@
</script> </script>
</body> </body>
</html> </html>
+8 -3
View File
@@ -2,10 +2,16 @@
/* /*
This file can be installed in any service. If done so a user can authenticate with Jakach Auth. Jakach Auth will redirect the user here where their token gets validated, and then they can be logged in to your service. This file can be installed in any service. If done so a user can authenticate with Jakach Auth. Jakach Auth will redirect the user here where their token gets validated, and then they can be logged in to your service.
*/ */
$auth_token = $_GET["auth"]; $auth_token = $_GET["auth"] ?? "";
header('Content-Type: application/json');
if ($auth_token === '') {
echo json_encode(['status' => 'failure', 'msg' => 'Missing auth token']);
exit;
}
// Check the auth token against Jakach login API // Check the auth token against Jakach login API
$check_url = "https://auth.jakach.ch/api/auth/check_auth_key.php?auth_token=" . $auth_token; $check_url = "https://auth.jakach.ch/api/auth/check_auth_key.php?auth_token=" . rawurlencode($auth_token);
// Initialize cURL // Initialize cURL
$ch = curl_init(); $ch = curl_init();
@@ -47,4 +53,3 @@ if (isset($data['status'])) {
echo json_encode(['status' => 'failure', 'msg' => 'Invalid response from authentication server']); echo json_encode(['status' => 'failure', 'msg' => 'Invalid response from authentication server']);
} }
?> ?>
+4 -7
View File
@@ -1,5 +1,6 @@
<?php <?php
session_start(); include "../api/utils/security.php";
secure_session_start();
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" data-bs-theme="dark"> <html lang="en" data-bs-theme="dark">
@@ -134,12 +135,8 @@ session_start();
showModalMessage('Success', 'Registration successful!'); showModalMessage('Success', 'Registration successful!');
// Redirect to a different page if needed after closing the modal // Redirect to a different page if needed after closing the modal
setTimeout(() => { setTimeout(() => {
<?php const endUrl = <?php echo json_encode($_SESSION["end_url"] ?? "/account/"); ?>;
if(empty($_SESSION["end_url"])) window.location.href = '/?send_to=' + encodeURIComponent(endUrl);
echo("window.location.href = '/?send_to=/account/';");
else
echo("window.location.href = '/?send_to=".$_SESSION["end_url"]."';");
?>
}, 2000); }, 2000);
} else { } else {
showModalMessage('Error', result.message || 'Registration failed!'); showModalMessage('Error', result.message || 'Registration failed!');