Code with htmlentities not work properly - php

I start to learn php and create a code to learn how to use the GET/POST in php code.
So I heard an unsafe code can be executed through the input, so I create a checker using the
htmlentities() function.
<?php
if (isset($_POST['firstname'], $_POST['lastname'], $_POST['pwd']) or isset($_GET['firstname'], $_GET['lastname'], $_GET['pwd'])) {
txt_check();
$fname = $_GET['firstname'];
$lname = $_GET['lastname'];
$pwd = $_GET['pwd'];
if ($fname == 'Or' and $lname == 'Halimi' and $pwd == 'password') {
print 'Welcome master';
} else {
print 'You are not my master!';
}
echo format('<br/> <br/> {} {}', array($fname, $lname)); # like format in python
}
function txt_check() {
foreach ($_GET as $name => $string) {
$_GET[$name] = htmlentities($_GET[$name], ENT_QUOTES, 'UTF-8');
}
foreach ($_POST as $name => $string) {
$_POST[$name] = htmlentities($_POST[$name], ENT_QUOTES, 'UTF-8');
}
}
?>
The problem is my function txt_check() not working,
but when I put echo htmlentities($fname, ENT_QUOTES, 'UTF-8') #fname=<script> i get <script> at the end of the code.
Maybe I can't edit $_GET? I come from python so I don't know if $_GET is special in someway.
Edit:
I want to understand if i can change the global $_GET\$_POST like I did and if its good to doing so' because i don't know if the code inside txt_check() working for me.
If not, there is a better way to protect the input I get? Because i want to make a standard level of protecting, even if i dont even know the most risks that's hanging out there.
And why htmlentities() its not so good for this case? I use basic tutorial about php security to make it.

If you are trying to remove HTML tags, i would recommend you to use the strip_tags...not the htmlentities.
<?php
$mytext = "hello<br><script>alert('everybody');</script>";
$allow = "<br>";
echo strip_tags($mytext,$allow);
?>
That will remove only the script tag.

Related

How would you echo the content of a file in php?

So I'm making a whitelist through my own website. I'm using a php to handle a request where it checks if your key matches the whitelisted keys and then echoes. My current code is:
$keys = array(
"Key", "key1");
$sub = $_GET["key"];
if (in_array($sub,$keys,TRUE)) {
echo "Whitelisted";
} else {
echo "Not Whitelisted";
}
?>
Instead of echoing "Whitelisted", I would like to return some text from a file (actually it is a script in some programming language to be executed on client side to make the whitelist more secure, but it does not matter for this question). I have the file in the public html directory and I was wondering if there was a way to call/access/require the entire content of the file. I'm a complete noob with php so if anyone could offer anything I would be very thankful.
Try something like:
<?php
$whitelistedKeys = array(
'Key', 'key1'
);
$input = $_GET['key'];
if (in_array($input, $whitelistedKeys, TRUE)) {
echo 'Whitelisted<br>';
$filePath = __DIR__ . '/my-file.txt';
echo "Content of \"$filePath\" file is:<br>";
echo file_get_contents($filePath);
} else {
echo 'Not Whitelisted';
}
?>
Note that I am not using double-quote to improve performance.
And am using __DIR__ to load my-file.txt from same directory which the PHP-script is in.

password_verify and special characters in password

I know this has to be a common question, but I can't find the answer.
I'm using PHP's password_verify. If the password contains "&" it won't verify. Without the "&" it does. What do I need to do to escape the character?
<?php
$password_entered = "Password&";
$stored_secret = '$2y$12$oG8A4pbZSfQFxBQ0cHcJTuJ1h7wzzhlMnqjhnurN4.0/AfS/Wp9W2';
if (password_verify($newstr, $stored_secret))
{
echo "Right\n";
}
else
{
echo "Wrong\n";
}
?>
Firstly ignoring that $newstr is not set and you meant $password_entered instead.
It looks like your running htmlentities/htmlspecialchars on the user input, (which you are not showing), so it's breaking it.
The following matches your hash: Password&.
<?php
$password_entered = "Password&";
$stored_secret = '$2y$12$oG8A4pbZSfQFxBQ0cHcJTuJ1h7wzzhlMnqjhnurN4.0/AfS/Wp9W2';
if (password_verify($password_entered, $stored_secret)) {
echo "Right\n";
} else {
echo "Wrong\n";
}
?>
https://3v4l.org/SjfRG

Is this script vulnerable to shell command bypass?

I'm using this script to receive base 64 encoded images from an Android app. I was wondering if there's any way possible to bypass a PHP shell command inside a POST request and get it to work in the server, for example, sending the command shell encoded and a name like "shell.php", "shell.php%0delete0". According to the script, everything will be saved as .png, so I'd say it's safe, but maybe I'm wrong and the script is actually vulnerable to shell command uploads.
<?php
header('charset=utf-8');
if($_SERVER['REQUEST_METHOD'] == 'POST') {
if(isset($_POST['image']) && isset($_POST['name'])) {
$image = $_POST['image'];
$name = $_POST['name'];
file_put_contents("/var/www/html/admigas/android/uploads/$name".strval(date('_Ym')).".png",base64_decode($image));
echo "Success";
} else {
echo "Wrong params";
}
} else {
echo "Nothing to do";
}
?>
So, let's look at the code step-by-step. My comments are preceded by #:
<?php
header('charset=utf-8');
if($_SERVER['REQUEST_METHOD'] == 'POST') {
if(isset($_POST['image']) && isset($_POST['name'])) {
# This is provided by the user:
$image = $_POST['image'];
# This is provided by the user:
$name = $_POST['name'];
# Where does $name come from? User input, of course!
file_put_contents("/var/www/html/admigas/android/uploads/$name".strval(date('_Ym')).".png",base64_decode($image));
echo "Success";
} else {
echo "Wrong params";
}
} else {
echo "Nothing to do";
}
Consequently, sending name=../../../../reverse-shell.php%00 with a base64-encoded payload will allow an attacker to upload an arbitrary file (in this case, PHP code), and probably execute it on the subsequent PHP request.
Solution (presented in diff format):
- $name = $_POST['name'];
+ $name = preg_replace('#[^A-Za-z0-9\-_]#', '', $_POST['name']);
You definitely want to remove any non-URL-safe characters to prevent attacks. You may want to totally rethink your strategy, of course.

