OpenCart Securimage PhpCaptcha weird behavior - php

I have downloaded securimage library from phpcaptcha, unzippped it into system/library/securimage and done the following:
index.php:
require_once(DIR_SYSTEM . 'library/securimage/securimage.php');
$registry->set('securimage', new Securimage($registry));
catalog\view\theme\my_theme\template\information\contact.tpl:
<form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data">
...
<img id="captcha_img" src="index.php?route=information/contact/securimage" alt="CAPTCHA Image" />
<a href="#" onclick="document.getElementById('captcha_img').src = 'system/library/securimage/securimage_show.php?' + Math.random(); return false">
<img src="system/library/securimage/images/refresh.png" height="25" width="25" alt="Reload Image" onclick="this.blur()" align="bottom" border="0"></a>
<label for="captcha" class="required"><?php echo $entry_captcha; ?></label>
<input type="text" id="captcha" name="captcha" size="31" maxlength="6" value="" onblur="check('captcha');" />
<span class="txt"><?php echo $entry_captcha_tip; ?></span>
<br />
<?php if ($error_captcha) { ?><span class="error_txt"><?php echo $error_captcha; ?></span><?php } ?>
...
catalog\controller\information\contact.php:
protected function validate() {
$this->log->write('SESSION CODE: ' . $this->session->data['captcha']);// 2nd variable in log
$this->log->write('REQUEST CODE: ' . $this->request->post['captcha']);// 3rd variable in log
...
if (empty($this->session->data['captcha']) || ($this->session->data['captcha'] != $this->request->post['captcha'])) {
$this->error['captcha'] = $this->language->get('error_captcha');
}
}
public function securimage() {
$this->session->data['captcha'] = $this->securimage->getCode();
$this->log->write('IMAGE CODE: ' . $this->session->data['captcha']); // 1st variable in log
$this->securimage->show();
}
...
Now, this is how it works:
Image loads fine, and reloads fine as well
Say, the first image code is abc123
I enter abc123 into captcha field, press submit
The error['name'] shows abc123, while error['email'] shows some other code
Now say, the image shows def456, I enter def456 into the captcha field and press submit
Now the error['name'] shows def456, but the error['email'] shows abc123!
Can anyone explain what's going on? How is it possible that the $this->session->data['captcha']; is 2 steps behind? Please help me fix it. How can I actually get the correct image code before the submit. Thank you.
[EDIT]
The weird behavior continues... (considering the logged variables):
The first time I visit the contact page, 1st variable IMAGE CODE = kzycbc, 2nd and 3rd are empty, the image on the page shows code eslmmg
I reload the page (without filling in the form), 1st variable IMAGE CODE = *eslmmg, 2nd and 3rd are empty, the image on the page shows code cnsf6u
I fill in the form and enter cnsf6u in the captcha field and press submit, the log shows SESSION CODE = eslmmg, REQUEST CODE = cnsf6u, IMAGE CODE = cnsf6u, image on the page has zvkht7
I enter zvkht7 in the captcha field and press submit, the log shows SESSION CODE = cnsf6u, REQUEST CODE = zvkht7, IMAGE CODE = zvkht7, image on the page has a new code
It looks to me, first, the IMAGE CODE is loaded twice on the first page load, the getCode() takes the first code, while the image on the page loads again, which is then stored in the session variable and shown as IMAGE CODE. This only happens on the very first load of the page. Then, after the second submit, the session takes the value from the previous submit, not from the one just made, while the request code is correct.
What does this tell you? Can anyone help please? The IMAGE CODE and SESSION CODE should be the same. Why do these value differ in securimage() and validate()? As the REQUEST CODE = IMAGE CODE, looks like the image code is correctly taken by the securimage() session, but as the SESSION CODE != IMAGE CODE, where does validate() session takes its value from? Why does it only update the value on the next submit?
[SOLVED]
The solution is much simpler than one might think. All it needs is simply this:
protected function validate() {
...
if (!$this->securimage->check($this->request->post['captcha'])) {
$this->error['captcha'] = $this->language->get('error_captcha');
}
}
public function securimage() {
$this->securimage->show();
}
And no need to use the session! Looks like Securimage handles that itself. Huge thank to drew0!

Related

Post File Data VIA INPUT FORM

