I am trying to separate an tangled mess of PHP and JS. I'm not looking for perfection in the first draft but anything is better than the current state.
Current (all in one file):
<?php if( checkSecureUserStuff ): ?>
//bunch of js like including admin features
//not fun stuff
<?php endif; ?>
Proposed:
PHP file
if( checkSecureUserStuff ){
$userAccess = 'admin';
}
...
//Later in file, I know this still not ideal
<script>
var useraccess = <?= json_encode($userAccess) ?>;
</script>
JS file
if( useraccess == 'admin' ){
// do the admin related JS stuff here
}
Obviously in the final HTML var useraccess = 'admin'; will be visible. Is it open to manipulation at that point? I know this design isn't great, but is it terribly insecure?
Oh yea, I should mention. Actions are still checked on the server. This is more about securing the UI and keeping certain stuff disabled. The server would still verify actions.
I guess the question is more about can a user manipulate the UI if the variables are set and checked on document load. Already partially answered by millerbr's mention of setting break points
. Didn't think of that
Yes. The user will be able to open their browser console, view the code, pause it at a breakpoint they have set, and then write code in the console to edit the variable.
You should never trust your frontend for security type things - yes, write code to limit access, but always double-check on your backend and assume any requests are insecure.
There are things you can do to obscure your code and make it more difficult to manipulate, such as minifying the code, but nothing is 100% effective and so you should always assume the frontend is compromised and place the necessary precautions on any incoming data or requests.
Related
First a little bit about me because it might help:
I am NOT a professional coder, I write HTML and CSS by hand with notepad++ because i like the lightweight and effective code + I have total control and clue of what is going on in my files/website.
I don't like WP. Its too much hassle and yes i know it's "easier" but since I know nothing about php, except that it's a server side language, it's not easier for me to get the look of the website that I want with it. (recently I found out I can INCLUDE a part(s).html in actual.html and compose actual.html - not up for that right now as it makes a new connection for each part.html (when i get to more complex web-developing, as my sites are static, etc...)) Tried multiple times, ended up deleting everything and writing my own code from scratch. I don't like to learn the (php) code from WP editing (extremely time-consuming and messy), I prefer learning it by using the code when i need it. That's how i remember and learn. That's how I learned C#.
I like one-file type of web pages as they are pretty much static. Any pics that i might use i DON'T create any links, I convert them in base64 and paste the code where i need it. So as minimalistic as possible with fewer requests as possible with least kb as possible - but resemble WP by look and behavior (responsivness).
I reserve one request for style.css and one for favicon.ico; #1 it's neater, #2 can't be base64-ed nor CSS loaded.
Anyway, a php contact form that I used in one of my sites was working perfectly, with just contact.php file on the server and a little bit of js in html. Therefore i ASSUME that fetching user data such as IP, time of access, screen resolution and OS would be easy similarly as the contact form was.
What I would like to know is next:
fetch device.useragent + device.resolution + time + IP;
write fetched to log.txt
Then i ftp the log.txt to my pc and investigate.
Thank you for reading and considering to help :)
The user agent, time, and IP address can be stored in variables as follows:
$userAgent = $_SERVER['HTTP_USER_AGENT'];
$time = date('Y-m-d H:i:s');
$ip = $_SERVER['REMOTE_ADDR'];
For resolution, you'd have to determine it with JavaScript and send it to the server with an AJAX request or as part of the request body. All of this can then be written to a log.txt file using file_put_contents('path/to/log.txt', $data);.
Note, that there are usually simpler ways of achieving this if using a framework (e.g. Symfony, Laravel, Zend), or there may even be a plugin for your CMS of choice.
Check this post, PHP's get_browser, and also this post is very helpful. For the resolution, like Sheraz said, you need JS or any JS library that can read the device resolution. If you want to use jQuery, check this post. To fetch user time of access, you can create a $_SESSION variable and use time. For the ip, check this. And for file handling, fopen, file_get_contents, file_put_contents and fclose will help you.
I need to print this variable:
{$array}
And i have this code:
<script type="text/javascript">
function write() {
writing = document.getElementById('box_user');
if(writing.innerHTML == ""){
writing.innerHTML = "{$array}";
}else{
writing.innerHTML = "";
}
}
</script>
When I click here, i dont get the result of the variable:
<td><button name="ver" onclick="write()"></td>
And the result must be here:
<div class="col-lg-12" id="box_user">
</div>
Content of variable:
while($array = mysqli_fetch_assoc($resultado)){
if($tabla1 == ""){
$tabla1 = "<table>
<thead>
<tr>
<td><strong>ID Formador</strong></td>
<td><strong>Nombre</strong></td>
<td><strong>Apellidos</strong></td>
<td><strong>Email</strong></td>
<td><strong>Teléfono</strong></td>
<td><strong>DNI</strong></td>
</tr>
<tr>
<td><strong>".$array['ofca_idFormador']."</strong></td>
<td><strong>".$array['daco_nombre']."</strong></td>
<td><strong>".$array['daco_apellido1']." ".$array['daco_appelido2']."</strong></td>
<td><strong>".$array['usrs_mail']."</strong></td>
<td><strong>".$array['daco_telefono']."</strong></td>
<td><strong>".$array['daco_dni']."</strong></td>
</tr>";
}else{
$tabla1 .= "<tr>
<td><strong>".$array['ofca_idFormador']."</strong></td>
<td><strong>".$array['daco_nombre']."</strong></td>
<td><strong>".$array['daco_apellido1']." ".$array['daco_appelido2']."</strong></td>
<td><strong>".$array['usrs_mail']."</strong></td>
<td><strong>".$array['daco_telefono']."</strong></td>
<td><strong>".$array['daco_dni']."</strong></td>
</tr>";
}
}
$tabla1 .= "</thead></table>";
I'm using a .tpl and all of controllers a model work great the problem is here.
I´m starting on smarty, this is my first project.
I'm not hugely familiar with Smarty, but I've done some PHP in my day, and I'll take a shot at an answer here. Forgive me if this answer is overly simplistic and sounds unnecessarily patronizing; I'm going to answer in a way that even a beginner could understand, since I don't know your skill level or familiarity with these concepts.
The main problem you're having has to do with the separation between the server and the client. PHP is a server-side language; JavaScript and HTML are client-side. The server is what hosts your website for the client, usually your web browser, to request and read.
The interaction usually goes something like this: your browser asks the server for a certain webpage, the server does some stuff to build that webpage up from the templates, and the server hands the completed webpage to your browser. From that point on, the server no longer has any access to your webpage, and server-side code won't do anything, because your browser doesn't know what it means, so if any server-side code is left as part of the webpage, it's just going to be rendered directly as text. Your browser does understand client-side code, however, and that will still work just fine.
Of course, sometimes you need information from the server after the page has loaded. The way your client-side code running in the browser gets new data from the server is generally through AJAX requests; essentially, the browser talks to the server again and asks for some data, the server again runs some server-side code to build up the data you're asking for, and it hands it back to the browser. This usually won't be in the form of another webpage, but will instead be in a data format like JSON or XML, which your client-side code can then process and use to add content to the page. But notice that the server-side code never touches the page; all it does is hand over some data that the client-side code can use to update the page.
If you're familiar with C and similar languages, think of PHP-style templates as preprocessor code. The preprocessor code can, in effect, add and remove sections of the C code at compile time, but once the build is complete, that preprocessor code doesn't exist anymore, and the preprocessor can't do anything at runtime; at that point it's all C. Similarly, PHP can build up client-side code, generate bits of HTML or JavaScript, etc., but once that page is handed off to the browser, PHP doesn't exist anymore as far as that page is concerned.
Based on the code I'm reading above, I think you have two options, depending on what you're trying to do. I can't quite tell whether you mean for that table code to be generated dynamically at runtime when the user requests it, based on some user input, or whether the table exists completely and is just waiting to be displayed.
If the table code already exists, I recommend moving it out of a PHP variable and into the page. If you don't want it to show immediately, you should use CSS to hide it initially and use that button click function to show it, something like this (assuming the Bootstrap .invisible class based on some other Bootstrap classes you used):
<div class="col-lg-12" id="box_user">
<div id="table-wrapper" class="invisible">{$tabla1}</div>
</div>
<script>
function write(){
document.getElementById('table-wrapper').classList.remove('invisible');
}
</script>
If you need to dynamically generate the table based on some user-generated info and MySQL queries, which it looks like you're using, then you have a little extra work to do. You need to look into how to set up a REST interface for your server, whether through PHP or something else, and you need to look into how to make AJAX calls. You should return data from the server as a JSON object, then convert that PHP code you're using to generate the table into a JavaScript function and pass in the JSON you get back.
Hope that helps! Please feel free to ask for any clarification you might need.
Ok, this could seem a little bit confusing, but the idea is next:
Normal PHP page which receives POST calls, and considering those vars acts in some or other ways. No problem, normal thing.
Some of the aspects which are loaded in this page (info blocks which get some big data from database), independently of POST vars and whatever, take long time to load, so I've decided to dynamically load them, instead of loading everything on loading page time. This means that in the beginning page was rendering and taking so long and right now, it renders fasts and shows some "loading..." blocks with spinning icon on them. Those blocks are basically "$.ajax" calls via POST, once $(document).ready();. Ok? No probe here too. All ok.
And now the problem: some of those blocks shows one or other info accordingly to $_POST received vars. Once this wasn't AJAX, everything worked right. But now, the received from server processed page (which already used the POST vars) to the client, makes new post calls to particular scripts and those scripts doesn't have the PHP POST needed vars.
Obviously you could say do something like:
$.ajax{
...
data: <?php ..............?>
...
}
but I can't, as this is a JS file, none PHP with embedded JS on it.
So the question is:
What can I do?
Which would be a good implementation for this particular solution?
It is not a design fault, as it works nice if it doesn't uses ajax. This is not a previous ajax call that can be made on request call. It is basically loading some page parts dynamically on serving time!
So what?
Thank everyone so much, and I hope you can help me whit it!
PS: I've came up with an idea, and it is basically, before load the main JS file, to create a petite snippet which basically transforms $_POST array to a JS object with all the bars in it. But even being it useful and probably great, I guess it basically fucks up security and obfuscation a lot!
There are numerous options. As you mention, you can pass the data to the client via inline js or dsata attributes, then post the data back in the ajax calls.
This will work fine, but if you have security concerns, then the alternative is to persist the data serverside, and change the php scripts retrieval method:
//main.php - the file that initially loads:
session_start();
$_SESSION['post']=$_POST;
//rest of script
//sidebar.php - the file called by ajax
session_start();
if(!$_POST){
if(isset($_SESSION['post']){
$_POST = $_SESSION['post'];
}
}
//rest of script
This is what I've finally came about:
Changed the "main.js" file to "main.php" file.
On header, changed the to require_once ".../js/main.php"
Now you have all the code block on header, but somehow I guess it's exactly the same?
Now I can put PHP code on """JS""" main file. And right now I can do something like:
var data = [];
//Controlled parameters which sure I'll have and always will add manually.
data.push({ name: "ajax", value: action }); //add more parameters...
data.push({ name: "section", value: section });
//Those "others" POST parameters which can vary depending on the request call.
<?php foreach ($_POST as $k=>$v){ ?>
data.push({ name: "<?php echo $k;?>", value: "<?php echo $v;?>" });
<?php } ?>
...
$.ajax({
type: "POST",
url: "?a="+action,
//data: { ajax: action, section: section },
data: $.param(data),
timeout: 8000 //8 seconds max.
}).done(function( data ) {
...
And that's it!
I've started by creating an object in JS on every view which played with this concept of forwarding POST data. But it was "unmaintainable".
Then I thought that could be good to create a JS snipet after main.js inclusion on header precisely with this "object creation POST data", as all the calls are going to be made on $(document).ready(); time, so sure it will be accessible. You know: if it exists use it if not... blah!
But the I thought that it is not necessary to create a POST object in JS all the time, as long as sometimes probably big data is going to be on server-side, so do not want to put it on client to. You delivery this "post" thing to the object and with time, you forget on this and start to put things on POST no-one should see and it happens that you have'em absolutely visible on JS!
So it seem that your proposed options (SESSIONING the POST via "post" var on session array or by ID screening) should be the most secure in this idea of reusing the info only on server side, but I've found it somehow... "tedious to mantain" too.
So I've finally came up with this idea. And as this is only happening on load time AJAX loaded blocks, this JS data is going to happen on very concret situations and parameters are going to be pretty small. Nothing to worry about I guess.
So questions come to my mind:
You like it? Is a good implementation or you think its a better approach to use the "session" thing?
Security compromising?
To add a script on head with src="..." so dinamically add the JS file to webpage, is the same in terms of time and used resources to add the code directly to head tag (which happens when you do a require_once for a PHP file which contains dinamized JS code)?
I need to run this code:
<?PHP
$pin=$_GET["pin"];
unlink("../users/$pin/host.php");
unlink("../users/$pin/votes.php");
unlink("../users/$pin/guest.php");
rmdir("../users/$pin");
echo "Session ended";
?>
Which is located at php/endsesh.php
Basically, when you start a session it creates you a folder with a pin number, and it places a host, guest and votes file.
I need this PHP script to run when the tab is closed, so it can delete all those files (Otherwise I'm just overloading my server with files)
So far I'm trying this with no luck:
<script>
window.onbeforeunload = function() {
alert("<?php include("http://musicdemo.hol.es/php/endsesh.php?pin=" . $_GET["pin"]; ?>");
$.get("http://musicdemo.hol.es/php/endsesh.php?pin=<?php echo $_GET["pin"]; ?>");
return false;
return "If you exit this page your session will not end. Please either allow the pop-up, by staying in this page and closing again, or click the link saying 'Close this session'";
}
</script>
neither the alert or the $.get commands work.
onbeforeunload is a highly secured, sandboxed event. It's really designed solely to catch people with "are you sure you want to close this window" messages, so I'm pretty sure it doesn't allow more advanced features such as an ajax call. To do so would open up security holes that allow malicious sites to prevent you from closing the window.
I think doing an ajax call to clean up server side session files is not the appropriate strategy anyway, since the browser could easily crash, laptop could lose power, user could lose network connectivity preventing the ajax call etc. You can't rely on that ajax call succeeding.
PHP already has very good session handling capabilities via session_start() and the $_SESSION global variable, which already has a built in cleanup feature for expiring old sessions.
If you absolutely must keep your current solution, what I would do is run a cron job every hour, day, week, whatever, that searches for any of your files that haven't been accessed in say 24 hours and deletes them.
Also I should note that taking a $_GET and passing it directly to unlink is one of the worst, most insecure things you can do in php. If you have that running on a server right now, you need to fix it immediately, since a malicious user could potentially do something like http://musicdemo.hol.es/php/endsesh.php?pin=../../../../../../etc/passwd. if 'pin' is a number, you should at least do something like:
<?PHP
$pin=$_GET["pin"];
$pin = (int) $pin; // ensure pin is converted to an integer
unlink("../users/$pin/host.php");
unlink("../users/$pin/votes.php");
unlink("../users/$pin/guest.php");
rmdir("../users/$pin");
echo "Session ended";
?>
This code looks to be incorrect, try:
<script>
window.onbeforeunload = function() {
$.get("http://musicdemo.hol.es/php/endsesh.php?pin=<?php echo $_GET["pin"]?>");
return false;
return "If you exit this page your session will not end. Please either allow the pop-up, by staying in this page and closing again, or click the link saying 'Close this session'";
}
</script>
It looks like your alert line is messing this up.
remove alert().
keep $.get.
Have you seen the apache logs?
Probably you could have a permission problems (chmod +x endsesh.php).
I think i will give a try with exec (http://it2.php.net/function.exec).
But before you have to understand if endsesh.php is reached.
I have created a website for a friend. Because he wished to have a music player continue to play music through page loads, I decided to load content into the page via ajax (facilitated by jQuery). It works fine, it falls back nicely when there is no javascript, and the back/forward buttons are working great, but it's dreadfully slow on the server.
A couple points:
The initial page load is fairly quick. The Chrome developer console tells me that "index.php" loads in about 2.5 seconds. I have it set up so that query string params dictate which page is loaded, and this time frame is approximately accurate for them all. For the homepage, there is 8.4KB of data loaded.
When I load the content in via an ajax request, no matter the size of the data downloaded, it takes approximately 20 seconds. The smallest amount of data that is loaded in this way is about 500 bytes. There is obviously a mismatch here.
So Chrome tells me that the vast majority of the time spent is "waiting" which I take to mean that the server is dealing with the request. So, that can only mean, I guess, that either my code is taking a long time, or something screwy is going on with the server. I don't think it's my code, because it's fairly minimal:
$file = "";
if (isset($_GET['page'])) {
$file = $_GET['page'];
} else if (isset($_POST['page'])) {
$file = $_POST['page'];
} else {
$file = "home";
}
$file = 'content/' . $file . '.php';
if (file_exists($file)) {
include_once($file);
} else {
include_once('content/404.php');
}
This is in a content_loader.php file which my javascript (in this scenario) sends a GET request to along with a "page" parameter. HTML markup is returned and put into a DIV on the page.
I'm using the jQuery .get() shorthand function, so I don't imagine I could be messing anything up there, and I'm confident it's not a Javascript problem because the delay is in waiting for the data from the server. And again, even when the data is very small, it takes about 20 seconds.
I currently believe it's a problem with the server, but I don't understand why a request made through javascript would be so much slower than a request made the traditional way through the browser. As an additional note, some of the content pages do connect to a MySQL database, but some do not. It doesn't seem to matter what the page requires for processing or how much data it consists of, it takes right around 20 seconds.
I'm at a loss... does anyone know of anything that might explain this? Also, I apologize if this is not the correct place for such a question, none of the other venues seemed particularly well suited for the question either.
As I mentioned in my comment, a definite possibility could be reverse DNS lookups. I've had this problem before and I bet it's the source of your slow requests. There are certain Apache config directives you need to watch out for in both regular apache and vhost configs as well as .htaccess. Here are some links that should hopefully help:
http://www.tablix.org/~avian/blog/archives/2011/04/reverse_dns_lookups_and_apache/
http://betabug.ch/blogs/ch-athens/933
To find more resources just Google something like "apache slow reverse dns".
A very little explanation
In a reverse DNS lookup an attempt is made to resolve an IP address to a hostname. Most of the time with services like Apache, SSH and MySQL this is unnecessary and it's a bad idea as it only serves to slow down requests/connections. It's good to look for configuration settings for your different services and disable reverse DNS lookups if they aren't needed.
In Apache there are certain configuration settings that cause a reverse lookup to occur. Things like HostnameLookups and allow/deny rules specifying domains instead of IP addresses. See the links above for more info.
As you suggested in your comment, the PHP script is executing quickly once it finally runs. The time is spent waiting on Apache - most likely to do a reverse DNS lookup, and failing. You know the problem isn't with your code, it's with the other services involved in the request.
Hope this helps!