MySQLi update not working, mutilple colums and two where clauses

So I have been debugging this for over 30 minutes and I still can't figure out what I'm doing wrong. I just started using MySQLi and thats one of the things that I keep messing up. I think it might have something to do with preg_replace I have only used this once before so i still am not very good with it.
<?php
ob_start();
session_start();
include("../include/config.php");
include("../include/functions.php");
if (isset($_SESSION['pv1_session']) && $_SESSION['pv1_session'] == true) {
if (isset($_POST['submit'])) {
$uid = idinfo($_SESSION['pv1_user_id'],"idu");
$id = mysqli_real_escape_string($mysql, $_POST['fid']);
$post_name = mysqli_real_escape_string($mysql, $_POST['name']);
$post_tags = mysqli_real_escape_string($mysql, $_POST['tags']);
$name = preg_replace("/[^\w a-zA-Zа-яА-Я0-9._-]/u", "_", $post_name);
$tags = preg_replace("/[^\w a-zA-Zа-яА-Я0-9._-]/u", "_", $post_tags);
$file = preg_replace("/[^\wa-zA-Zа-яА-Я0-9._-]/u", "_", $post_name);
$update = mysqli_query($mysql,"UPDATE files SET name='$name', filename='$file', tags='$tags' WHERE user_id='$uid' AND filehash='$id'");
if (!$update) {
echo "<p>Unable to update file.</p>";
exit;
} else {
echo "<p>Success: Your uploaded file has been updated!</p>";
$pro_url = $web['url'].'/account/manage_uploads.php';
header("Location: $pro_url");
}
}
} else {
echo "ERROR: Please log in first!";
}
?>
Use "prepared statements" (http://php.net/manual/en/mysqli.quickstart.prepared-statements.php)
This gives you two advantages:
it handles the escaping for you (and also does it right: you do the escaping BEFORE the preg_replace, and that could go very wrong)
it also provides you with very easy debug. You put the parameters into an array, and you can simple echo out (print_r) the parameters array and see what your preg_replace has done.

Php backslashes Issue

I've a html form which handle by Php. When I submit the form it's show a backslashes if i write for example: 5 rue de l'ourq. If a again submit the form because of I wrongly input any other field of the form then it's show 5 rue de l\'ourq and again 5 rue de l\\'ourq. This is happened in address filed.
Php Variable:
$address = $_POST['address'];
$title = inputvalid($_POST['title']);
$f_name = inputvalid($_POST['f_name']);
The problem is $address variable. I don't why it's show the backslashes. That's why I didn't put inputvalid function to that variable but can't fix this. Any idea ?
Sounds like you have magic_quotes turned on. You need to turn them off in you php settings.
If you can't turn off magic_quotes, I would make the first thing your inputvalid() function does is check to see if magic_quotes are enabled, if they are then stripslashes() on values.
http://php.net/manual/en/security.magicquotes.disabling.php
According to link above you can simulate disabling at runtime by adding the following code, but it is really just doing the same thing as I said above, checking if magic_quotes are on then stripslashes() on input arrays:
if (get_magic_quotes_gpc()) {
$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
while (list($key, $val) = each($process)) {
foreach ($val as $k => $v) {
unset($process[$key][$k]);
if (is_array($v)) {
$process[$key][stripslashes($k)] = $v;
$process[] = &$process[$key][stripslashes($k)];
} else {
$process[$key][stripslashes($k)] = stripslashes($v);
}
}
}
unset($process);
}
Put this in your config file:
ini_set('magic_quotes_gpc', 'off');
OR, if this is not allowed on your server, put this in config:
##/ Special Code to stop get_magic_quotes_gpc
function stop_magic_quotes($in)
{
$out = $in;
if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc())
{
if(is_array($out))
{
foreach($out as $k=>$v)
{
$v = stop_magic_quotes($v);
$out[$k] = $v;
}
}
else
{
$out = stripslashes($out);
}
}
return $out;
}//end func................
if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc())
{
$_GET = array_map('stop_magic_quotes', $_GET);
$_POST = array_map('stop_magic_quotes', $_POST);
}//end if....
PHP adds backslashes to escape the ' because it would literally mean the opening of a string.
Use stripslashes() to remove them.
Your inputvalid function is preventing SQL injections which are used to load and modify information from your database. The function escapes ' and " to prevent the injections. Your code should be able to translate those escaped characters back to a human-readable form after loading the information from the database.
From my comment to this question:
Check magic_quotes_gpc option in your php.ini file and set it to Off. Don't forget to restart the php process. If you don't have a direct access to the php.ini file, try this:
<?php ini_set('magic_quotes_gpc', 'Off'); ?>

Categories