Globally deny access to website for update, Laravel - php

This is a fairly open question as i am not sure what the best practice could/should be for this type of activity.
The scenario; A user based website (with logged in user areas and user editable content) needs to have several operations performed that will manipulate live data. To stop any errors occurring due to users simultaneously editing as the update is taking place, i need to shut out the users temporarily.
I don't currently have a config database table, just a config file. Two things need to happen;
An update to the config happens to stop the users accessing certain areas of the website during the update - this is then reverted once the update is complete.
The website (or at least portions on the site) need to be checked before every request for said portions of the site - so whatever the method, it needs to be lightweight
This is site built on Laravel.
Thanks!

There is a simple artisan command for that. Use this to shut down the application:
php artisan down
And this to turn it back on:
php artisan up

I'll use serveral measures in this case.
put the code in try - catch block so that if something goes wrong, you can grcefully show an error message.
If there are mulitple executions invovled, then better use DB::transaction() and the system will roll back automatically if it encounters an error.
If you really want to put certain features on maintence mode, then put those routes in Route::group() and use a middleware for that group only. In that middleware, return response with 503 status. This way, you can put certain routes into maintanace mode while the rest will give 200 ok response.

Related

retrieve user->ID from wordpress to aanother php site

I have a PHP application custom_appli in /var/www/httpdocs.
Wordpress is installed on the same server in /var/www/httpdocs/new_cms/wordpress.
I need to retrieve user->ID using SESSION of custom_appli.
I have tried to insert :
require( './new_cms/wp-snapshots/wp-blog-header.php' );
global $user;
$user = wp_get_current_user();
echo "ID :".$user->ID;
writing wp-load instead of wp-blog-header doesn't change anything no matter whether I use include or require_once.
Could you please give me a link or advice on how to obtain user from SESSION?
Thanks in advance
Details and info are sparse, but here's how I would do it (I know about 5 methods, these are the least painful):
As mentioned, wp_get_current_user() gets you close, but that is generally only usable on the page for the user as in "on load" only. So from the WP served page you can get user ID (and all other info) and the session and have something that is usable. There are many ways to use that data to solve your problem, not really smooth all the time. Session data is etherial, beware.
Another way to go about it is to use wp-load.php and wrap it in middleware. this script bootstraps WP and allows queries and similar in the "bootstrapped" wordpress environment providing the applications internal API. I would consider adding wp-load to custom_appli "in the right way" and use that as middleware between the 2 applications. You will still need to identify the user as in many cases.
Without more information it is hard to guide you, but I can tell by your needs and the code already in the post that you are setting up for possible problems with dependencies, possible name-spacing collisions($user is something that could bite you as a global), and a myriad of other ways to loose time. If custom_appli needs a user ID, send it the user from WP on page load or similar.
When/why do you need that info? What is the flow?
You can also traverse a lot via session ID info too (depending on configuration).
FWIW I have passed user information successfully from 2 freestanding applications on different servers, it was very hard to do correctly, but it is possible.
Update after clarification
As mentioned "wordpress-user and cusstom-appli have same users" is possibly a replication of functionality, specifically running 2 tables(?) or logic. Just some feedback.
Basically you are wanting to hook the "logged in" status of a WP user. I see no mention of:
FK/relationships built on user (easy but a little more work)
ACL/permission based access on custom appl
No serializing of data or similar to the WP user (user in general)
Any of the above might have me change the solution. Here is a pretty clean prototype I wrote for you that is about 15 lines of code.
It follows some code from wp and essentially:
Makes sure PHP session is initialized via the theme functions.php
Uses the WP login (authentication) success to add a var to the session
On logout unsets the var (!IMPORTANT!)
Also makes sure the session is set when not logged in or the key is not present
Is easy to pick up outside of WP via session (custom_appl.php)
I tested this and it worked fine locally on one of my installs, I don't see any reason why it would give you problems. I would harden this a little more, but this is only a prototype showing how to use the key tools in PHP and WP.
wp_get_current_user() is a function in wp-includes/pluggable.php, which is loaded by wp-settings.php. I'm not sure how exactly WordPress bootstraps itself but I'd try to include wp-settings.php if anything.

Is it possible to track who used a php script I created and how often? What is the best way to go about this?

