security for a simple php search form - forms

I have a table that lists movies and I have incorporated a simple search function.
I have one text field in a form where a title or keyword can be entered and then the form is submitted.
php/mysql code that does the work is:
$find = $_POST['find'];
$find = mysql_real_escape_string($find);
$find = htmlspecialchars($find);
$sql = "SELECT * FROM tbl_buyerguide WHERE rel_date BETWEEN NOW() AND DATE_ADD(now(), INTERVAL 2 MONTH) AND title LIKE '%".$find."%' ORDER BY title";
where 'find' is the name of the text input in the search form.
This works well enough for the search functionality for the required purpose.
My question to all is:
Is the mysql_real_escape_string and htmlspecialchars enough to make my search form secure?
I have read all of the questions that I can find on stackoverflow about this, but I would really like someone in the know to just say to me "yes, that is all you need", or "no, you also need to take into account ...".
Thanks in Advance.
Cheers Al.

Remember the adage: Filter In, Escape Out.
You're not outputting the term there, so why are you escaping it for HTML purposes with htmlspecialchars()?
Instead, ONLY escape it for the database (you should be using prepared statements, but that's another point). So you should not be using htmlspecialchars there.
Instead, when you go to output the variable onto the HTML page, that's when you should escape it for HTML (again, using htmlspecialchars).
Right now, you're mixing database and html escaping, which is going to lead to neither being effective...

Yes it is enough to make it secure....you could always throw strip_tags() in there as well....
Although I would just do it in one line...instead of using three
$find = htmlspecialchars(mysql_real_escape_string($_POST['find']));
But to really make it secure and up to date, you should stop using mysql_* functions as they are deprecated, and will be removed in any future relases of PHP....
You should instead switch to either mysqli_* or PDO, and implement prepared statements which handles security for you.
Example...in PDO
$db = new PDO('mysql:server=localhost;dbname=test', 'username', 'password');
$find = $_POST['find'];
$query = $db->prepare('SELECT * FROM tbl_buyerguide WHERE rel_date BETWEEN NOW() AND DATE_ADD(now(), INTERVAL 2 MONTH) AND title LIKE :like ORDER BY title');
$query->bindValue(':like', '%' . $find . '%');
$query->execute();

Related

Extract Two Value between special characters with Preg_Match

Hello I want to Extract the username and Password value with one preg_match_all
$url='http://xxxxxxxx.com:80/get.php?username=xxxxxx&password=xxxxxx&type=m3u_plus';
I get wiht this explode where i want but i know is more effect with preg_match_all can you show me how.?
$url_ext = parse_url($url);
$username=explode ("&",explode("=",$url_ext['query'])[1]);
$password=explode ("&",explode("=",$url_ext['query'])[2]);
I try with this code but not working
$lotes_fil='~https?://.\=(.+?)&~';
preg_match_all($lotes_fil,$url,$link_pre);
It is better to use parse_url and parse_str like explained here.
But, if you really want a regex, this does the job:
(?<=[?&])([^&=\r\n]+)=([^&=\r\n]+)
preg_match_all('/(?<=[?&])([^&=\r\n]+)=([^&=\r\n]+)/', $url, $matches);
The parameter name is in group 1, the value in group 2
Demo & explanation

issue with DLOOKUP syntax error for new database

I have a database with 4 tables but primarily it is a diversion table/form (DiversionT/F) and a payback table/form (PaybackT/F). Basically, when my program loans parts to other programs in my organization a diversion is created in DiversionT. When the program want to payback they create a payback entry in PaybackT.
I have an issue that I am confused about: On PaybackF the user enters an NSN (long part code) that they want to payback. Ultimately, I want some of the form to auto populate with part info based on the NSN entered. The info is stored in DiversionT. I have created a few text boxes on PaybackF to show the info. The first text box I am trying to autofill based on the NSN is a textbox called PartName. It should search DiversionT for that NSN and fill in the appropriate PartName on PaybackF. In the control Source for the box I typed:
=DLookUp("[PartName]","[DiversionT]", "[PartName]=" & Forms![PaybackF]!NSN)
I get the following error:
The expression you entered contains invalid syntax.
To be perfectly honest I don't really understand VBA yet (spent my life until now with C, C++, Java, and Python) but looked up the function on the Microsoft site.
If I am not going about this right, please also let me know?
When using DLookup to get data, if you are dealing with text strings, you need to ensure that you use single quotes to wrap the text in.
Also, I think that your logic in the DLookup is slightly wrong. I think that this is what you are after:
=DLookUp("[PartName]","[DiversionT]", "[NSN]='" & Me!NSN & "'")
Regards,
You can't enter VBA in to form properties like source control. VBA is only used in procedural code in the VBE. That being said, there is a DLOOKUP function available to form fields and the syntax is similar. This is a cause of your confusion.
EXAMPLE SYNTAX FOR NUMBERS:
=DLookUp("[PartName]","DiversionT", "[PartName]=" & [NSN])
EXAMPLE SYNTAX FOR STRINGS:
=DLookUp("[PartName]","DiversionT", "[PartName]='" & [NSN] & "'")
NOTE:
I can't tell what form you are on or if NSN is from a parent form or subform. Basically, NSN needs to be readable from the same form where that text field exists.

Handle POST data sent as array

I have an html form which sends a hidden field and a radio button with the same name.
This allows people to submit the form without picking from the list (but records a zero answer).
When the user does select a radio button, the form posts BOTH the hidden value and the selected value.
I'd like to write a perl function to convert the POST data to a hash. The following works for standard text boxes etc.
#!/usr/bin/perl
use CGI qw(:standard);
sub GetForm{
%form;
foreach my $p (param()) {
$form{$p} = param($p);
}
return %form;
}
However when faced with two form inputs with the same name it just returns the first one (ie the hidden one)
I can see that the inputs are included in the POST header as an array but I don't know how to process them.
I'm working with legacy code so I can't change the form unfortunately!
Is there a way to do this?
I have an html form which sends a hidden field and a radio button with
the same name.
This allows people to submit the form without picking from the list
(but records a zero answer).
That's an odd approach. It would be easier to leave the hidden input out and treat the absence of the data as a zero answer.
However, if you want to stick to your approach, read the documentation for the CGI module.
Specifically, the documentation for param:
When calling param() If the parameter is multivalued (e.g. from multiple selections in a scrolling list), you can ask to receive an array. Otherwise the method will return the first value.
Thus:
$form{$p} = [ param($p) ];
However, you do seem to be reinventing the wheel. There is a built-in method to get a hash of all paramaters:
$form = $CGI->new->Vars
That said, the documentation also says:
CGI.pm is no longer considered good practice for developing web applications, including quick prototyping and small web scripts. There are far better, cleaner, quicker, easier, safer, more scalable, more extensible, more modern alternatives available at this point in time. These will be documented with CGI::Alternatives.
So you should migrate away from this anyway.
Replace
$form{$p} = param($p); # Value of first field named $p
with
$form{$p} = ( multi_param($p) )[-1]; # Value of last field named $p
or
$form{$p} = ( grep length, multi_param($p) )[-1]; # Value of last field named $p
# that has a non-blank value

How can I display count of imagefield images in views?

I want to display the number of images uploaded to an imagefield, in a views field or views tpl.php. How can I do this? My imagefield is called boatimages. I tried this but it comes out as 0, not the correct number: < ? php print count($fields->field_boatimages) ?>
Ack. I do not think count() works like that.
Why not just do this using Views? Take a look at Arguments > Settings and you'll see 'display record count' which seems like all you would need for this.
My suggestion is install the devel module and use the function dpm to print the variable if you wanna know the structure (print_r() may work too). If count isn't working it's because, you are probably using it with the wrong data.
OR, you could just query the database for the field. I'm gonna provide you instructions for drupal 7 but drupal 6 should be similar.
Check the table field_data_field_boatimages. See how there's a list of your images related with a single entity_id
Then execute this query
SELECT COUNT(*) FROM `field_data_field_boatimages` WHERE entity_id = ###
Where ### is the entity_id you want to know. You can get it by looking for arg(1) if arg(0) == node in your page.
Now you just have to use php power to print thar result
$query = SELECT COUNT(*) FROM `field_data_field_boatimages` WHERE entity_id = :eid
$result = db_query($query, array(':eid', $nid))->fetchField();
echo $result;
Drupal 6 would be very similar. Just a little difference in the table names and the query syntax. For example using db_result instead of fetchField()
Anyway good luck!

How to deal with nameless forms on websites?

I would like to write a script that lets me use this website
http://proteinmodel.org/AS2TS/LGA/lga.html
(I need to use it a few hundred times, and I don't feel like doing that manually)
I have searched the internet for ways how this could be done using Perl, and I came across WWW::Mechanize, which seemed to be just what I was looking for. But now I have discovered that the form on that website which I want to use has no name - its declaration line simply reads
<FORM METHOD="POST" ACTION="./lga-form.cgi" ENCTYPE=multipart/form-data>
At first I tried simply not setting my WWW::Mechanize object's form_name property, which gave me this error message when I provided a value for the form's email address field:
Argument "my_email#address.com" isn't numeric in numeric gt (>) at /usr/share/perl5/WWW/Mechanize.pm line 1618.
I then tried setting form_name to '' and later ' ', but it was to no avail, I simply got this message:
There is no form named " " at ./automate_LGA.pl line 40
What way is there to deal with forms that have no names? It would be most helpful if someone on here could answer this question - even if the answer points away from using WWW::Mechanize, as I just want to get the job done, (more or less) no matter how.
Thanks a lot in advance!
An easy and more robust way is to use the $mech->form_with_fields() method from WWW::Mechanize to select the form you want based on the fields it contains.
Easier still, use the submit_form method with the with_fields option.
For instance, to locate a form which has fields named 'username' and 'password', complete them and submit the form, it's as easy as:
$mech->submit_form(
with_fields => { username => $username, password => $password }
);
Doing it this way has the advantage that if they shuffle their HTML around, changing the order of the forms in the HTML, or adding a new form before the one you're interested in, your code will continue to work.
I don't know about WWW::Mechanize, but its Python equivalent, mechanize, gives you an array of forms that you can iterate even if you don't know their names.
Example (taken from its homepage):
import mechanize
br = mechanize.Browser()
br.open("http://www.example.com/")
for form in br.forms():
print form
EDIT: searching in the docs of WWW::Mechanize I found the $mech->forms() method, that could be what you need. But since I don't know perl or WWW::Mechanize, I'll leave there my python answer.
Okay, I have found the answer. I can address the nameless form by its number (there's just one form on the webpage, so I guessed it would be number 1, and it worked). Here's part of my code:
my $lga = WWW::Mechanize->new();
my $address = 'my_email#address.com';
my $options = '-3 -o0 -d:4.0';
my $pdb_2 = "${pdb_id}_1 ${pdb_id}_2";
$lga->get('http://proteinmodel.org/AS2TS/LGA/lga.html');
$lga->success or die "LGA GET fail\n";
$lga->form_number(1);
$lga->field('Address', $address);
$lga->field('Options', $options);
$lga->field('PDB_2', $pdb_2);
$lga->submit();
$lga->success or die "LGA POST fail\n";