i have a form for uploading files / images. I have no problem uploading and displaying the images , but i want to forward the images back to the same page that the imageas where selected, and use the POST data to place the image chosen in the 1st place , so the user can view and then if wanting to change the image for another.
The Problem i am having though is posting the flie back.
I have tried using it as a veriable and just using the variable to display an image but when i send that back to the image selection page, it does not display anything and if the user does not select a new image , the image data is not sent either..
i know im short cutting my explanation but i hope sum1 can help
here is my code (simplyfied)
THE INPUT FORM
<input type='file' class='fileinput' id='sellimage0' name='sellimage0' onchange='addimg0(this , img0, mainimage);' accept='image/*' /></input>
THE RECEIVER
if (!empty($_FILES['sellimage0']['name'])){
$image_path0 = $_FILES['sellimage0']['name'];
$image_path0 = filter_var($image_path0, FILTER_SANITIZE_STRING);
$image_path0 = strip_tags($image_path0);
$i0url=$image_path0;
} else {$i0url='';}
THE DISPLAY
<?php if (!empty($i0url)) { echo "
<div class='image0' id='image0' title='1st Image' >
<img id='img0' src='{$i0url}' class='imageclass'></img>
<input type='hidden' id='img0' name='sellimage0' value='{$_FILES['sellimage1']['name']}' ></input>
</div>
"; } ?>
THE POST BACK & RECEIVE
if (!empty($_FILES['sellimage0']['name'])){
$image_path0 = $_FILES['sellimage0']['name'];
$image_path0 = filter_var($image_path0, FILTER_SANITIZE_STRING);
$image_path0 = strip_tags($image_path0);
$i0url=$image_path0;
} else {$i0url='';}
<img id='img0' <?php if (!empty($i0url)) { echo " src='{$i0url}' "; } else { echo " src='' style='opacity:0;' "; } ?> onclick=' document.getElementById("sellimage0").click();' class='imageclass' ></img>
<div class='cancel' onClick='cancelimage(sellimage0 , img0);'> </div>
<div class='magnify' > </div>
<input type='file' class='fileinput' id='sellimage0' name='sellimage0' onchange='addimg0(this , img0, mainimage);' accept='image/*' /></input>
I hope this is making sense to you all.
i wish to choose an image, then post that choice to a view page
then from the view page , user has option to go back and edit
but how do i send the form data back to be received correctly so i can send the file back and forth between edit and review...
The way i have been trying just removes the selected images when i go back to the mainpage again.. iv tried many methods, but im lost on how to do this correctly.. Iv looked on the net to but finding my specific problem seems to be difficult.
Thank you.

How to call php function on html form submit - in the same page

Okay so I have an html form in Add.html. When I click submit, I would like the data to be added to my database via php and then return to the same form with "instance added" or "failed blah blah."
The only way I know how is to set the form action to a separate php file and call that - but then the php file renders and I do not return to the same form.
I would like to not have to add a "return to form" button and would prefer to return to the form on submit with a status message.
Any better ways to do this?
A very simple way to do is to do following :
yourpage.php
<?php
if(isset($_POST)){
//data posted , save it to the database
//display message etc
}
?>
<form method="post" action="yourpage.php" >....
You can do a redirect in php, to the html form - and you can set a "flash message" - to show "instance added" by saving "instance added" to the session and showing that value when you redirect to html.
you can use this trick
<?php if (!isset $_POST['Nameofyourinput']){
?>
<form method="post" action="add.html">
// your inputs here along with the rest of html
</form>
<?php
}
else
{
// Update you database and do your things here
//in your request variable you can add the error you want if things didn't go well, for example
$result = mysqli_query($connection, $sql) or die('Instance not added !'.$req.'<br>'.mysql_error());
// and then
echo (" instance added")
};
The action attribute will default to the current URL. It is the most reliable and easiest way to say "submit the form to the same place it came from".
Just give nothing to the action attribute. It will refer to your current page.
<form method="post" action="">
Other way to do this are:
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Or just add '#'
<from method="post" action="#">
To handle php code. Write your code inside it.
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// write your code here.
}
You should change your file extension from .html to .php .
Well you can employ old school AJAX. For instance,let's say we have a form that takes in a number N,and once we click the calculate button we should see the result the of 2^N displayed on the same page without the page being refreshed and the previous contents remaining in the same place. Here's the code
<html>
<head>
<title> Simple Math Example</title>
<script type="text/javascript">
var request = new XMLHttpRequest();
function createAjaxObject(){
request.onreadystatechange = applyChange;
request.open("POST","calculate.php",true);
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
request.send("N="+document.getElementById('N').value);
}
function applyChange(){
if(request.status == 200 && request.readyState == 4){
document.getElementById('resultSpace').innerHTML = request.responseText;
}
}
</script>
</head>
<body>
<fieldset>
<legend>Enter N to get the value of 2<sup>N</sup> ::: </legend>
<input type="text" name = "N" id = "N">
<br>
<input type="button" value = "Calculate" onclick="createAjaxObject()">
</fieldset>
<div id="resultSpace">
</div>
</body>
The file calculate.php is the same file with the above code. When the calculate button is clicked, it calls a function createAjaxObject which takes in a value N and sends the value to the same file via the POST method. Once the calculation is done, a response will be sent. And if the response is successful, it will be sent to a function called applyChange which will render it to the same page via JavaScript.