I built a PHP script to help my team in work carry out a task more efficiently. It is not compulsory that they use it and they can still use the manual method. The script is located in a global location that is accessible for everyone to use, is it possible I can track usage by user so I can show the impact of the script? What would be the best way to do this?
I assume I could check who's logged into the script via command line and output the name and increment a counter once the script completes? Is there some better way?
Thanks
If its on global location (ie public computer), there is no such simple way. There is no any if you ask me due to a many reasons (ie due to sharing informations mouth-to-mouth).
However, I have been using acces code(s) (simple phrase, or few digits number - per user) for me to know if some specific user has read some data/documents or not - online, on www. With no registration at all, from its own home!
Table should go like this:
id | name_of_mysterious_worker | email | access_code
Page at first loaded completly blank with input form to enter access form. When (and if) "mysterious" user entered his/her code, script launched (page opened), acces code went into DB and.. I expected that he/her read data or documents. I even knew exact time and location from where user accessed documents.
Note: user could not read/use anything without acces code if you follow me.
This is especially effective if some authcode is sent via url as email to workers. Ie http://ourcompany.com/index.php?email=workers_email&acces=ioa897u3u0120912
If you trust to your workers, you can add simple form field for them to simply enter their name during using script what would be easiest to program.
If that shall not be a case, some "usersystem" should be developed within script, at least one I just described.

Create server log

I am working on a rather large website and i need to log errors that users may face while using the website.
Here is how it will work:
>if operation passed
#operation success
>else
#Log the failure
log()
>email admin
>create log
What i need to know is the best practice for creating this log, because there are several methods for doing this.
text based
database
There is possibly a better method for doing this as well, which is why i'm asking stack overflow.
Just tell me how you would go about doing this, and i will do the rest of the research and coding on my own.
I find using a 3rd party service like airbrake.io or pagerduty.com is best. Basically, they handle creating a ticket and logging everything as well as notifying the proper people about the incident. Yes, you can write up your own system the way you mention via emailing an admin and creating your own logs... but then you will also have to worry about updating the email list and emailing the right people at the right time... What if you're on vacation? Who is to get the email at that point? 3rd party services manage all that for you.
You can use (and probably should use) open source logging frameworks for the language you are working in. They will provide you with nice wrappers for all your logging needs, most have the option to email logs to you (and even upload files to remote directories).
If you wish to create your own logging system, this is how I would personally do it:
Make a log directory
Create a log file (plain text) each hour (or day or X units of time) using a naming scheme
Write 1 line to the file with the time, then some delimiter, then the error (including error codes/messages etc)
Every time an hour or day passes, you would make a new file and email the previous file to yourself (or admin). You can also send an immediate email for fatal errors/issues. I wouldn't really use a database personally.
I implemented such a logging system for a online script that talks to a gaming server. The end result is a directory of files filled with logs for each hour of each day. Files older than 30 days are also deleted. It allows me to check on how things are going easily and pinpoint certain events/issues that players on the game server experience. However, I only wrote my own logger as there was no script that did this for my game.
First of all, since it was mentioned in the comments, we should differntiate the php error log from a custom application log:
The php error log logs errors of a certain level (notices, errors, warnings depending on your error_reporting() settings) while interpreting your php files. That means when you are trying to use an array key which was not set before a warning would be generated and either printed to the screen or logged to your php error log file.
A custom application logger on the other side logs custom messages which might contain warnings and errors regarding the application logic and which are able to be handled by the application.
When we compare the following two code examples:
<?php
error_reporting(E_ALL|E_STRICT);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', sys_get_temp_dir() . '/php_error.log');
updateUser($_POST['user_id']);
// Assuming $_POST['user_id'] was not set the above lines would produce a notice in your php_error.log stating the use of an undefined index 'user_id'
?>
Against:
// Instantiate your own logger or a 3rd party logger
$myLogger = new Logger(sys_get_temp_dir() . '/application.log');
if (!array_key_exists('user_id', $_POST)) {
$myLogger->error('Cannot update user since user_id was not set');
// Handle the error in the UI accordingly
header('Location: 404.php');
die();
}
updateUser($_POST['user_id']);
?>
For me personally it makes sense to separate these two types of errors in different log files: The php errors are usually a result of code which does not handle all imaginable cases (i.e. a user removes the hidden user_id field from a form manually) and are a hint for yourself that you should change your code to avoid the same error next time.
The second piece of code handles the exactly same use case but you considered this case while writing the code and the application is able to react somehow.
No matter if you decide pick a 3rd party logger or write your own: Think about using one which fulfils the PRS-3 logging standard to be able to make it exchangable when you i.e. decide to switch from file based logging to a database based logging mechanism. By doing so you won't have to change a lot of code when you decide to switch your loggers since the methods and general usage is standardised.
When writing your own logger, consider the following points:
Locking and unlocking your log file while writing to it
Log rotation (daily, weekly, monthly)
Deletion of old log files
Like stated above think about implementing PSR-3

