I'm not sure why my code is not stored XSS - php

Update: I changed my payload to "<img src="fake.jpg" onerror="alert()"> and the XSS worked so I still don't know why the won't work but at least my stored XSS is working right now.
Thanks for everyone helping.
I downloaded a code from GitHub that is a chat, the code is written in PHP and MYSQL I want to make that chat vulnerable to stored XSS, and I quite can't figure why it's not.
Of course, everything is stored inside the database but whenever I try to inject XSS the tags or the content of the tags aren't showing, but in the database, I see the alert() it's just not letting me see it on the website itself...
Does anyone know what might cause the problem?
Here's the index.php:
<?php
include 'db.php';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>::Message::</title>
<link rel="stylesheet" href="style.css">
<script>
function ajax() {
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (req.readyState == 4 && req.status == 200) {
document.getElementById('chat').innerHTML = req.responseText;
}
}
req.open('GET','chat.php', true);
req.send();
}
setInterval(function(){ajax()},1000);
</script>
</head>
<body onload="ajax();">
<div class="page">
<div class="display-box">
<div id="chat"></div>
</div>
<div class="form">
<form action="" method="post">
<label for="name">Name:</label><br>
<input type="text" name="name" placeholder="Your name"><br>
<label for="message">Write some thing:</label><br>
<textarea name="message" id="message-write" cols="30" rows="3"></textarea><br>
<input type="submit" name="submit" value="Send">
</form>
<?php
if (isset($_POST['submit'])) {
$name = $_POST['name'];
$message = $_POST['message'];
$query = "INSERT INTO tbl_chat (name, message) VALUES ('$name','$message')";
$run = $con->query($query);
}
?>
</div>
</div>
</body>
</html>
and here is the chat:
<?php
include 'db.php';
$query = "SELECT * FROM `tbl_chat` ORDER BY id DESC";
$run = $con->query($query);
while($row = $run->fetch_array()):
?>
<div class="chating_data">
<span id="name"><?php echo $row['name'];?></span><br>
<span id="message"><?php echo $row['message'];?></span>
</div>
<?php endwhile; ?>

I think you might be using a modern browser that prevents the exploit for you. That does not mean the application is not vulnerable, it only means it is so straightforwardly vulnerable that even the browser can detect an exploit automatically.
Try sending the following response header:
X-XSS-Protection: 0
You can do so with something like header('X-XSS-Protection: 0'); and see if that allows you to try XSS. Also you can display XSS messages in this chat not in a response to your "malicious" request but afterwards - it should then work because the browser will have no way to associate your request with the response.

Related

I cant figure out why my tinyMCE editor doesnt display text from the database

