PHP $_SESSION error when posting to the database - php

I am trying to create posts with a userid = to the currently logged in users id.
On page 1 I use $_SESSION to set a variable
$_SESSION['Userid'] = $row_getUserStuff['userid'];
I can call $_SESSION['Userid'] on both page 1 and page 2 with
echo($_SESSION['Userid']);
which outputs the users id, my problem is when I try to push that data to the database.
In the form I put
<input type="hidden" name="userid" value="<?php $_SESSION['Userid']?>" />
But when I try to post it I get the error
Column 'userid' cannot be null

Don't put the session data in the form. It is pointless for the browser to have to send the server something the server already knows, and anyone can change it in an injection attack.
Instead, just access $_SESSION['Userid'] when inserting the value into the database.

try this:
<input type="hidden" name="userid" value="<?php echo $_SESSION['Userid']?>" />
You're not actually telling PHP to output the session variable, you're just referring to it. But since it's a session variable, it doesn't need to be in the form at all, I assume there's a $_POST['userid'] somewhere in your code to handle the form, just replace that with $_SESSION['Userid'].

try
<input type="hidden" name="userid" value="<?php echo $_SESSION['Userid']; ?>" />
I added the echo statement and the ; so that no php error will be generated and the $_SESSION['Userid'] is properly sent to the browser.

Replace this line:
<input type="hidden" name="userid" value="<?php $_SESSION['Userid']?>" />
to
<input type="hidden" name="userid" value="<?php echo $_SESSION['Userid']?>" />

Related

Using hidden fields for updating data in database