Laravel application very slow when connecting to the database

Note: Now that I know where the issue comes from, I modified the question. It now contains only the information needed.
I'm new to the Laravel PHP framework.
I have a very small app working on my computer. It is connected to a MySQL database and has a User model. I use the Auth class to log in and out.
Everything works fine, but when I am logged in, loading a page takes about a second which is very slow. When I'm not logged in, it's a matter of milliseconds.
By using the built-in profiler, I realized two problems. First, like I said, loading a page takes a bit more than 1000 milliseconds. Second, the framework makes one SQL every time I load a page when I'm logged in. The query searches a user with a certain id (my id). I guess it is there to get information about the logged in user. But isn't there supposed to be some sort of cache. Will this be a problem if my website will have to manage many requests per seconds.
I realized that using Auth::check() in the view is what is causing the issue. I have around 4 Auth::check() is my Blade view. When I have none, it goes fast. If I have one, it is slow. Then, no matter how many I have, it doesn't get much slower. It's like if the Auth class' initialization takes too much time or something like that. I guess it explains why it only happens when I'm logged in.
I dived into Laravel's code and I found out that when Auth::check() is called for the first time, the Auth class needs to "activate" my Session by retrieving the user's info from the database. That explains the query being executed every page request. But since the profiler says that the query doesn't even take a millisecond to execute, I still don't know why it slows down the app.
New information: Even when I'm not sending a query to the database, the simple act of connecting to it takes almost a second. This is the reason it is slow. I think I'm getting really close to solve the issue.
Any idea so far?
Thanks in advance.
Notes
The fact that Auth::check() is in the view doesn't change anything.
Using another method like Auth::guest() doesn't solve the issue.
New: Connecting to the database is what is slow.
I finally found a way to fix this.
When reading some posts on many forums about XAMPP, MySQL, and PHP, and I read somewhere that it is preferable to use 127.0.0.1 because locahost needs an extra DNS lookup.
In the database configuration file, I simply changed locahost for 127.0.0.1.
Now everything is fast.
I find this really strange. Using locahost in the configuration file used to make the database connection take more than a second!
I do not agree with Hammo's example. Having any user information other than their ID within the session is a security risk, which is why most frameworks take this route. Is there anything else being run when the user is logged in, apart from the query for their record? It's definitely not that that's slowing your application down.

Best way to allow user to inject and run php code

I've been thinking for a while about the idea of allowing user to inject code on website and run it on a web server. It's not a new idea - many websites allow users to "test" their code online - such as http://ideone.com/.
For example: Let's say that we have a form containing <textarea> element in which that user enters his piece of code and then submits it. Server reads POST data, saves as PHP file and require()s it while being surrounded by ob_*() output buffering handlers. Captured output is presented to end user.
My question is: how to do it properly? Things that we should take into account [and possible solutions]:
security, user is not allowed to do anything evil,
php.ini's disable_functions
stability, user is not allowed to kill webserver submitting while(true){},
set_time_limit()
performance, server returns answer in an acceptable time,
control, user can do anything that matches previous points.
I would prefer PHP-oriented answers, but general approach is also welcome. Thank you in advance.
I would think about this problem one level higher, above and outside of the web server. Have a very unprivileged, jailed, chroot'ed standalone process for running these uploaded PHP scripts, then it doesn't matter what PHP functions are enabled or not, they will fail based on permissions and lack of access.
Have a parent process that monitors how long the above mentioned "worker" process has been running, if its been too long, kill it, and report back a timeout error to the end user.
Obviously there are many implementation details to work out as to how to run this system asynchronously outside of the browser request, but I think it would provide a pretty secure way to run your untrusted PHP scripts.
Wouldn't disabling functions in your server's ini file limit some of the functions of the application itself?
I think you have to do some hardcore sanitization on the POST data and strip "illegal" code there. I think doing that with the addition of the other methods you describe might make it work.
Just remember. Sanitize the everloving daylight out of that POST data.

Categories