My website allows users to input and upload 2 things:
Their name - which they type into a textfield in an HTML form
And a photo - which they upload from their computer also using this same form.
Upon hitting "submit" my Javascript code calls a PHP script sitting on my server, that PHP script takes that data and writes it into a JSON file, puts that file in the right folder, also puts the image where it needs to go - and it all works perfectly thus far.
However, it just dawned on me that anyone reading my Javascript code can find the URL of my PHP script - which means they can then copy-paste that URL directly into the browser - and wreak all sorts of havoc.
Obviously I need to go about all this in a different way.
Should I just not use PHP for this? If so, what other languages or platforms are available for me to do what I just described - in a way that's impossible to hack?
Or is there a way to obfuscate the URL of my PHP script so that no one can copy-paste it into the browser address bar?
Any advice would be greatly appreciated!
================================
UPDATE:
Here’s my PHP script:
<?php
$tokenID = $_POST["tokenIDNum"];
$fileName = "TokenMetadata/token". $tokenID .".json";
$userName = $_POST["userName"];
$imageURL = $_POST["userImageURL"];
// Log out for verification:
echo "Here's what I got so far:<br/>";
echo "tokenID: " .$tokenID ."<br/>";
echo "userName: " .$userName ."<br/>";
echo "imageURL: " .$imageURL ."<br/>";
// CREATE AND SAVE THE NEW METADATA-FILE:
$newMetadataFile = fopen($fileName, "wb");
if( $newMetadataFile == false ) {
// Do debugging or logging here:
echo "OPPS! We got an 'fopen' problem!";
}
else {
$contentString = "{\r\n";
$contentString = $contentString. ' "name" : “Fun Token # ' . $tokenID . '",';
$contentString = $contentString. "\r\n";
$contentString = $contentString. ' "description" : "Another token from our FUN Collection.",';
$contentString = $contentString. "\r\n";
$contentString = $contentString. ' "image" : "' .$imageURL;
$contentString = $contentString. "\r\n}";
fwrite($newMetadataFile, $contentString);
fclose($newMetadataFile);
}
// or die("Unable to open file!");
// $myfile = fopen("token.json", "w") or die("Unable to open file!");
?>
When I copy-paste the URL for this script into my browser - which is what I worry some bad actor might do - it creates a new EMPTY JSON file - and that's without me passing any arguments into that URL. So I'm pretty sure right now someone could not only create new phoney JSON files in this manner, but also rewrite existing ones with false data if they were to pass values for my arguments.
What I need to know is if it's even possible to prevent bad actors from doing this - or if I have to go about this in some totally different way?
My understanding is that if I add SESSION and perhaps CAPTCH I might be ok? (Obviously, I'm no PHP expert.)
Would love any thoughts/suggestions regarding that - before I spend hours going down that rabbit hole.
Related
I have a php code as shown below in which there is an if condition.
php:
if(mysqli_num_rows($result1) > 0){ // Line X
while($row = mysqli_fetch_array($result1)){
if($row['open'] == "true") {
if(!isset($_SESSION['admin'])) {
$message = "user " . $row['user_name'] . " is currently editing the form. Want to take over ?"; // Line B
echo "<script type='text/javascript'>if(confirm('$message')) { } else { };</script>"; // Line A
}
break;
}
}
}
I was able to integrate $message at Line B.
I am wondering what changes I should do at Line A so that I can integrate the following code in the curly braces of the if(confirm('$message') block:
$username = $_SESSION['user_name'];
$open="true";
$write="1";
$stmt=$connect->prepare("UPDATE trace_users SET write=0 WHERE write=1"); // revoke write access of all users
$stmt=$connect->prepare("UPDATE trace_users SET open=?, write=? WHERE user_name=?");
$stmt->bind_param('sss', $open, $write, $username);
$stmt->execute();
Unfortunately user1950349, this is a bit more complex than it may seem because your idea is closer to how a desktop app would where there is a message loop which allows the code to respond to user input. But with a webpage generated by php and sent over the internet, we do not have a message loop to work with. Thus, we have figure out a way to get the server and the user's computer to message back and forth without any additional webpage loads.
This is where AJAX would come into play; however, an explanation of how to use that for your use case would depend on how you implement AJAX. For instance, you might use jQuery or some other javascript library.
It is a good practice if you avoid mixing two different languages together.
When mixing these two the complexity of your code increases.
Since you need the answer here you go
echo "<script type='text/javascript'>if(confirm(" . $message . ")) { } else { };</script>";
Inside echo's double/single quotes(" / ') everything is considered as a string, so to access your PHP variable you need to use the concatenation method to use that PHP variable.
if(confirm(" . $message . "))
UPDATE
You need to follow the same steps, as described above. You need to use the string concatenations.
But that will be very complex and as well as very difficult to make debugging.
You can use a better approach using XHR request or you can design the PHP code in a better way to use it with your JavaScript code.
I am trying to build a simple web page where a user is prompt to click on an image as many times as desired. Eventually, after user is done s/he should click a link saying "I'm done" that should trigger the server to write to disk a sting (let's say: "I clicked x times", which I can manage to get).
I tried:
<a onclick="WriteNGo()" href="next_index.html">I am Done</a>
and of course:
function WriteNGo() {
$.ajax({
type: "POST",
url: 'php/save.php',
data: {writeMe: textToWrite}
});
}
where textToWrite is a global variable that contains the string. I can
alert(textToWrite)
it and get the required sentence.
and added php/save.php at the correct location:
<?php
$data = $_POST['writeMe'];
$f = "../d/data.txt";
file_put_contents($f,$data,FILE_APPEND);
?>
and did a
sudo chmod +777 d
on the folder.
I only want to end up with a text file containing my string, (i.e. "I clicked x times"). I am not even sure that the POST command triggers the PHP server.
One more thing: the index.html is in the root dir, where I am currently running:
php -S localhost:8000
So that there should have not been any problems.
I should also state that there was one time that the string was written, though I can't reproduce this it.
Not sure if this might address your problem. Maybe, try something like this to see, where your data might be written:
<?php
$data = $_POST['writeMe'];
$path = "../d";
$dir = $path . "/";
if (!is_dir($dir)) {mkdir($dir, 0755, true);}
// A faster alternative to file_put_content
$f = $dir . "/data.txt";
$fp = fopen($f, "x+");
fwrite($fp, $data);
fclose($fp);
?>
I've been trying for a while to rewrite a php code into node.js, but I've encountered a problem.
This is the PHP code I'm stuck on (a little bit modified):
$fp = fopen($privateKeyFileName, "r");
$priv_key = fread($fp, 8192);
fclose($fp);
echo "PRIVATE KEY: <br/><br/>";
var_dump($priv_key);
$pkeyid = openssl_pkey_get_private($priv_key, $privateKeyPassword);
echo " <br/><br/>PRIVATE KEY ID: <br/><br/>";
var_dump($pkeyid);
openssl_sign($message, $signature, $pkeyid);
openssl_free_key($pkeyid);
echo " <br/><br/>SIGNATURE: <br/><br/>";
var_dump($signature);
$message .= $signature;
echo " <br/><br/>END MESSAGE: <br/><br/>";
var_dump($message);
The part I'm stuck on is: openssl_pkey_get_private. I'm not sure how to replicate it. I tried skipping it, a let crypto (nodejs) do the work, but with no luck.
The interesting thing that needs to be done is: everytime, when I sign the message, $signature has 128 characters (string). This is an requirement, and this is my problem in node.
This is my nodejs code:
function signData(data) {
var sign = crypto.createSign('RSA-SHA256');
sign.update(data);
var signed = sign.sign(privateKey);
return signed;
}
And another thing, this RSA-SHA256 has to be SHA1withRSA. This example never generates exactly 128 char string. It returns a buffer, and no matter how I parse or convert it, I can't achieve the requirement. I'm using the same private key on both examples.
Any ideas?
I'll try to be thorough and brief here. I am currently working in Joomla for the first time, but I've developed before. I am using Joomla 3.4. What I am trying to do:
A user signs up for our newsletter through a specific page that directs them to a coupon.
The next page shows them the coupon and has an email tag in the URL (i.e. &email='email')
I am trying to code within a module to parse out that email and send a copy of the coupon to that users email automatically.
I can't use a general automatic email when any user subscribes, because only users that sign up from that specific page will get the coupon. I have turned all text filtering off and am using basic module editor. When I save the module, the code shows just fine in the edit box. When I viewed the source of the page, that script tags would still be there, but the code would all be blank. I have now gone into phpmyadmin and can edit the module directly there. Now, the script is showing up just fine.
I've tried many different fixes, including adding a jQuery($) function load in order to bypass any issues with mootools. Wondering if it was an issue with Javascript, I cleared the script and made a simple alert("Testing..."); script that fired just fine on the page. This means that there must be something within my full script that is not working correctly. Any help or other ideas would be wonderful. I have spent over a day on this already and am at wits' end. Here's the code:
<script type="text/javascript">
function get(name){
if(name=(new RegExp('[?&]'+encodeURIComponent(name)+'=([^&]*)')).exec (window.location.search))
$recipient = decodeURIComponent(name[1]);
}
$mailer = JFactory::getMailer();
$config = JFactory::getConfig();
$sender = array(
$config->get( 'config.mailfrom' ),
$config->get( 'config.fromname' )
);
$mailer->setSender($sender);
get('email');
$mailer->addRecipient($recipient);
$body = '<h2>Thank you for joining our mailing list!</h2>
'<div>Here is your coupon for a FREE 8" 1-topping pizza at Goodfellas!'
'<img src="http://www.goodfellas309.com/main/images/pizzacoupon.jpg" alt="pizza coupont"/></div>';
$mailer->isHTML(true);
$mailer->Encoding = 'base64';
$mailer->setSubject('Your Free Pizza!');
$mailer->setBody($body);
$send = $mailer->Send;
if ( $send !== true ) {
echo 'Error sending email: ' . $send->__toString();
} else {
alert("An email with your coupon has been sent to you! Thank you for joining our mailing list!");
}
');
</script>
I have even attempted an inline PHP parse through Joomla with this code wrapping the javascript:
<?php
$document = JFactory::getDocument();
$document->addScriptDeclaration('
-Javascript here-
');
?>
I've always loved StackOverflow, and the answered questions have gotten me out of so many jams. I just can't find the answer to this anywhere. Thanks for your time!
Put the following inside your module.
<?php
// Get the email from the url
$jinput = JFactory::getApplication()->input;
$recipient = $jinput->get('email', '', 'string');
$mailer = JFactory::getMailer();
$config = JFactory::getConfig();
$sender = array(
$config->get( 'config.mailfrom' ),
$config->get( 'config.fromname' )
);
$mailer->setSender($sender);
$mailer->addRecipient($recipient);
$body = '<h2>Thank you for joining our mailing list!</h2>'
.'<div>Here is your coupon for a FREE 8" 1-topping pizza at Goodfellas!'
.'<img src="http://www.goodfellas309.com/main/images/pizzacoupon.jpg" alt="pizza coupont"/></div>';
$mailer->isHTML(true);
$mailer->Encoding = 'base64';
$mailer->setSubject('Your Free Pizza!');
$mailer->setBody($body);
$send = $mailer->Send;
if ( $send !== true ) {
echo '<script type="text/javascript">Error sending email: ' . $send->__toString() . '</script>';
} else {
echo '<script type="text/javascript">alert("An email with your coupon has been sent to you! Thank you for joining our mailing list!");</script>';
}
Note: Depending on where you're putting this code you might need an extension like this one to make the php run.
<a class='okok' id='$file' href='" . $_SERVER['PHP_SELF'] . "?file=" . $file . "'>$file</a>
The above code is a link which passes its name to the variable 'file' which then gets displayed in the URL as:
http://example.com?file=thefile.html (whatever the file is)
Using PHP, I can now retrieve the variable from the URL and then process it (in this case the variable is 'thefile.html'.
How would I use Sessions to prevent variables from getting passed onto the URL. So instead of:
http://example.com?file=thefile.html
I would have:
http://example.com
And the variable 'thefile.html' would be stored in a Session.
If you need more info on what I am trying to ask, then please ask.
You've got to create a valid page for receiving the query string you're passing in the url
suppose the link you have is on index.html and your link destination is result.php, then you'd write the following code in result.php
<?php
session_start();
if( isset($_GET["filename"]) ){
$fname = $_GET["filename"];
//code to deal with filename
//save in session variable
$_SESSION['UploadedFilename'] = $fname;
}
?>
<!-- html -->
<?php
session_write_close();
?>
If you wanted to pass the file name from the browser (where the link is) to the host without a parameter, you would need to use a cookie. Sessions are a host concept.
So, as a simple example, you could use:
<a class='okok' id='$file' href='" . $_SERVER['PHP_SELF'] . "' onclick="document.cookie='filename=" . $file . "';">$file</a>
This creates a cookie with the filename in it.
On the host side, you retrieve the name with $_COOKIES['filename'].