This code leaks information from the login page when a route that does not exist is being tried to navigate at.
<html>
<head>
<title>Login</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Login</h1>
<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
Name: <input type="text" name="uname">
password: <input type="password" name="upass">
<input type="submit">
</form>
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$loginusername = $_POST['uname'];
$loginpassword = $_POST['upass'];
if (empty($loginusername) || empty($loginpassword)) {
echo "Please enter username and password";
} else {
$user = getEnv('USER');
$password = getEnv('PASSWORD');
$database = getEnv('DATABASE');
$table = getEnv('SONGS');
$db = new PDO("mysql:host=localhost;dbname=$database", $user, $password);
$query = "SELECT * FROM $table where user_name = :username and password = :loginPassword";
$statement = $db->prepare($query);
$statement->bindParam(":username",$loginusername, PDO::PARAM_STR);
$statement->bindParam(":loginPassword",$loginpassword, PDO::PARAM_STR);
$statement->execute();
$result = $statement->fetchAll();
if(!$result) {
echo "<p>No result!</p>";
exit;
} else {
$userid = $result[0][0];
$username = $result[0][1];
}
}
}
?>
</body>
</html>
This is an indexing page which will index all articles that are in the website.
<html>
<head>
<title>Some title</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
Return
<?php
if (isset($_GET['file'])) {
$file = $_GET['file'];
$file = file_get_contents($file);
echo "$file";
echo '<br />Index';
}
else {
$user = getEnv('USER');
$password = getEnv('PASSWORD');
$database = getEnv('DATABASE');
$table = getEnv('ARTICLES');
$db = new PDO("mysql:host=localhost;dbname=$database", $user, $password);
$query = "SELECT * FROM $table";
$stmt = $db->prepare($query);
$stmt = $db->query($query);
echo "<ul>";
foreach($stmt as $row) {
$href = $row[2];
$title = $row[1];
echo "<li> <a href='/myPage?file=../dir/$href'>$title</a> </li> ";
}
echo "</ul>";
}
?>
</body>
</html>
When this href echo "<li> <a href='/myPage?file=../dir/$href'>$title</a> </li> "; is changed manually at browser at suppose this route /myPage/?file=../login.php it will cause to leak code from the login file, which can uncover to the attack some crucial information about my backend setup. Is there any way how to patch this problem.
Yes, it's easily avoided by sanitizing your input.
Structures such as this
if (isset($_GET['file'])) {
$file = $_GET['file'];
$file = file_get_contents($file);
are highly problematic.
But there isn't a one-size-fits-all solution without knowing what the legit files that you want to allow to be referenced are.
Roughly how many valid files are there ? are they all located in the same directory ? do they follow some sort of specific naming convention ? do they all have the same extension (or lack any at all) ?
Edit: I suspect you'll want something along these lines. I haven't tested it, so it's possible i made a typo somewhere, but it shouldn't suffer from the same vulnerabilities atleast.
<html>
<head>
<title>Some title</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
Return
<?PHP
$user = getEnv('USER');
$password = getEnv('PASSWORD');
$database = getEnv('DATABASE');
$table = getEnv('ARTICLES');
$db = new PDO("mysql:host=localhost;dbname=$database", $user, $password);
$filekey = 'ref';
$dbcolumn = 'href'; // <--- should match the name of the column in mysql
if (isset($_GET[$filekey]) && $request = $_GET[$filekey]) {
$stmt = $db->prepare("SELECT $dbcolumn FROM $table WHERE $dbcolumn = ?");
$stmt->execute([ $request ]);
if ( $records = $stmt->fetchAll(PDO::FETCH_ASSOC)
&& !empty($records)
&& $record = reset($records)
&& isset($record[$dbcolumn])
&& $request = $record[$dbcolumn]
) {
echo file_get_contents("../dir/$request");
echo '<br />Index';
} else {
die('Access denied');
}
} else {
$query = "SELECT * FROM $table";
$stmt = $db->prepare($query);
$stmt = $db->query($query);
echo "<ul>";
foreach($stmt as $row) {
$href = $row[2];
$title = $row[1];
printf('<li><a href='/myPage?%s=%s'>%s</a></li>',
$filekey,
htmlentities($href, ENT_QUOTES),
htmlentities($title, ENT_QUOTES)
);
}
echo "</ul>";
}
?>
</body>
</html>
Make sure you set $dbcolumn correctly (should match the mysql column name), and optionally change $filekey to whatever you want to see in the URL.
This fixes your security problem: it only allows filenames to be specified in the URL, that actually exist in your database table, so it cant be used to pull random files anymore. If someone tries to manually change thevalue in the URL to something not in the database they get the error above.
It also fixes potential problems with the title in the listing, which was being output raw (i added htmlentities). Depending on the type of content inside the files, you may want to wrap a htmlentities call around file_get_contents() aswell, but don't do that if there is actual html inside those files.
I did see some other oddities , such as that you create a prepared statement and then don't use it :) but that has no security implications in this case, i left it as is.
Related
Let me explain what I want to.
I want to add a value in a list with db add without page change when I input in form, and click submit.
but in this code, I must refresh one more time to add, and also added twice a time.
How can I do that?
<?php
$conn = mysqli_connect('127.0.0.1','MYID','MYPASS','MYDB');
$sql = "SELECT * FROM MYTABLE";
$rs = mysqli_query($conn, $sql);
$list = '';
while($row = mysqli_fetch_array($rs)) {
$list = $list."<li>{$row['title']}</li>";
}
$article = array(
'title' => 'Welcome!',
'description' => 'Hello, Web!'
);
if (isset($_GET['id'])){
$filtered_id = mysqli_real_escape_string($conn, $_GET['id']);
$sql = "SELECT * FROM topic WHERE id={$filtered_id}";
$rs = mysqli_query($conn, $sql);
$row = mysqli_fetch_array($rs);
$article['title'] = $row['title'];
$article['description'] = $row['description'];
}
if ($_POST['title'] != null){
$sql_in = "INSERT INTO topic (title, description, created) VALUES ('{$_POST['title']}', '{$_POST['description']}', NOW())";
$rs_in = mysqli_query($conn, $sql_in);
if ($rs_in === false) {
$msg = mysqli_error($conn);
} else {
$msg = 'Success.';
}
} else {
$msg = 'Fill in';
}
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>WEB</title>
</head>
<body>
<h1>WEB</h1>
<ol>
<?=$list?>
</ol>
<details>
<summary>Create</summary>
<form action="./index.php" method="POST">
<p><input type="txt" name="title" placeholder="title"></p>
<p><textarea name="description" placeholder="description"></textarea></p>
<p><input type="submit"></p>
<p><?=$msg?></p>
</form>
</details>
</body>
</html>
<h2><?=$article['title']?></h2>
<?=$article['description']?>
</body>
</html>
In php realtime isn't a thing but there is a workaround you can use events services like pusher https://pusher.com/docs and receive the events in client side instantly .
there other website offers this so do your search before choosing them also you can always build your event server in node.js , c# , go
I have made a database, it works and values have been entered, I have also made a service page using PHP which also works great thanks to a person on here! So I can query that and it works fine e.g.
http://localhost/NewWebApp/php/databaseRestService.php?episodename=Pilot
//Outputs: "7th October 2014"
Which is correct, however when I use a client (Input field), I get nothing returned. At all. I have gone through all of my code again, and done little if statements to see where the problem could lie, and I have shortlisted it down to my $data variable. The code is as follows for this Client.
<!doctype html>
<html lang="en">
<head>
<?php
if(isset($_GET["submit1"]))
{
$episodeNameForFlash = $_GET["episodename"];
$url = "http://localhost/NewWebApp/php/databaseRestService.php?episodename ='".$episodeNameForFlash."'";
$client = curl_init($url);
curl_setopt($client,CURLOPT_RETURNTRANSFER,1);
$data = curl_exec($client);
echo curl_error($client);
if(!$data)
{
echo "Error on data";
}
}
?>
</head>
<body>
<form action="databaseRestClient.php" method="GET">
<label>Enter Name of Episode</label> <input type="text" name="episodename"/>
<input type="submit" name="submit1"/><br/>
</form>
<?php
if(isset($data))
{
echo ("The date of the Episode is ". $data);
}
?>
</body>
</html>
Thus the output is: Error on data.
Does anyone know what I am doing wrong? Been trying to figure this out for a couple of hours now.
Kieran
UPDATE: databaseRestService.php code
<?php
class FlashEpisodes
{
var $serverName = "localhost";
var $userName = "root";
var $password = "";
var $databaseName = "test";
public function FlashEpDate($name)
{
$databaseConnection = mysqli_connect($this->serverName, $this->userName, $this->password);
if(!$databaseConnection)
{
// echo "Error";
}
if(!mysqli_select_db($databaseConnection, $this->databaseName))
{
//echo "Error";
}
else
{
//echo "Success";
}
$sql = "SELECT theFlashEpsDate FROM superhero WHERE theFlashEps ='".$name."'";
$result = mysqli_query($databaseConnection, $sql);
if(!$result)
{
echo "<br>Error on Query";
}
if ($result)
{
$row = mysqli_fetch_array($result, MYSQLI_NUM);
$getTheFlashEpsDate = $row[0];
}
else
{
$getTheFlashEpsDate = null;
}
return $getTheFlashEpsDate;
}
}
$getEpisodeName = $_GET['episodename'];
$objSuperHero = new FlashEpisodes;
$response = $objSuperHero->FlashEpDate($getEpisodeName);
echo $response;
?>
^ The code here works as it should, I can just put in the query in the string and this page works, just when I want to use a client (input field) it does not :(
when defining $url variable in databaseRestClient.php file, why do you have single quotes for the $episodeNameForFlash parameter?
I think these single quotes are the cause of the problem, remove them and check your code again.
that line should look like this:
$url = "http://localhost/NewWebApp/php/databaseRestService.php?episodename =".$episodeNameForFlash;
it's better for you to use urlencode to encode the $episodeNameForFlash variable before using it in the $url in case of any special characters in the $episodeNameForFlash variable and then use urldecode in the databaseRestService.php file when retrieving the $_GET['episodename']
Here's my working version...
<head>
<?php
if(isset($_GET["submit1"]))
{
$episodeNameForFlash = $_GET["episodename"];
$url = "http://localhost/testserver.php?episodename ='".$episodeNameForFlash."'";
$data = file_get_contents($url);
if(!$data)
{
echo "Error on data";
}
}
?>
</head>
<body>
<form action="testclient.php" method="GET">
<label>Enter Name of Episode</label> <input type="text" name="episodename"/>
<input type="submit" name="submit1"/><br/>
</form>
<?php
if(isset($data))
{
echo ("The date of the Episode is ". $data);
}
?>
</body>
</html>
I have a code in php where i m clikcing on women products or any other link for any other product.On click of which i m going to next page and passing the product name in querystring.
And then in next page i m using my sql query,which will give me the list of products which u clicked on first page.There are lot of queries in my project like this one.This query is quite prone to Google bots hacking with SQL injection.Following is the code
<html>
<head>
</head>
<body>
<ul id="list">
<li><h3>tops</h3></li>
<li><h3>suits</h3></li>
<li><h3>jeans</h3></li>
<li><h3>more</h3></li>
</ul>
</body>
</html
Search.php
<?php
$mysqli = new mysqli('localhost', 'root', '', 'shop');
if(mysqli_connect_errno()) {
echo "Connection Failed: " . mysqli_connect_errno();
}
?>
<html>
<head>
</head>
<body>
<?php
session_start();
$lcSearchVal=$_GET['name'];
//echo "hi";
$lcSearcharr=explode("-",$lcSearchVal);
$result=count($lcSearchVal);
//echo $result;
$parts = array();
$parts1=array();
foreach( $lcSearcharr as $lcSearchWord ){
$parts[] = '`PNAME` LIKE "%'.mysql_real_escape_string($lcSearchWord).'%"';
$parts1[] = '`TAGS` LIKE "%'.$lcSearchWord.'%"';
//$parts[] = '`CATEGORY` LIKE "%'.$lcSearchWord.'%"';
}
$stmt = $mysqli->prepare('SELECT * FROM xml where'.'PNAME LIKE ?');
var_dump($stmt);
$parts='%women%';
$stmt->bind_param('s',$parts);
$list=array();
if ($stmt->execute()) {
while ($row = $stmt->fetch()) {
$list[]=$row;
}
}
$stmt->close();
$mysqli->close();
foreach($list as $array)
{
?>
<div class="image">
<img src="<?php echo $array['IMAGEURL']?>" width="200px" height="200px"/></a>
<?php
}
?>
</div>
</body>
</html>
The query i m using above is quite prone to Google Bot hacking.Please guide me what should i change in this query so that Google Bot wont be able to hack my application with mysql injection..There are some other similar queries in my application to this one.Please guys help me on this.
The reason this is open to SQL injection is that you have not escaped the input.
For example you have the line:-
$parts[] = '`PNAME` LIKE "%'.$lcSearchWord.'%"';
If someone had used a link something like as follows (ignoring the encoding to get it to work in a URL):-
search.php?name=fred%' UNION SELECT * FROM users #
the SQL you would land up with would be something like:-
SELECT * FROM xml WHERE (`PNAME` LIKE "%fred%' UNION SELECT * FROM users #%")limit '.$offset.', '.$limit1.'
then they can execute a query to get data from the other table (possibly one containing the passwords, etc), with just a bit of patience getting the right number of columns, etc.
If you switch to mysqli_* you can use parameterised queries, but these are a minor pain when the SQL itself changes (as yours does in this case with a variable number of LIKE statements).
The simple solution would be to use mysql_real_escape_string() / mysqli_real_escape_string() on the variable you use in the SQL.
foreach( $lcSearcharr as $lcSearchWord )
{
$parts[] = '`PNAME` LIKE "%'.mysql_real_escape_string($lcSearchWord).'%"';
$parts1[] = '`TAGS` LIKE "%'.mysql_real_escape_string($lcSearchWord).'%"';
//$parts[] = '`CATEGORY` LIKE "%'.mysql_real_escape_string($lcSearchWord).'%"';
}
It is worth switching to mysqli_* if you can.
EDIT
Played with script using mysqli_() and a class and function to cope with variable numbers of parameters
<?php
session_start();
$mysqli = new mysqli('localhost', 'root', '', 'shop');
if(mysqli_connect_errno())
{
echo "Connection Failed: " . mysqli_connect_errno();
}
?>
<html>
<head>
</head>
<body>
<?php
if (array_key_exists('name', $_GET))
{
$lcSearchVal = $_GET['name'];
$lcSearcharr = explode("-",$lcSearchVal);
$result = count($lcSearchVal);
$parts = array();
foreach( $lcSearcharr as $lcSearchWord ){
$parts[] = "%$lcSearchWord%";
}
$bindParam = new BindParam();
$parms = array();
foreach($parts as $aPart)
{
$parms[] = ' PNAME LIKE ? ';
$bindParam->add('s', $aPart);
}
$query = 'SELECT IMAGEURL FROM xml where '.implode(' OR ', $parms);
$stmt = $mysqli->prepare($query);
if ($stmt)
{
call_user_func_array(array($stmt, "bind_param"), refValues($bindParam->get()));
if ($stmt->execute())
{
while ($row = $stmt->fetch())
{
echo '<div class="image"><img src="'.$row['IMAGEURL'].'" width="200px" height="200px"/></a>';
}
}
else
{
echo $mysqli->error;
}
$stmt->close();
$mysqli->close();
}
else
{
echo $mysqli->error;
}
}
else
{
?>
<ul id="list">
<li><h3>tops</h3></li>
<li><h3>suits</h3></li>
<li><h3>jeans</h3></li>
<li><h3>more</h3></li>
</ul>
<?php
}
?>
</div>
</body>
</html>
<?php
function refValues($arr)
{
if (strnatcmp(phpversion(),'5.3') >= 0) //Reference is required for PHP 5.3+
{
$refs = array();
foreach($arr as $key => $value) $refs[$key] = &$arr[$key];
return $refs;
}
return $arr;
}
class BindParam
{
private $values = array(), $types = '';
public function add( $type, $value )
{
$this->values[] = $value;
$this->types .= $type;
}
public function get()
{
return array_merge(array($this->types), $this->values);
}
}
?>
I was looking for a way to update the count for the database after finding the result of a product but it keeps returning an error and/or not updating the count. I found ways to update the counts out right but not after finding a result. If i'm blind please redirect me. My apologies if I overlooked anything. RAM
<?php
//Variables for connecting to your database.
//These variable values come from your hosting account.
require_once '../connect/connect.php';
$usertable = "UPC_Product";
$yourfield2 = "Product";
$yourfield1 = "UPCA";
$yourfield3 = "Gluten Free";
$yourfield4 = "Company";
$yourfield5 = "search_cnt";
$yourfield6 = "CompName";
$yourfield7 = "id";
$search_id = $_POST["search_id"];
//Connecting to your database
mysql_connect($hostname, $username, $password) or die("Unable to
connect to database! Please try again later.");
mysql_select_db($dbname);
//Fetching from your database table.
$query = "SELECT * FROM $usertable WHERE UPCA = $search_id";
$result = mysql_query($query);
if ($result) {
while ($row = mysql_fetch_array($result)) {
$name = $row["$yourfield2"];
$upca = $row["$yourfield1"];
$gluten = $row["$yourfield3"];
$count = $row["$yourfield5"];
$id = $row["$yourfield7"];
}
//update count
$ucount = "UPDATE $usertable SET search_cnt = ($count + 1)";
mysql_query($ucount);
}
?>
<head>
<link rel="icon"
type="image/png"
href="../images/GluteFreefavicon.jpg">
<meta name="viewport" content="width=device-width">
<title>Result Page</title>
<meta http-equiv="Content-Language" content="English" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="/style.css" media="screen" />
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-39600334-1', 'glutefree.com');
ga('send', 'pageview');
</script>
</head>
<body>
<div id="wrap">
<div id="top"></div>
<div id="content">
<div class="header">
<img src="/images/glutefreefacebookbanner.jpg"/>
</div>
<div class="breadcrumbs">
<center> Home · Search · Application · Register · Contact Us · About Us · Games
</center>
</div>
<div class="result">
<center>Your Results
<br/>
</center>Product:
<?php echo $name; ?>
<br/>
<div class="product">Gluten Free?
<?php echo $gluten; ?>
<br>
<br>UPC:
<?php echo $upca;?>
<br>Search count:
<?php echo $count;?>
<br/>
</div>
</div>
<p>No Result? Click here to fill out information on the product you were searching for.</p>
</div>
<div id="bottom"></div>
</div>
<div id="footer">
</a>
</div>
</body>
</html>
correction 1 :- I think you need to write your update query below the while loop. because you are using $count variable before creating it.
Also please specify if you need to increase count for individual row or total.
If you need to update count for individual row then you have write query inside while loop.
UPDATE $usertable SET search_cnt = ($count + 1) WHERE id_column_name = $id;
correction 2:- You are calling mysql_query($ucount); in wrong place. this should be below update query.
Correction 3 :- as $count is your count number then obviously it will not be your column name , write down you column name in update query.
UPDATE $usertable SET count_column_name = ($count + 1)
Corrected Block of code:-
<?php
//Variables for connecting to your database.
//These variable values come from your hosting account.
require_once '../connect/connect.php';
$usertable = "UPC_Product";
$yourfield2 = "Product";
$yourfield1 = "UPCA";
$yourfield3 = "Gluten Free";
$yourfield4 = "Company";
$yourfield5 = "search_cnt";
$yourfield6 = "CompName";
$yourfield7 = "id";
$search_id = $_POST["search_id"];
//Connecting to your database
mysql_connect($hostname, $username, $password) or die("Unable to
connect to database! Please try again later.");
mysql_select_db($dbname);
//Fetching from your database table.
$query = "SELECT * FROM $usertable WHERE UPCA = $search_id";
$result = mysql_query($query);
if ($result) {
while ($row = mysql_fetch_array($result)) {
$name = $row["$yourfield2"];
$upca = $row["$yourfield1"];
$gluten = $row["$yourfield3"];
$count = $row["$yourfield5"];
$id = $row["$yourfield7"];
}
//update count
// Please write here count column name not $count. I have write count at this time.
$ucount = "UPDATE $usertable SET search_cnt = ($count + 1)";
mysql_query($ucount);
}
?>
All you need to do is rearrange a function to get the correct count. Below should be the right code.
<?php
//Variables for connecting to your database.
//These variable values come from your hosting account.
require_once '../connect/connect.php';
$usertable = "UPC_Product";
$yourfield2 = "Product";
$yourfield1 = "UPCA";
$yourfield3 = "Gluten Free";
$yourfield4 = "Company";
$yourfield5 = "search_cnt";
$yourfield6 = "CompName";
$yourfield7 = "id";
$search_id = $_POST["search_id"];
//Connecting to your database
mysql_connect($hostname, $username, $password) or die ("Unable to
connect to database! Please try again later.");
mysql_select_db($dbname);
//Fetching from your database table.
$query = "SELECT * FROM $usertable WHERE UPCA = $search_id" ;
$result = mysql_query($query);
if ($result) {
while($row = mysql_fetch_array($result)) {
$name = $row["$yourfield2"];
$upca = $row["$yourfield1"];
$gluten = $row["$yourfield3"];
$count = $row["$yourfield5"];
$id = $row["$yourfield7"];
}
}
$ucount = "UPDATE $usertable SET $count = ($count + 1)";
mysql_query($ucount) or die(mysql_error());
?>
To be more specific - You were trying to call:
$ucount = "UPDATE $usertable SET $count = ($count + 1)";
before you actually updated the $count method in the while loop.
So, I neet to set the argument to a function in order to convert it to a .mp3 file. Using this line : $tts->setText($row['raspuns']); doesn't happen anything but if i write $tts->setText("Hello World!"); it works perfectly, which takes me to the conclusion that i have to find a correct code to make that tts get the text. Can anyone help me please?
<html>
<head>
<title>
Bot
</title>
<link type="text/css" rel="stylesheet" href="main.css" />
</head>
<body>
<form action="bot.php "method="post">
<lable>You:<input type="text" name="intrebare"></lable>
<input type="submit" name="introdu" value="Send">
</form>
</body>
</html>
<?php
mysql_connect("localhost", "root", "") or die(mysql_error());
mysql_select_db("robo") or die(mysql_error());
$intrebare=$_POST['intrebare'];
$query = "SELECT * FROM dialog where intrebare = '$intrebare'";
$result = mysql_query($query) or die(mysql_error());
$row = $result;
?>
<?php
require "tts.php";
$tts = new TextToSpeech();
**$tts->setText($row['raspuns']);**
*//$tts->setText("Hello World!");*
$tts->saveToFile("voice.mp3");
$file='voice.mp3';
?>
<div id="history">
<?php
while (true == ($row = mysql_fetch_array($result))) {
echo "<b>The robot says: </b><br />";
echo $row['raspuns'];
echo "<embed src =\"$file\" hidden=\"true\" autostart=\"true\"></embed>";
}
?>
</div>
Here's the tts.php file:
<?php
class TextToSpeech {
public $mp3data;
function __construct($text="") {
$text = trim($text);
if(!empty($text)) {
$text = urlencode($text);
$this->mp3data = file_get_contents("http://translate.google.com/translate_tts?tl=en&q={$text}");
}
}
function setText($text) {
$text = trim($text);
if(!empty($text)) {
$text = urlencode($text);
$this->mp3data = file_get_contents("http://translate.google.com/translate_tts?tl=en&q={$text}");
return $this->mp3data;
} else { return false; }
}
function saveToFile($filename) {
$filename = trim($filename);
if(!empty($filename)) {
return file_put_contents($filename,$this->mp3data);
} else { return false; }
}
}
?>
You need to fetch the row from your result
If you want your code to work where your tts class calls are, change
$row = $result;
To
$row = mysql_fetch_row($result);
Note you have a code block below that redefines the $row array.
Also note mysql_* functions are deprecated, use PDO or mysqli_ functions instead. Your current code is wide open to sql injects!