I've been working on a CRUD project, within which i'm asked to use a tinyMCE editor for both publishing posts and editing them.
I got the publishing part to work correctly, but i' having trouble with the editing one.
The situation is as follow : using an MVC model, the view that generates the editing form is as such :
`<!DOCTYPE html>
<html lang="en">
<?php include("components/head.php") ?>
<body>
<?php include("components/header.php") ?>
<div class="containers">
<div class="admincolumn1">
<?php include("components/adminmenu.php") ?>
</div>
<div class="column2">
<div class="Redaction">
<form class="NewArticle" id="newArticle" method="POST" action="index.php?action=store-post">
<h2>Editez votre article</h2>
<div class="Articlecontainer">
<label for="Title"><strong>Titre:</strong></label>
<input type="text" placeholder="" name="Title" value=<?php $articleTitle ?>>
<label for="Subject"><strong>Votre Article:</strong></label>
<tinymce-editor api-key="0ki8kh44dpr0iupw97fjo8e0x3vrccw5i082axf6oco1elwv" name="Subject" value=<?php echo $articleText ?>>
<!-- <textarea name="Subject" rows=25 cols=150 value=<?php echo $articleText ?>></textarea> -->
</tinymce-editor>
</div>
<button type="submit">Publier</button>
</form>
</div>
</div>
</div>
<script>
tinymce.init({
selector: 'tinymce-editor',
setup: function(editor) {
editor.setContent('<?php echo $articleText; ?>');
}
});
</script>
</body>
</html>`
As you can see there's a commented textarea, that existed before i used the tinyMCE editor. While the editor works, when i'm editing a post i fetch it through the controller with this function:
`function edit_post()
{
// grab post ID
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
if ($id == 0) {
header("Location: http://projet4git/index.php?action=admin");
}
// match post and ID
$Post = new posts_model();
$singlePost = $Post->getOnePostById($id);
require("./views/edit_post.php");
}`
and this function calls the model to fetch the post by its ID :
`public function getOnePostById($id)
{
$query = $query = "SELECT id, titre, message, date FROM posts WHERE id= :id";
$request = $this->db->prepare($query);
$request->bindParam(":id", $id, PDO::PARAM_INT);
$request->execute();
$singlePost = $request->fetch(PDO::FETCH_ASSOC);
return $singlePost ? $singlePost : [];
}`
this all results in the post returning its text directly when the edit_post() function is called, at least when using the textarea instead of the tinyMCE editor, when using the tinyMCE editor the editor itself remains empty instead of displaying the text that it should display, and i'm struggling to figure out why.
PS: my head component does feature the script src for tinyMCE :
`<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../CSS/main.css">
<script src="https://kit.fontawesome.com/50ab74dd38.js" crossorigin="anonymous"></script>
<script src="https://cdn.tiny.cloud/1/0ki8kh44dpr0iupw97fjo8e0x3vrccw5i082axf6oco1elwv/tinymce/6/tinymce.min.js" referrerpolicy="origin"></script>
<script src="https://cdn.jsdelivr.net/npm/#tinymce/tinymce-webcomponent#1/dist/tinymce-webcomponent.min.js"></script>;
<title>Document</title>
</head>`
As i said above, what i expected was to get the text to automatically be inserted within the tinyMCE editor, after some research i found out about getContent() and setContent() from the tinyMCE documentation but those did not work properly, in my best attempt, it would simply send me back an error message saying that $articleText wasnt defined, which i find strange since echo'ing it works fine with the textarea method.
It must be noted that $articleText is a variable that exists when initially publishing a post withing the model,where its defined as the data from the named field "Subject" :
` public function post($data)
{
$articleTitle = htmlspecialchars($data['Title']);
$articleDate = date('Y-m-d');
$articleText = htmlspecialchars($data['Subject'], ENT_QUOTES);
if (!empty($articleTitle) && !empty($articleText)) {
$query = "INSERT INTO posts(titre,message,date) VALUES(?,?,?)";
$request = $this->db->prepare($query);
$request->execute([$articleTitle, $articleText, $articleDate]);
}
//check insertion
if ($request->rowCount() == 1) {
return true;
} else {
return false;
}
}`

Empty data sending into MySQL, instead input value

I have simple php/ajax/mysql chat. But unfortunately when I am sending form into database, php send off empty string to MySQL, how can I fix it ?
Here page.php code, with script:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#messages").load('ajaxLoad.php');
$("#userArea").submit(function(){
$.post('ajaxPost.php', $('#userArea').serialize(), function(data){
$("#messages").append('<div>'+data+'</div>');
});
return false;
});
});
</script>
</head>
<body>
<div class="container">
<div id="messages"></div>
<form method="post" action="ajaxPost.php" id="userArea" style="margin: 0 auto; font-size: 23px; text-align: center;">
<h1>Chat</h1>
<input type="text" name="message" />
<input type="submit" value="send!" />
</form>
</div>
<?php include_once('ajaxLoad.php'); ?>
<?php include_once('ajaxPost.php'); ?>
And ajaxPost.php:
<?php
include_once('page.php');
include('config.php');
$message = $_POST['message'];
$db->Query("INSERT INTO messages(message1) VALUES ('$message')");
echo $message;
?>
If you run: alert($('#userArea').serialize()) it will show you your message.
Get rid of these lines:
<?php include_once('ajaxLoad.php'); ?>
<?php include_once('ajaxPost.php'); ?>
These scripts are only supposed to be used from AJAX, you shouldn't execute them when just displaying the original form. When you execute them with include() there's nothing in $_POST, so you insert an empty message.
You haven't shown what's in ajaxLoad.php, but from the way you use it with $("#messages").load(), I doubt that it should be run with include.
I'm pretty sure that ajaxPost.php works correctly when you call it with $.post(), and the empty rows are coming from the include_once().
I don't think it should prevent the insert, but you also shouldn't have
include_once('page.php');
in ajaxPost.php.

PHP session_id() being overridden

