diff --git a/.htaccess b/.htaccess
index 032e40ad1..0faa952da 100644
--- a/.htaccess
+++ b/.htaccess
@@ -35,6 +35,11 @@ RewriteRule ^(.*) public/$1 [L]
+ # if you want to prevent your site from being embedded into other sites via an iframe (sometimes used for scam), then
+ # simply uncomment these lines below. you need to have apache rewrite headers activated, usually via
+ # "a2enmod rewrite headers" on the command line
+ #Header set X-Frame-Options Deny
+ #Header always append X-Frame-Options SAMEORIGIN
Header set Cache-Control "max-age=2592000, public"
@@ -44,4 +49,4 @@ RewriteRule ^(.*) public/$1 [L]
Header set Cache-Control "max-age=216000, private"
-
+
\ No newline at end of file
diff --git a/README.md b/README.md
index a11a14c94..0e397727c 100644
--- a/README.md
+++ b/README.md
@@ -68,7 +68,9 @@ Chris
- [Quick Installation](#quick-installation)
- [Detailed Installation](#detailed-installation)
- [NGINX setup](#nginx-setup)
-+ [Documentation](#documentation)
++ [Documentation](#documentation)
+ - [How to use the user roles](#user_roles)
+ - [How to use the CSRF feature](#csrf)
+ [Community-provided features & feature discussions](#community)
+ [Future of the project, announcing soft EOL](#future)
+ [Why is there no support forum anymore ?](#why-no-support-forum)
@@ -374,7 +376,7 @@ doing this for free in our free time :)
- TODO: Full documentation
- TODO: Basic examples on how to do things
-#### The different user roles
+#### How to use the different user roles
Currently there are two types of users: Normal users and admins. There are exactly the same, but...
@@ -393,7 +395,7 @@ There's also a very interesting [pull request adding user roles and user permiss
which is not integrated into the project as it's too advanced and complex. But, this might be exactly what you need,
feel free to try.
-#### An introduction into the CSRF features
+#### How to use the CSRF feature
To prevent [CSRF attacks](https://en.wikipedia.org/wiki/Cross-site_request_forgery), HUGE does this in the most common
way, by using a security *token* when the user submits critical forms. This means: When PHP renders a form for the user,
@@ -405,6 +407,18 @@ This CSRF prevention feature is currently implemented on the login form process
and user name change form process (see *application/view/user/editUsername.php*), most other forms are not security-
critical and should stay as simple as possible.
+So, to do this with a normal form, simply: At your form, before the submit button put:
+``
+Then, in the controller action validate the CSRF token submitted with the form by doing:
+```
+// check if csrf token is valid
+if (!Csrf::isTokenValid()) {
+ LoginModel::logout();
+ Redirect::home();
+ exit();
+}
+```
+
A big thanks to OmarElGabry for implementing this!
#### Can a user be logged in from multiple devices ?
diff --git a/application/controller/LoginController.php b/application/controller/LoginController.php
index 4cea26b31..f1ab4c517 100644
--- a/application/controller/LoginController.php
+++ b/application/controller/LoginController.php
@@ -35,10 +35,11 @@ public function index()
*/
public function login()
{
-
// check if csrf token is valid
if (!Csrf::isTokenValid()) {
- self::logout();
+ LoginModel::logout();
+ Redirect::home();
+ exit();
}
// perform the login method, put result (true or false) into $login_successful
diff --git a/application/core/Csrf.php b/application/core/Csrf.php
index bd0b7bf1e..f2064c8e3 100644
--- a/application/core/Csrf.php
+++ b/application/core/Csrf.php
@@ -12,10 +12,14 @@
*
*
* This validation needed in the controller action method to validate CSRF token submitted with the form:
+ *
* if (!Csrf::isTokenValid()) {
- * Login::logout();
- * }
- * And that's all
+ * LoginModel::logout();
+ * Redirect::home();
+ * exit();
+ * }
+ *
+ * To get simpler code it might be better to put the logout, redirect, exit into an own (static) method.
*/
class Csrf {
@@ -26,9 +30,10 @@ class Csrf {
* @static static method
* @return string
*/
- public static function makeToken() {
-
- $max_time = 60 * 60 * 24; // token is valid for 1 day
+ public static function makeToken()
+ {
+ // token is valid for 1 day
+ $max_time = 60 * 60 * 24;
$stored_time = Session::get('csrf_token_time');
$csrf_token = Session::get('csrf_token');
@@ -47,7 +52,8 @@ public static function makeToken() {
* @static static method
* @return bool
*/
- public static function isTokenValid(){
+ public static function isTokenValid()
+ {
$token = Request::post('csrf_token');
return $token === Session::get('csrf_token') && !empty($token);
}
diff --git a/application/core/DatabaseFactory.php b/application/core/DatabaseFactory.php
index e868d2441..417972c77 100644
--- a/application/core/DatabaseFactory.php
+++ b/application/core/DatabaseFactory.php
@@ -21,26 +21,44 @@
*/
class DatabaseFactory
{
- private static $factory;
- private $database;
+ private static $factory;
+ private $database;
- public static function getFactory()
- {
- if (!self::$factory) {
- self::$factory = new DatabaseFactory();
- }
- return self::$factory;
- }
+ public static function getFactory()
+ {
+ if (!self::$factory) {
+ self::$factory = new DatabaseFactory();
+ }
+ return self::$factory;
+ }
- public function getConnection() {
- if (!$this->database) {
- $options = array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ, PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING);
- $this->database = new PDO(
- Config::get('DB_TYPE') . ':host=' . Config::get('DB_HOST') . ';dbname=' .
- Config::get('DB_NAME') . ';port=' . Config::get('DB_PORT') . ';charset=' . Config::get('DB_CHARSET'),
- Config::get('DB_USER'), Config::get('DB_PASS'), $options
- );
- }
- return $this->database;
- }
-}
\ No newline at end of file
+ public function getConnection() {
+ if (!$this->database) {
+
+ /**
+ * Check DB connection in try/catch block. Also when PDO is not constructed properly,
+ * prevent to exposing database host, username and password in plain text as:
+ * PDO->__construct('mysql:host=127....', 'root', '12345678', Array)
+ * by throwing custom error message
+ */
+ try {
+ $options = array(PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ, PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING);
+ $this->database = new PDO(
+ Config::get('DB_TYPE') . ':host=' . Config::get('DB_HOST') . ';dbname=' .
+ Config::get('DB_NAME') . ';port=' . Config::get('DB_PORT') . ';charset=' . Config::get('DB_CHARSET'),
+ Config::get('DB_USER'), Config::get('DB_PASS'), $options
+ );
+ } catch (PDOException $e) {
+
+ // Echo custom message. Echo error code gives you some info.
+ echo 'Database connection can not be estabilished. Please try again later.' . ' ';
+ echo 'Error code: ' . $e->getCode();
+
+ // Stop application :(
+ // No connection, reached limit connections etc. so no point to keep it running
+ exit;
+ }
+ }
+ return $this->database;
+ }
+}
diff --git a/application/core/Text.php b/application/core/Text.php
index 80ac3e5ea..f6a5d083d 100644
--- a/application/core/Text.php
+++ b/application/core/Text.php
@@ -4,13 +4,17 @@ class Text
{
private static $texts;
- public static function get($key)
+ public static function get($key, $data=NULL)
{
// if not $key
if (!$key) {
return null;
}
-
+ if ($data) {
+ foreach ($data as $var => $value) {
+ ${$var} = $value;
+ }
+ }
// load config file (this is only done once per application lifecycle)
if (!self::$texts) {
self::$texts = require('../application/config/texts.php');