Simple Captcha in PHP with rand()

I'm trying to make a simple captcha in PHP, but it does not work. The query is not currently executing. This is my current code:
<?php
$Random = rand(1, 100);
$Random2 = rand(1,100);
echo "Result: ".$Random." + ".$Random2." ?";
?>
<input type="text" name="r_input"/><br />
$Cap = mysql_real_escape_string($_POST['r_input']);
$Result = $Random+$Random2;
if(isset($_POST['myButton']) and trim($Var) and trim($Var2) and trim($Var3) and $Cap==$Result){
//My Query
}
When you use rand() to generate 2 values, and show those 2 values, and give the form for the user to enter the answer, ...
... the user enters the answer and submits back to the server ...
... the server gets the answer, and then GENERATES 2 NEW VALUES, that don't correspond to the answer given by the user.
Try using session variables to store the generated values in, and match against when the user submits the form!
<?php
session_start();
$captcha_id = 'captcha_' . rand();
$_SESSION['$captcha_id']['val1'] = rand(1,1000);
$_SESSION['$captcha_id']['val2'] = rand(1,1000);
echo "
<form action='' method='post'>
<p>Result: {$_SESSION['$captcha_id']['val1']} + {$_SESSION['$captcha_id']['val2']} = </p>
<input type='hidden' name='captcha_id' value='{$captcha_id}' />
<input type='text' name='captcha_answer' />
<p>?</p>
</form>
";
if (
isset($_POST['captcha_id'])
&& isset($_SESSION[$_POST['captcha_id']])
&& isset($_POST['captcha_answer'])
&& $_SESSION[$_POST['captcha_id']]['val1'] + $_SESSION[$_POST['captcha_id']]['val2'] == intval($_POST['captcha_answer'])
) {
unset($_SESSION[$_POST['captcha_id']]); // don't let this answer be reused anymore.
// do allowed stuff
}
?>
Because $Random and $Random2 have a different value each time.
When you show the form for the first time, they may have the values $Random = 12 and $Random2 = 26. The User sees those, adds them up correctly and types in 38 (which is the correct answer for those two values). The answer is sent to the script again, the values of $Random and $Random2 are generated again (this time as $Random = 23 and $Random2 = 30 which equals 53) and the answer the user has sent is not correct any more.
So you would need to store those values in hidden fields and add these up, instead of the generated ones, like so:
<input type="hidden" name="rand_1" value="<?php echo $Random; ?>">
<input type="hidden" name="rand_2" value="<?php echo $Random2; ?>">
<?php
if ($_POST['rand_1'] + $_POST['rand_2'] == $_POST['r_input']) {
// Query etc.
EDIT: As suggested by #nl-x you should use the Session variables instead of hidden fields to prevent abuse of the captcha:
<?php
$Random = $_SESSION['rand_1'] = rand(1, 100);
$Random2 = $_SESSION['rand_2'] = rand(1,100);
echo "Result: ".$Random." + ".$Random2." ?";
?>
And check those values against the given result afterwards:
<?php
$Cap = mysql_real_escape_string($_POST['r_input']);
$Result = $_SESSION['rand_1'] + $_SESSION['rand_2'];
if ($Result == $Cap) {
// ...
You never re-enter PHP mode after you output your form field:
<input type="text" name="r_input"/><br />
<?php // <----this is missing
$Cap = mysql_real_escape_string($_POST['r_input']);
Pardon me, but you are not making a real captcha. The purpose of the captcha is to distinguish the human from the bots. I would highly suggest you to pick a image database, and randomize a function to call a image. Internally, i would check if the text/description of the image matches with what the user typed.
The only thing you will rand() is what image to load from your image database.
That's a not-healthy way to do it, and there are plenty of better ways to do this. But it's more closer to a captcha than just your current code.
There is also a lot of libraries and engines that can do the job for you.
I'm not a pro at PHP, or even programming at all, but i think you're going to the wrong side - your code won't block any... malicious actions at all, or whatever kind of action that you will try to prevent with the captcha.
Search google for the libraries. PhpCaptcha is one of them. And here is a very simple quickstart guide for phpcaptcha.
Here's a code example, extracted from PHPCaptch that I linked above.
At the desired position in your form, add the following code to display the CAPTCHA image:
<img id="captcha" src="/securimage/securimage_show.php" alt="CAPTCHA Image" />
Next, add the following HTML code to create a text input box:
<input type="text" name="captcha_code" size="10" maxlength="6" />
[ Different Image ]
On the very first line of the form processor, add the following code:
<?php session_start(); ?>
The following php code should be integrated into the script that processes your form and should be placed where error checking is done. It is recommended to place it after any error checking and only attempt to validate the captha code if no other form errors occured. It should also be within tags.
include_once $_SERVER['DOCUMENT_ROOT'] . '/securimage/securimage.php';
$securimage = new Securimage();
This includes the file that contains the Securimage source code and creates a new Securimage object that is responsible for creating, managing and validating captcha codes.
Next we will check to see if the code typed by the user was entered correctly.
if ($securimage->check($_POST['captcha_code']) == false) {
// the code was incorrect
// you should handle the error so that the form processor doesn't continue
// or you can use the following code if there is no validation or you do not know how
echo "The security code entered was incorrect.<br /><br />";
echo "Please go <a href='javascript:history.go(-1)'>back</a> and try again.";
exit;
}
Following the directions above should get Securimage working with minimal effort.
This code is included here as well.
Good luck!

PHP | Captcha won't write to $_SESSION

i'm building a form + form validation class , and i also wanted to add captcha to this.
The captcha image is showing, however it itsn't storing anything in the $_SESSION.
I am using this captcha script:
https://github.com/gesf/captcha.class.php
Now in my controller i use this :
$data['regform']->addfield('user_captcha', 'Human verification', 'captcha', 'captcha' );
And that generates the following :
<label>
<span>Human verification</span>
<img name="user_captcha" src="http://www.websiteurl.com/dev/misc/captcha.php?c=1"><input type="text" name="user_captcha" value="" />
</label>
The image is showing like it should. However i'm not able to validate the input because it's not writing to the session. Now in the image file captcha.php it loads the class Captcha , and in this class constructor it tries to write to the session :
function Captcha($letter = '', $case = 5) {
$this->_capCase = $case;
if (empty($letter)) {
$this->StringGen();
} else {
$this->_capLength = strlen($letter);
$this->_capString = substr($letter, 0, $this->_capLength);
}
#session_start();
$_SESSION['asd'] = 'asd';
$_SESSION["CAPTCHA_HASH"] = sha1($this->_capString);
$this->SendHeader();
$this->MakeCaptcha();
}
My session always stays empty. But when i try the following :
<?php $_SESSION['bleh'] = 'asd'?>
<?php echo $form; ?>
It adds 'bleh' to the session like it should.
I really can't see why it won't write to the session..
could someone help me out ??
Thanks!!
Make sure, that session_start() is called before any output for every single page. As I can see, you are using # operator, that shuts up some errors. Can you remove it and tell us what does it output?
Also, your sessiaon_start() call is somewhere in the middle of the script. Perhaps there are some other output before that.

setting textarea to empty yet it reloads variable data on submission

If I set my text area in my edit page to blank and I hit submit, it reloads the page with an error as its supposed to but it also loads the summary text from my php variable. instead it should stay blank.
Here's what I've tried:
<textarea name="summarytxt" cols="52" rows="7">
<?php
if ( isset($_POST['updatebtn']) AND (!empty($POST['summarytxt'])) ){
echo #$POST['summarytxt'];
}
elseif ( isset($_POST['updatebtn']) AND (isset($POST['summarytxt'])) ){
echo #$POST['summarytxt'];
}
else{
$summary=stripslashes($data['summary']);
echo $summary;
}
?>
</textarea>
I was hoping the elseif condition will fix it but it doesn't seem to work:
elseif ( isset($_POST['updatebtn']) AND (isset($POST['summarytxt'])) )
The above to me meant if the button is clicked and the text area is set echo whatever is in the text area.
Any suggestions on what I'm doing wrong or how I can fix it?
Edit:
I basically want to know the following:
if say i have field summarytxt and an array called data['summary'] i need:
1. on page load, load from data['summary']
2. if the user clears the summarytxt, on page submit, it should be blank inside summarytxt
i have tried the following which seems to work...
<?php
if (!isset($_POST['updatebtn'])){
$summary=stripslashes($data['summary']);
echo $summary;
}else{
echo $_POST['summarytxt'];
}
?>
Now i'm having some trouble with my drop down box:
1. when i change it from a product to 'select' which is what you get in the add form, and i update the page. instead of sticking to select its loading the product it had when i opened the form.
Can somebody please show me a simple way of this? thanks!
So I would do this similar to (remember about php and html separation):
<?php
$summary = "";
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
$summary = stripslashes($_POST['summarytxt']);
}
?>
<textarea name="summarytxt" cols="52" rows="7"><?php echo $summary; ?></textarea>

Categories