I really don't know how to describes this, but here goes. I'm trying to make a Login for an online multiplayer game (cluedo to be exact) that is written using mainly the LAMP stack (php,js,etc), and creating a session when someone logs in/registers works for me and all and I even save it to a sql database, but it seems that as soon as a next user Logs in/registers the session id to the previous user is overridden to the new ones details. In other words they both now have the same session for some reason.
My Game LogIn basically:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="StyleSheet.css">
<meta charset="UTF-8">
<title>Game Setup</title>
</head>
<body>
<header>
<h1>Game Setup</h1>
</header>
//My form for user details and character select
<form name="Registration" id=Form1 action="Lobby.php" method="POST">
<fieldset>
<legend>Player information:</legend>
<label for="Pid">Player Name(required): </label><br>
<input autofocus type="text" id="Pid" name="Pid" placeholder="Player ID" required><br>
<label for="Avatar">Character(required):</label><br>
<select name="Avatar">
<option value="Miss White">Miss White</option>
<option value="Col Mustard">Col Mustard</option>
<option value="Miss Scarlet">Miss Scarlet</option>
<option value="Mr Green">Mr Green</option>
<option value="Madame Plum">Madame Plum</option>
<option value="Benjamin Blue">Benjamin Blue</option>
</select><br><br>
<input type="submit" value="Register">
</fieldset>
</form>
</body>
and the lobby (where I wait for someone to press game start or for more people to register)
<?php
session_start() ;
session_regenerate_id();
$_SESSION["UserName"]=$_POST['Pid'];
$_SESSION["Avatar"]=$_POST['Avatar'];
?>
<?php require 'DatabaseConnect.php' ?>
<?php include 'Users.php' ?>
<?php
$PlayerID = mysqli_real_escape_string($conn, $_POST['Pid']);
$PlayerChar = mysqli_real_escape_string($conn, $_POST['Avatar']);
$SesID = session_id();
$sql = "INSERT INTO users (UserName, Avatar, sessionID)
VALUES ('$PlayerID', '$PlayerChar','$SesID')";
if ($conn->query($sql) === TRUE) {
echo "Welcome $PlayerID , currently in Lobby: <br>";
$User = new Users();
$User->setUserName($_SESSION['UserName']);
$User->setAvatar( $_SESSION['Avatar']);
$User->isPlaying = false;
$_SESSION['User'] = serialize($User);
?>
<html>
<body>
<div id="Players"> </div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src ="Display.js"></script>
</body>
</html>
<?php
}
else {
if($conn->errno == 1062){//when a userName or Character already in use
$sql = "SELECT * FROM users";
$result = $conn->query($sql);
$sql = "ALTER TABLE users AUTO_INCREMENT = ".$result->num_rows;
$conn->query($sql);
echo "<script type='text/javascript'>alert('ERROR :Username or Character already in use!')</script>";
echo" <script>
window.location = 'LogIn.php';
</script>";
}
}
?>
and then the Display.js runs in a loop until either 6 people connect or a user presses start. It also displays everyone currently waiting for a game by outputting the SQL database, but I don't think that code is necessary to add, but then when that's done I go to the Cluedo.php page and if I echo session_id() there on two different browsers(same machine) I get the same session_id()
<?php
session_start() ;
?>
<?php require 'DatabaseConnect.php' ?>
<?php include 'Users.php' ?>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="StyleSheet.css">
<meta charset="UTF-8">
<title>Cluedo</title>
</head>
<body>
<?php
$User = unserialize($_SESSION['User']);
echo session_id();
?>
</body>
</html>
Also I'm using XAMPP and running it all locally at the moment so don't know if there's a problem there maybe?
Here's an example of my database with the saved values, the table saves unique sessions however when the session_id() is echoed at the Cluedo.php page it is always the last registered user:
UserTable

submit button being created inside of submit button