So I have a html table containing data retrieved from the database. In each row, there is an "edit" button. It looks like this:
<td><form action="controller/edit" method="post">
<input type="hidden" name="id" value="<?php echo $id ?>">
<input type="submit" value="edit">
</form></td>
Then in the controller/edit page I will access the database again:
select * from table where id=$_POST['id']
This is all fine. However I am thinnking of avoiding the second access to the database to improve performance. I am trying to do something like this:
<td><form action="controller/edit" method="post">
<input type="hidden" name="id" value="<?php echo $id ?>">
<input type="hidden" name="name" value="<?php echo $name ?>">
<input type="hidden" name="amount" value="<?php echo $amount ?>">
<input type="submit" value="edit">
</form></td>
This way all the data from the row is in the form, so when the form submits to controller/edit I don't need to access the database again. Is this approach fine? Or Is this bad practice?
The second one you've mentioned does seem like a shortcut, but it can be vulnerable.
Hidden fields can easily be tampered. For example, a user can manipulate the value of the hidden field and change the value to a random number like 975646456456456.
In that case, your database will have an incorrect insertion since there probably wouldn't be a matching record corresponding to id 975646456456456.
So, I think you should go with the first one and check your database if the id exists, and fetch its records.
Try to submit using jquery.button. For example submit form:
submitform(){
jQuery('form id').attr('action','url'+'?id= "id from db");
jQuery('form id').submit();
}

Insecure form post value validating

Currently I'm using a form to post a "comment" and save it in the database there are two hidden fields, one to check what component the comment is made on and the other hidden field is the comment number. But I found a exploit in my own form. If I go into the developer console I can change them to either crosspost the comments to a other form, or to something that doesn't exist, this doesn't really matter, nor the fact that I can change the number the comment is, because it still works properly if there's a comment with the same number.
<form action="/index.php?option=com_comments&view=comment&row=<?= $row ?>&table=<?= $table ?>" method="post">
<input type="hidden" name="row" value="<?= $row ?>" />
<input type="hidden" name="table" value="<?= $table ?>" />
<textarea type="text" name="text" class="control control--textarea control-group__control" placeholder="<?= translate('Add new comment here ...') ?>" id="new-comment-text"></textarea>
<br />
<input class="leader btn btn--theme control-row__trigger" type="submit" value="<?= translate('Comment') ?>"/>
But the issue is that when I go to the console and I add and then submit the form I can actually override the value and post as that I'm someone else. Which is obviously not intended behaviour to be able to post as someone else. I can't seem to find a way to validate the value of created_by before the post is being send, because if I put it in a hidden input field too it can be changed just as well. What can I do to make this secure?
EDIT: The posting is done automatically and I literally can't change anything about it because of the Framework we're using. And it overrides the proper default behaviour. A better way to phrase my question would be, can I prevent a user from adding a extra hidden input field to post extra values? Should I post form post check everytime if the post includes a created_by and if it does change it to the current profile_id?
Malicious code changed via developer console
<form action="/index.php?option=com_comments&view=comment&row=2&table=blogs_blogs&created_by=6" method="post" class="ng-pristine ng-valid">
<input type="hidden" name="_token" value="a0b15d3664d7bc0e0e40675095fec014">
<input type="hidden" name="_token" value="a0b15d3664d7bc0e0e40675095fec014">
<input type="hidden" name="row" value="2">
<input type="hidden" name="created_by" value="6">
<input type="hidden" name="table" value="blogs_blogs">
<textarea type="text" name="text" class="control control--textarea control-group__control" placeholder="Add new comment here ..." id="new-comment-text"></textarea>
<br>
<input class="leader btn btn--theme control-row__trigger" type="submit" value="Comment">
</form>
Rule #1 in web application security: Never trust the client
If the user is logged in, store the user's id in the session and only use that identifier to store his/her records in the database.
Plus, you should implement a mechanism to prevent CSRF (cross site request forgery) in your form. Because I can't see that it does.
You can use session or cookies together with database
[php]
$userHash = $db->prepare('SELECT user_hash FROM user WHERE id = :uId')->scalar([':uId' => $this->getUserId()]);
if (!empty($_SESSION['userHash']) && $_SESSION['userHash'] == $userHash) {
// process form
// generate new user hash
} else {
die('!HACKER!');
}
Instead of user ID you can use session ID.
I fixed it by adding this check to the behaviour that's applied before it's actually posted to the server
public function createdbycheck(Library\CommandContext $context)
{
$context->request->data->created_by = null;
}
Just sets it to NULL, and then it's handled by the default behaviour.

Multi page form PHP

I have a page which is sending the variable idClient to another page.
Lets say on the step1.php i fill the idClient input and submit it via GET.
It goes to step2.php?idClient=1, then i'am hidding it:
<input type="hidden" id="idClient" value="<?php echo $_GET['idClient']; ?>">
But after that, when i submit that second page to another, it doesn't send the idClient variable.
Can anyone give me a hint?
You have to change id="idClient" to name="idClient".
id attribute is only used in the client side, and will never passed to the server side.
Try this:
<input type="hidden" id="idClient" name="idClient" value="<?php echo $_GET['idClient']; ?>">
use POST to access idClient
<input type="text" id="idClient" name="idClient" value="<?php echo $_GET['idClient']; ?>">

PHP: keeping the username in field

How do i do if i want to keep the username in the field if the users entered incorrect password, so the person doesnt need to retype the username? Should i use sessions for this?
Just pass the value to the field:
<input name="uid" value="<?php echo (isset($_POST['uid'])) ? $_POST['uid'] : ''?>" />
Never forget to sanitize user input first! (not like in my example but it should give you the right idea).
But be careful with error messages. Don't say that the password is wrong. Say that the password or username is wrong. You don't want to let anyone know that a certain username is register in your system (at least not by trying to login).
Make sure $_POST['username'] data is not harmful first.
<input name="username" type="text" value="<?php echo $_POST['username'] ?>" />
try this one
use the session variable
$_SESSION['username'] = $_POST['username'];
<input type="text" name="username" value="<?php echo $_SESSION['username']; ?>" />
Just print it:
<input name="username" type="text" value="<?php echo htmlspecialchars($_POST['username']) ?>">
Yes if you are not posting to the same page but to a php handeling script you would need to use a session variable like $_SESSION['sticky']['username'] = $_POST['username'], then on the page that you return to
<input type="text" value="<?php if isset($_SESSION['sticky']['username']) echo $_SESSION['sticky']['username'] ?>" name="username" />

How can I set the value of a textbox through PHP?

So I have this empty textboxes in a registrationg page. The user enters some data, hits continue and then there's a confirmation page. If the data is incorrect, the user hits go back to go correct whatever was wrong. However, when he goes back, all the textboxes are empty. So the first thing that comes to my mind is to store the user data in a Session (I have a User class that holds all this data so I store the class in the session). When the user goes back I am able to retrieve the data.
I do something like this:
if($_SESSION['UserInfo'])
{
$user = $_SESSION['UserInfo'];
$firstName = $user->FirstName;
$lastName = $user->LastName;
}
How would I put these variables in a textbox?
To set the value, you can just echo out the content inside the value attribute:
<input type="text" name="firstname" value="<?php echo htmlentities($firstName); ?>" />
<input type="text" name="lastname" value="<?php echo htmlentities($lastName); ?>" />
Of course you will want to escape it but...
<input type="text" value="<?php echo $firstName ?>" />
or if the form is posted, it would be easier to do:
<input type="text" name="firstName" value="<?php echo $_POST['firstName'] ?>" />
fine... even though it was out of the scope of the question here is the escaped version:
<input type="text" name="firstName" value="<?php echo htmlentities($_POST['firstName']) ?>" />
smth like
<input type="text" value="<?php echo $first_name;?>">
Don't forget to escape with htmlentities() or smth similar. If you don't know why - google XSS.

Categories