Refactor and enforce Content-Security-Policy
This commit is contained in:
parent
6d17b400de
commit
79cb1a8f25
4
app.php
4
app.php
@ -74,7 +74,7 @@ if (!is_empty($_GET['page'])) {
|
||||
}
|
||||
?>
|
||||
<a class="navbar-brand" href="app.php">
|
||||
<img style="height: 35px; padding-bottom: 12px; padding-left: 5px;" src="<?php echo $src; ?>" />
|
||||
<img src="<?php echo $src; ?>" />
|
||||
</a>
|
||||
<?php
|
||||
}
|
||||
@ -122,7 +122,7 @@ if (!is_empty($_GET['page'])) {
|
||||
<?php
|
||||
if (MENU_BAR_STYLE == "fixed") {
|
||||
?>
|
||||
<div style="height: 75px;"></div>
|
||||
<div class="pad-75px"></div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
@ -54,11 +54,11 @@ if (count($messages) > 0) {
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<i class="fa fa-user fa-fw"></i> <span data-toggle="tooltip" title="<?php lang2("from user", ["user" => $usercache[$msg['from']]['username']]) ?>"><?php echo $usercache[$msg['from']]['name']; ?></span> <i class="fa fa-caret-right fa-fw"></i> <span data-toggle="tooltip" title="<?php lang2("to user", ["user" => $to['username']]) ?>"><?php echo $to['name']; ?></span>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-6" style="text-align: right;">
|
||||
<div class="col-xs-12 col-sm-6 col-md-6 text-right">
|
||||
<i class='fa fa-clock-o'></i> <?php echo date("F j, Y, g:i a", strtotime($msg['date'])) ?>
|
||||
<form style="display: inline-block; margin-left: 5px;"
|
||||
action="action.php" method="GET"
|
||||
onsubmit="$('#delmsgbtn<?php echo $msg['id']; ?>').prop('disabled', true);setTimeout(refreshMsgs, 100);">
|
||||
<form class="msgdelform"
|
||||
data-msgid="<?php echo $msg['id']; ?>"
|
||||
action="action.php" method="GET">
|
||||
<input type="hidden" name="msgid" value="<?php echo $msg['id']; ?>" />
|
||||
<input type="hidden" name="action" value="delmsg" />
|
||||
<button type="submit" id="delmsgbtn<?php echo $msg['id']; ?>" class="btn btn-sm btn-danger" data-toggle="tooltip" data-placement="auto left" title="<?php lang("delete message") ?>"><i class="fa fa-trash"></i></button>
|
||||
|
@ -115,12 +115,16 @@ if (count($tasks) > 0) {
|
||||
</div>
|
||||
<div class='col-xs-12 col-sm-4 col-md-4'>
|
||||
<div class='pull-right'>
|
||||
<form action='app.php?page=edittask' method='GET' class='form-inline' style='display: inline-block;'>
|
||||
<form action='app.php?page=edittask' method='GET' class='form-inline inblock'>
|
||||
<input type='hidden' name='page' value='edittask' />
|
||||
<input type='hidden' name='taskid' value='<?php echo $task['taskid'] ?>' />
|
||||
<button type='submit' class='btn btn-sm btn-primary' data-toggle="tooltip" data-placement="auto left" title="<?php lang("edit task") ?>"><i class='fa fa-pencil'></i></button>
|
||||
</form>
|
||||
<form action='action.php' onsubmit='$("#deltaskbtn<?php echo $task['taskid'] ?>").prop("disabled", true);' method='POST' class='form-inline' style='display: inline-block; padding-left: 5px;'>
|
||||
<form
|
||||
action='action.php'
|
||||
method='POST'
|
||||
data-taskid="<?php echo $task['taskid'] ?>"
|
||||
class='form-inline inblock padleft-5px deltaskform'>
|
||||
<input type='hidden' name='taskid' value='<?php echo $task['taskid'] ?>' />
|
||||
<input type='hidden' name='action' value='deltask' />
|
||||
<?php
|
||||
@ -146,7 +150,7 @@ if (count($tasks) > 0) {
|
||||
if (isset($_GET['alone']) || (isset($pageid) && $pageid != "home")) {
|
||||
echo "<div class=\"col-xs-12 col-sm-6 col-md-4 col-sm-offset-3 col-md-offset-4\">";
|
||||
} else {
|
||||
echo "<div style=\"height: 52px;\"></div>";
|
||||
echo "<div class=\"height-52px></div>";
|
||||
}
|
||||
echo "<div class='alert alert-info'><i class='fa fa-info-circle'></i> " . lang("no tasks", false) . "</div>";
|
||||
if (isset($_GET['alone']) || (isset($pageid) && $pageid != "home")) {
|
||||
|
@ -73,7 +73,12 @@ if (count($tasks) > 0) {
|
||||
<?php
|
||||
if ($task['statusid'] == 0) {
|
||||
?>
|
||||
<form action='action.php' method='POST' onsubmit='$("#starttaskbtn<?php echo $task['taskid'] ?>").prop("disabled", true); refreshTasksSoon();' class='form-inline' style='display: inline-block;'>
|
||||
<form
|
||||
action='action.php'
|
||||
method='POST'
|
||||
data-taskid="<?php echo $task['taskid'] ?>"
|
||||
data-action="start"
|
||||
class='form-inline inblock task-btn'>
|
||||
<input type='hidden' name='taskid' value='<?php echo $task['taskid'] ?>' />
|
||||
<input type='hidden' name='action' value='start' />
|
||||
<button type='submit' id='starttaskbtn<?php echo $task['taskid'] ?>' class='btn btn-primary'><i class='fa fa-fw fa-play'></i> <?php lang("start") ?></button>
|
||||
@ -81,17 +86,32 @@ if (count($tasks) > 0) {
|
||||
<?php
|
||||
} else if ($task['statusid'] == 1) {
|
||||
?>
|
||||
<form action='action.php' method='POST' onsubmit='$("#finishtaskbtn<?php echo $task['taskid'] ?>").prop("disabled", true); refreshTasksSoon();' class='form-inline' style='display: inline-block; padding-left: 5px;'>
|
||||
<form
|
||||
action='action.php'
|
||||
method='POST'
|
||||
data-taskid="<?php echo $task['taskid'] ?>"
|
||||
data-action="finish"
|
||||
class='form-inline inblock task-btn padleft-5px'>
|
||||
<input type='hidden' name='taskid' value='<?php echo $task['taskid'] ?>' />
|
||||
<input type='hidden' name='action' value='finish' />
|
||||
<button type='submit' id='finishtaskbtn<?php echo $task['taskid'] ?>' class='btn btn-success'><i class='fa fa-stop'></i> <?php lang("finish") ?></button>
|
||||
</form>
|
||||
<form action='action.php' method='POST' onsubmit='$("#pausetaskbtn<?php echo $task['taskid'] ?>").prop("disabled", true); refreshTasksSoon();' class='form-inline' style='display: inline-block; padding-left: 5px;'>
|
||||
<form
|
||||
action='action.php'
|
||||
method='POST'
|
||||
data-taskid="<?php echo $task['taskid'] ?>"
|
||||
data-action="pause"
|
||||
class='form-inline inblock task-btn padleft-5px'>
|
||||
<input type='hidden' name='taskid' value='<?php echo $task['taskid'] ?>' />
|
||||
<input type='hidden' name='action' value='pause' />
|
||||
<button type='submit' id='pausetaskbtn<?php echo $task['taskid'] ?>' class='btn btn-warning'><i class='fa fa-pause'></i> <?php lang("pause") ?></button>
|
||||
</form>
|
||||
<form action='action.php' method='POST' onsubmit='$("#problemtaskbtn<?php echo $task['taskid'] ?>").prop("disabled", true); refreshTasksSoon();' class='form-inline' style='display: inline-block; padding-left: 5px;'>
|
||||
<form
|
||||
action='action.php'
|
||||
method='POST'
|
||||
data-taskid="<?php echo $task['taskid'] ?>"
|
||||
data-action="problem"
|
||||
class='form-inline inblock task-btn padleft-5px'>
|
||||
<input type='hidden' name='taskid' value='<?php echo $task['taskid'] ?>' />
|
||||
<input type='hidden' name='action' value='problem' />
|
||||
<button type='submit' id='problemtaskbtn<?php echo $task['taskid'] ?>' class='btn btn-danger'><i class='fa fa-exclamation'></i> <?php lang("problem") ?></button>
|
||||
@ -99,7 +119,12 @@ if (count($tasks) > 0) {
|
||||
<?php
|
||||
} else if ($task['statusid'] == 3 || $task['statusid'] == 4) {
|
||||
?>
|
||||
<form action='action.php' method='POST' onsubmit='$("#resumetaskbtn<?php echo $task['taskid'] ?>").prop("disabled", true); refreshTasksSoon();' class='form-inline' style='display: inline-block;'>
|
||||
<form
|
||||
action='action.php'
|
||||
method='POST'
|
||||
data-taskid="<?php echo $task['taskid'] ?>"
|
||||
data-action="resume"
|
||||
class='form-inline inblock task-btn'>
|
||||
<input type='hidden' name='taskid' value='<?php echo $task['taskid'] ?>' />
|
||||
<input type='hidden' name='action' value='resume' />
|
||||
<button type='submit' id='resumetaskbtn<?php echo $task['taskid'] ?>' class='btn btn-primary'><i class='fa fa-play'></i> <?php lang("resume") ?></button>
|
||||
|
@ -90,6 +90,7 @@ switch ($VARS['action']) {
|
||||
if (authenticate_user($VARS['username'], $VARS['password'], $autherror)) {
|
||||
if (account_has_permission($VARS['username'], "TASKFLOOR")) {
|
||||
doLoginUser($VARS['username'], $VARS['password']);
|
||||
$_SESSION['mobile'] = true;
|
||||
exit(json_encode(["status" => "OK"]));
|
||||
} else {
|
||||
exit(json_encode(["status" => "ERROR", "msg" => lang("no permission", false)]));
|
||||
|
13
pages.php
13
pages.php
@ -11,18 +11,25 @@ define("PAGES", [
|
||||
],
|
||||
"scripts" => [
|
||||
"static/js/jquery.easy-autocomplete.min.js",
|
||||
"static/js/messages.js"
|
||||
"static/js/messages.js",
|
||||
"static/js/tasks.js"
|
||||
]
|
||||
],
|
||||
"mytasks" => [
|
||||
"title" => "my tasks",
|
||||
"navbar" => true,
|
||||
"icon" => "th-list"
|
||||
"icon" => "th-list",
|
||||
"scripts" => [
|
||||
"static/js/tasks.js"
|
||||
]
|
||||
],
|
||||
"taskman" => [
|
||||
"title" => "task manager",
|
||||
"navbar" => true,
|
||||
"icon" => "tasks"
|
||||
"icon" => "tasks",
|
||||
"scripts" => [
|
||||
"static/js/taskman.js"
|
||||
]
|
||||
],
|
||||
"messages" => [
|
||||
"title" => "messages",
|
||||
|
@ -6,41 +6,26 @@ redirectifnotloggedin();
|
||||
<h2 class="page-header">
|
||||
<?php lang("messages") ?>
|
||||
</h2>
|
||||
<form action="action.php" method="POST" onsubmit="setTimeout(function () {
|
||||
$('#msgsendbox').val('');
|
||||
$('#msgtobox').val('');
|
||||
refreshMsgs();
|
||||
}, 100);" class="form-horizontal">
|
||||
<form action="action.php" method="POST" class="form-horizontal" id="msgsendform">
|
||||
<input type="hidden" name="action" value="sendmsg" />
|
||||
<div class="form-group">
|
||||
<div class="col-xs-12 col-sm-6" style="margin-bottom: 5px;">
|
||||
<div class="col-xs-12 col-sm-6 mgn-btm-5px">
|
||||
<input type="text" id="msgsendbox" name="msg" class="form-control" placeholder="<?php lang("send message") ?>" autocomplete="off" />
|
||||
</div>
|
||||
<div class="col-xs-9 col-sm-4" style="padding-right: 0px;">
|
||||
<div class="col-xs-9 col-sm-4 padright-0px">
|
||||
<input type="text" id="msgtobox" name="to" class="form-control" placeholder="<?php lang("to") ?>" autocomplete="off" />
|
||||
</div>
|
||||
<button id="msgsendbtn" style="border-top-left-radius: 0px; border-bottom-left-radius: 0px; margin-left: 0px;" class="btn btn-primary col-xs-3 col-sm-2" type="submit"><i class="fa fa-paper-plane"></i> <?php lang("send") ?></button>
|
||||
<button id="msgsendbtn" class="btn btn-primary col-xs-3 col-sm-2" type="submit"><i class="fa fa-paper-plane"></i> <?php lang("send") ?></button>
|
||||
</div>
|
||||
</form>
|
||||
<div style="<?php
|
||||
<div<?php
|
||||
if ($pageid != "messages") {
|
||||
echo "max-height: 600px; overflow-y: auto; padding: 5px;";
|
||||
echo ' class="home-list-container"';
|
||||
}
|
||||
?>">
|
||||
?>>
|
||||
<div id="messagedispdiv">
|
||||
<?php
|
||||
include __DIR__ . '/../lib/getmsgs.php';
|
||||
?>
|
||||
</div>
|
||||
<script>
|
||||
function refreshMsgs() {
|
||||
$.get('lib/getmsgs.php', function (data) {
|
||||
$('#messagedispdiv').html(data);
|
||||
setupTooltips();
|
||||
});
|
||||
}
|
||||
setInterval(function () {
|
||||
refreshMsgs();
|
||||
}, 10 * 1000);
|
||||
</script>
|
||||
</div>
|
@ -4,15 +4,17 @@ require_once __DIR__ . '/../required.php';
|
||||
redirectifnotloggedin();
|
||||
?>
|
||||
<h2 class="page-header"><?php lang("my tasks") ?></h2>
|
||||
<div id="tasksdispdiv" style="<?php if ($pageid != "mytasks") {
|
||||
echo "max-height: 600px; overflow-y: auto; padding: 5px;";
|
||||
} ?>" class="row">
|
||||
<div id="tasksdispdiv" class="row<?php
|
||||
if ($pageid != "mytasks") {
|
||||
echo ' home-list-container"';
|
||||
}
|
||||
?>">
|
||||
<?php
|
||||
include __DIR__ . '/../lib/gettasks.php';
|
||||
?>
|
||||
</div>
|
||||
<br />
|
||||
<script>
|
||||
<script nonce="<?php echo $SECURE_NONCE; ?>">
|
||||
function refreshTasks() {
|
||||
$.get('lib/gettasks.php<?php if ($pageid == "mytasks") {
|
||||
echo "?alone=1";
|
||||
|
@ -7,17 +7,17 @@ redirectifnotloggedin();
|
||||
<div class="well well-sm">
|
||||
<a href="app.php?page=edittask" class="btn btn-primary"><i class="fa fa-plus"></i> <?php lang("new task") ?></a>
|
||||
</div>
|
||||
<div id="tasksdispdiv" style="<?php
|
||||
<div id="tasksdispdiv" class="row<?php
|
||||
if ($pageid != "taskman") {
|
||||
echo "max-height: 600px; overflow-y: auto; padding: 5px;";
|
||||
echo ' home-list-container"';
|
||||
}
|
||||
?>" class="row">
|
||||
?>">
|
||||
<?php
|
||||
include __DIR__ . '/../lib/gettaskman.php';
|
||||
?>
|
||||
</div>
|
||||
<br />
|
||||
<script>
|
||||
<script nonce="<?php echo $SECURE_NONCE; ?>">
|
||||
function refreshTasks() {
|
||||
$.get('lib/gettaskman.php<?php
|
||||
if ($pageid == "taskman") {
|
||||
|
45
required.php
45
required.php
@ -10,6 +10,11 @@ header('Content-Type: text/html; charset=utf-8');
|
||||
// l33t $ecurity h4x
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
header('X-XSS-Protection: 1; mode=block');
|
||||
header('X-Powered-By: PHP'); // no versions makes it harder to find vulns
|
||||
header('X-Frame-Options: "DENY"');
|
||||
header('Referrer-Policy: "no-referrer, strict-origin-when-cross-origin"');
|
||||
$SECURE_NONCE = base64_encode(random_bytes(8));
|
||||
|
||||
$session_length = 60 * 60; // 1 hour
|
||||
session_set_cookie_params($session_length, "/", null, false, false);
|
||||
|
||||
@ -17,6 +22,30 @@ session_start(); // stick some cookies in it
|
||||
// renew session cookie
|
||||
setcookie(session_name(), session_id(), time() + $session_length);
|
||||
|
||||
if ($_SESSION['mobile'] === TRUE) {
|
||||
header("Content-Security-Policy: "
|
||||
. "default-src 'self';"
|
||||
. "object-src 'none'; "
|
||||
. "img-src * data:; "
|
||||
. "media-src 'self'; "
|
||||
. "frame-src 'none'; "
|
||||
. "font-src 'self'; "
|
||||
. "connect-src *; "
|
||||
. "style-src 'self' 'unsafe-inline'; "
|
||||
. "script-src 'self' 'unsafe-inline'");
|
||||
} else {
|
||||
header("Content-Security-Policy: "
|
||||
. "default-src 'self';"
|
||||
. "object-src 'none'; "
|
||||
. "img-src * data:; "
|
||||
. "media-src 'self'; "
|
||||
. "frame-src 'none'; "
|
||||
. "font-src 'self'; "
|
||||
. "connect-src *; "
|
||||
. "style-src 'self' 'nonce-$SECURE_NONCE'; "
|
||||
. "script-src 'self' 'nonce-$SECURE_NONCE'");
|
||||
}
|
||||
|
||||
// Composer
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
@ -32,7 +61,21 @@ require __DIR__ . '/lang/' . LANGUAGE . ".php";
|
||||
* @param string $error error message
|
||||
*/
|
||||
function sendError($error) {
|
||||
die("<!DOCTYPE html><html><head><title>Error</title></head><body><h1 style='color: red; font-family: sans-serif; font-size:100%;'>" . htmlspecialchars($error) . "</h1></body></html>");
|
||||
global $SECURE_NONCE;
|
||||
die("<!DOCTYPE html>"
|
||||
. "<meta charset=\"UTF-8\">"
|
||||
. "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"
|
||||
. "<title>Error</title>"
|
||||
. "<style nonce=\"" . $SECURE_NONCE . "\">"
|
||||
. "h1 {color: red; font-family: sans-serif; font-size: 20px; margin-bottom: 0px;} "
|
||||
. "h2 {font-family: sans-serif; font-size: 16px;} "
|
||||
. "p {font-family: monospace; font-size: 14px; width: 100%; wrap-style: break-word;} "
|
||||
. "i {font-size: 12px;}"
|
||||
. "</style>"
|
||||
. "<h1>A fatal application error has occurred.</h1>"
|
||||
. "<i>(This isn't your fault.)</i>"
|
||||
. "<h2>Details:</h2>"
|
||||
. "<p>". htmlspecialchars($error) . "</p>");
|
||||
}
|
||||
|
||||
date_default_timezone_set(TIMEZONE);
|
||||
|
@ -9,6 +9,65 @@
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
.navbar-brand img {
|
||||
height: 35px;
|
||||
padding-bottom: 12px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.pad-75px {
|
||||
height: 75px;
|
||||
}
|
||||
|
||||
.mgn-btm-10px {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.mgn-top-8px {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.black-text {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.msgdelform {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.inblock {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.padleft-5px {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.height-52px {
|
||||
height: 52px;
|
||||
}
|
||||
|
||||
.mgn-btm-5px {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.padright-0px {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
#msgsendbtn {
|
||||
border-top-left-radius: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.home-list-container {
|
||||
max-height: 600px;
|
||||
overflow-y: auto;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10em;
|
||||
text-align: center;
|
||||
|
@ -23,3 +23,30 @@ var options = {
|
||||
};
|
||||
|
||||
$("#msgtobox").easyAutocomplete(options);
|
||||
|
||||
function refreshMsgs() {
|
||||
$.get('lib/getmsgs.php', function (data) {
|
||||
$('#messagedispdiv').html(data);
|
||||
setupTooltips();
|
||||
});
|
||||
}
|
||||
|
||||
setInterval(function () {
|
||||
refreshMsgs();
|
||||
}, 10 * 1000);
|
||||
|
||||
$(".msgdelform").on("submit", function () {
|
||||
var msgid = $(this).data("msgid");
|
||||
$('#delmsgbtn' + msgid).prop('disabled', true);
|
||||
setTimeout(function () {
|
||||
refreshMsgs();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
$("#msgsendform").on("submit", function () {
|
||||
setTimeout(function () {
|
||||
$('#msgsendbox').val('');
|
||||
$('#msgtobox').val('');
|
||||
refreshMsgs();
|
||||
}, 100);
|
||||
});
|
3
static/js/taskman.js
Normal file
3
static/js/taskman.js
Normal file
@ -0,0 +1,3 @@
|
||||
$('.deltaskform').on("submit", function () {
|
||||
$("#deltaskbtn" + $(this).data("taskid")).prop("disabled", true);
|
||||
});
|
21
static/js/tasks.js
Normal file
21
static/js/tasks.js
Normal file
@ -0,0 +1,21 @@
|
||||
$("#tasksdispdiv").on("click", ".task-btn", function () {
|
||||
var taskid = $(this).data("taskid");
|
||||
var action = $(this).data("action");
|
||||
switch (action) {
|
||||
case "start":
|
||||
break;
|
||||
case "finish":
|
||||
break;
|
||||
case "pause":
|
||||
break;
|
||||
case "problem":
|
||||
break;
|
||||
case "resume":
|
||||
break;
|
||||
default:
|
||||
// Not a valid action code
|
||||
return;
|
||||
}
|
||||
$("#" + action + "taskbtn" + taskid).prop("disabled", true);
|
||||
refreshTasksSoon();
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user