I'm having a problem with a submit button in a form, when clicked it first reloads the current page, which creates a submit button inside of the original one before posting to the post page.
You can see the behavior example here:
http://tampary.com/pick_game.php?c_id=15&p_id=0&f_id=1&l_id=1
You can click back in your browser after clicking "start game" and you will see the nested controls. Using Chrome and Firefox, you get same results. Any ideas what could be causing this behavior? ideally, I just want the php page to be redirected to after the form submit to just load up cleanly. Any help would be greatly appreciated
The complete code is as follows:
<?php
require_once(dirname(__FILE__).'/grl-lib/db.php');
require_once(dirname(__FILE__).'/grl-lib/ui.php');
require_once(dirname(__FILE__).'/grl-lib/family.php');
require_once(dirname(__FILE__).'/grl-lib/location.php');
require_once(dirname(__FILE__).'/grl-lib/contact.php');
$ui = new x_ui;
$ui->set_ui(1);
if (!empty($_POST)){
$p_id = $_POST['p_id'];
$f_id = $_POST['f_id'];
$l_id = $_POST['l_id'];
$c_id = $_POST['c_id'];
}else{
$p_id = $_GET['p_id'];
$f_id = $_GET['f_id'];
$l_id = $_GET['l_id'];
$c_id = $_GET['c_id'];
}
?>
<!DOCTYPE HTML>
<html lang="<?php echo $ui->getLocale($ui->language_id,1); ?>">
<head>
<?php include_once('grl-lib/gen_include.php'); ?>
<meta name="robots" content="noindex"> <!-- no indexing this page -->
<link href="css/main.css" rel="stylesheet" type="text/css">
<link href="css/devices.css" rel="stylesheet" type="text/css">
<title>Tampary<?php ' '._('game'); ?></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name=viewport content="width=device-width, initial-scale=1">
</head>
<body class="color_bg">
<?php include('standard/header.txt'); ?>
<!-- all content -->
<div class="entire_content_length aling_text_c">
<div class="max_width_responsive align_container_c spc_a_5">
<div class="align_container_c spc_a_5 container_c">
<form id="pick_game" action="game.php" method="post">
<?php
$html = '<input type="hidden" name="p_id" id="p_id" value="'.$p_id.'"><input type="hidden" name="f_id" id="f_id" value="'.$f_id.'"><input type="hidden" name="l_id" id="l_id" value="'.$l_id.'"><input type="hidden" name="c_id" id="c_id" value="'.$c_id.'">';
//$html = $html.'<input type="submit" value="'._('Start Game').'">';
echo $html;
?>
<input type="submit" value="Start Game">
</form>
</div>
</div>
</div>
<?php include('standard/footer.txt'); ?>
</body>
</html>
I see you are using an Ajax script, which is fine. But is definitely the culprit cause I can see it responding the entire page in firebug.
I will bet you that your front page is Ajax to and you append something somewhere (can't find it this fast).
Whatever the case, I'm not convinced that what ever your doing (loading an entire page through AJAX) is good practice.
Looking at your AJAX requests will solve your inception button problem

Updating a Database With PHP

I'm trying to update my database records with the following code but am having no luck what so ever. Anybody care to help? Thanks
<?php include "base.php"; ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Project Sproom</title>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<?php if(!empty($_SESSION['LoggedIn']) && !empty($_SESSION['Username']))
{
if(!empty($_POST['username']) && !empty($_POST['email']))
{
$newusername = mysql_real_escape_string($_POST['username']);
$newemail = mysql_real_escape_string($_POST['email']);
$edit = mysql_query("UPDATE users (Username, EmailAddress) VALUES('".$newusername."', '".$newemail."') WHERE UserID=".$_SESSION['UserID']."");
// }
?>
<div id="container">
<div id="homemenu">
<ul id="navlist">
<li id="active">Home</li>
<li>Edit Profile</li>
</ul>
</div>
<div id="homemain">
<h1>Edit Profile</h1>
<p>This will be the edit profile when i have figured out how to do it...</p>
<br />
<form method="post" action="profile.php" name="editprofile" id="editprofile">
<label for="username">Username: </label> <input type="text" name="username" id="username" value="<?=$_SESSION['Username']?>"/><br />
<label for="email">E-Mail: </label> <input type="text" name="email" id="email" value="<?=$_SESSION['EmailAddress']?>"/> <br />
<input type="submit" name="editprofile" id="editprofile" value="Submit" />
</fieldset>
</form>
</div>
</div>
<?php
}
else
{
?>
<meta http-equiv="refresh" content="0;index.php">
<?php
}
?>
You're using INSERT syntax for an UPDATE query. The syntax should be like this:
UPDATE users SET Username = 'username', EmailAddress = 'email' WHERE UserID = 1;
Docs here.
You haven't connected to the MySQL database, have you?
I didn't see that in this code...
Or is that part of the included "base.php" on top of this script?
I am afraid you need fist establish a connection to a certain MySQL database before trying to update a row in a table.
Edit:
Okay, well then. Try issue the following line of code after the update:
echo "edit was " .$edit;
This is to check whether the update query was executed successfully (in which case it should echoes true) or failed (in which case it echoes false).
So at least you can tell the result of such a mysql_query.
$edit = mysql_query("UPDATE users SET Username='".$newusername."', EmailAddress='".$newemail."' WHERE UserID=".$_SESSION['UserID']."");
Try this

Categories