Sending special characters in HTML form - php

I have an input field (which is filled automatically) with the format name <myemail#host.com>. I gave the form enctype="application/x-www-form-urlencoded", but when I retrieve it in PHP, it shows only the name. Please help me retrieving the email too.
My HTML form:
<form action="{$path_site}{$index_file}" method="POST" enctype="application/x-www-form-urlencoded">
<table>
<tr>
<td>Your Name</td>
<td><input type="text" name="sender_name" size="37" /></td>
</tr>
<tr>
<td>To</td>
<td><input type="text" name="reciever_name" size="37" id="inputString" onkeyup="lookup(this.value)" onblur="fill()" /></td>
</tr>
</table>
</form>
And PHP code:
echo $msg_sender_name = $info[reciever_name];

Extracting the information from comments, where you say:
if the text is like "myName<myEmail#email.com>", info['reciever_name'] displays only "myName"
I would say that your problem is related to the displaying the results, and is not related to the form.
You probably display the received string as HTML, where the characters "<" and ">" are special.
Instead of
echo $info['reciever_name'];
you should use the htmlspecialchars function:
echo htmlspecialchars($info['reciever_name'], ENT_QUOTES);
This is the most common bug in PHP (and in many other languages).
You should escape all the text you are displaying, especially when it comes from untrusted sources - and every value provided by the user is untrusted.
Failing to escape the output you risk the security of your users - you may want to read about Cross-site-scripting on Wikipedia.

The following PHP code
echo $msg_sender_name = $info[reciever_name];
seems to be missing a couple of quotes. Try this instead:
echo $msg_sender_name = $info['reciever_name'];

Related

POST-ing HTMLFormElements as Array Keep DOM Order Accross Browser

I am POST-ing three HTML input elements that has the PHP Array naming convention i.e. name="name[]" (the 3 inputs have different names "A[]", "B[]" and "C[]"). The input elements are children of <td> elements of which there are anything from 7 to 1001 <td>'s, meaning for each <td> there is 3 times the input elements i.e. 21 to 3003. The layout is similar to that of a Spreadsheet e.g.
<table>
<--! ... -->
<tbody>
<tr>
<td>
<input type="text" name="A[]" placeholder="A1">
<input type="hidden" name="B[]" value="A1">
<input type="hidden" name="C[]" value="2021-10-03">
</td>
<td>
<input type="text" name="A[]" placeholder="B1">
<input type="hidden" name="B[]" value="B1">
<input type="hidden" name="C[]" value="2021-10-04">
</td>
<--! ... -->
</tr>
<--! ... -->
</tbody>
<--! ... -->
When I POST them I noticed that each input' Array keys on the server side conforms to the order the input element appears within the HTMLFormElement.
What I want to know is the order of array keys true accross browser? I could not find anything in the HTML Spec, but the PHP manual gives the following note when denoting an input name as name[] :
Specifying array keys is optional in HTML. If you do not specify the keys, the array gets filled in the order the elements appear in the form. Our first example will contain keys 0, 1, 2 and 3.
Thanks for your question, quite interesting, however I have problems to answer it specifically. That is because this depends on implementation and it can (or as we can see at least could) be different across browsers.
For the PHP part, this is encoded in PHPs source code and therefore defined, but that is only one side and my educated guess (have not looked into the sources) is that it depends on the input order.
This is how I understand it: Given the browsers build the form data set from successful controls and then encode it. For the PHP array keys (of which order you're interested in) with the HTML form (excerpt) example:
<form method="post">
...
<td>
<input type="text" name="A[]" placeholder="A1">
<input type="hidden" name="B[]" value="A1">
<input type="hidden" name="C[]" value="2021-10-03">
</td>
<td>
<input type="text" name="A[]" placeholder="B1">
<input type="hidden" name="B[]" value="B1">
<input type="hidden" name="C[]" value="2021-10-04">
</td>
...
</form>
I would assume document order of the input elements to build the form data-set from. Problem with that is - IIRC - that in HTML there is no specification of document order. Within the DOM there is but from what I know a browser must not have a DOM. It's perhaps stupid to not have a DOM browser internally (or some structure with similar semantics) but there is no requirement in the HTML specification to have one: From what I know DOM is Javascript specific and a browser must not support any client side scripting.
NOTE: The HTML living standard supports this interpretation (as of today 2021-10-03). It does not relate to the DOM in form data encoding, instead it has tree order which has similar semantics to DOM document order. And it is the tree from which the list of input elements is obtained from that is used to identify the successful controls for building and encoding the forms' data. All lists have ordered sequence (first to last, add appends), are initialized empty and are traversed from start to end. So it is that this sequence is retained including in the encoding serializers' encoding which becomes the input parsed by the PHP SAPI.
This confirms the observation that the input order is always the same. If not (the part you're curious about), you could treat it as a flaw. Your standard form input validation should handle that case thought anyway, as any form data in the request could be composed elsewhere (e.g. different form, there is no same-origin policy for form submits) and therefore needs validation.
Considering there is DOM support and also used internally when creating the forms data-set and considering that the successful inputs are processed in document order when building the data-set, the following data-set in this top-down order (one control-name/current-value pair per line) is created:
A[]: A1
B[]: A1
C[]: 2021-10-03
A[]: B1
B[]: B1
C[]: 2021-10-04
If then the result of the encoding (not further specified for the order in the HTML 4.01 specs) of this data-set. Again it would be kind of counter-intuitive to implement it different to the processing order, but if in processing order this then defines the input-order as the PHP SAPI receives this data (HTTP request body) and forms the $_POST array out of it.
What then follows is the following (at least how I explain it to myself, not verified in the sources):
The $_POST array is initialized empty.
The first control-name is A[].
PHP "realizes" the array access brackets [] and that no index or key is given within those brackets.
Therefore the array is populated similar like in PHP code: $_POST['A'][] = 'A1'; (compare: array_push()).
These steps 2. - 4. are done for each name/value pair.
Now this does not specifically answer your question. However if you're asking because you'd like to set the indexes in stone (apart from any order), it should be possible to provide those within the HTML form control-names and it perhaps is what you're looking for:
<form method="post">
...
<td>
<input type="text" name="A[0]" placeholder="A1">
<input type="hidden" name="B[0]" value="A1">
<input type="hidden" name="C[0]" value="2021-10-03">
</td>
<td>
<input type="text" name="A[1]" placeholder="B1">
<input type="hidden" name="B[1]" value="B1">
<input type="hidden" name="C[1]" value="2021-10-04">
</td>
...
</form>
Then at least on the level of accessing via $_POST the keys are defined as the control-names need to be preserved by the HTML standard. And they have the names you expect, as you can re-create the order via the numerical index.
If you're concerned about rows, all you would need to do is to transpose those "named" parts (as PHP is handling the [...] array part) to their indexes:
// required input
$input = $_POST;
// define structure of result data
$fields = ['A' => null, 'B' => null, 'C' => null];
$count = 2;
// initialize the result
$result = array_fill(0, $count, $fields);
// map $input to $result
foreach (array_keys($result) as $index) {
foreach ($fields as $name => $default) {
$result[$index][$name] = $_POST[$name][$index] ?? $result[$index][$name];
}
}
Such a part is also a good place to verify the input is complete. The resulting $result (pick the name that fits best in your case) are also better to map onto database fields (e.g. use A, B, C, ... within the form when you generate the inputs from a structure and then map them back with the same structure onto database (or your applications internal entity/property names).
This is especially the case if you realized that the order was suddenly brittle - you can make the form creation/submission/data-handling a more distinct transaction even HTTP is stateless. At least more distinct on the data level.
Which brings me to another improvement/variant when writing the HTML of the form to have the data in the processing order already within $_POST. It won't spare the needed validation steps, however this can be done within PHP:
<td>
<input type="text" name="set[0][D]" placeholder="A1">
<input type="hidden" name="set[0][E]" value="A1">
<input type="hidden" name="set[0][F]" value="2021-10-05">
</td>
<td>
<input type="text" name="set[1][D]" placeholder="B1">
<input type="hidden" name="set[1][E]" value="B1">
<input type="hidden" name="set[1][F]" value="2021-10-06">
</td>
Then $_POST['set'] already contains the form-data in an ordered array and the transposition is not necessary and to map the order, ksort may suffice already:
ksort($_POST['set']);
So this can help with the immediate processing for the form data (the numeric indexes can be left out as well if the input elements are in the correct order, no ksort() necessary then, PHP will take care of that).
It would be even possible to leave the first name out but it might not be useful because of other form fields not relating to the set:
<td>
<input type="text" name="0[G]" placeholder="A1">
<input type="hidden" name="0[H]" value="A1">
<input type="hidden" name="0[I]" value="2021-10-07">
</td>
<td>
<input type="text" name="1[G]" placeholder="B1">
<input type="hidden" name="1[H]" value="B1">
<input type="hidden" name="1[I]" value="2021-10-08">
</td>
Makes $_POST a numerically indexed (in undefined order) array of arrays.

apostrophe in PHP string

This is weird! I have a form which gets info from a DB and then fills in a form with the details. I am trying to cater for cases where a person has a name like O'Neill. At the top of the page (outside the actual form itself) is a line that echoes the user's name to the screen:
<h2>Member Details for <?php echo $thefn; ?></h2>
And this does indeed display on the page properly, i.e., Member Details for Mike O'Neill
However, in the actual form, where the code runs:
<td><?php echo "<input type='text' name='fname' value='$thefn' size='30' maxlength='30'>"; ?></td>
The name is shown with everything after the apostrophe gone! The variable is the same, so what am I doing wrong? This has got me tearing my hair out (and there's a fair amount of that!)
Let's say I put in my name as:
' /><script type="text/javascript">alert("You've just been hacked!");</script><input type="hidden" name="lol" value='hax
Now what?
htmlspecialchars($thefn)
Should help.
Use double quotes " " in your HTML like so :
echo "<input type='text' name='fname' value=\"$thefn\" size='30' maxlength='30'>";
Note that you have to escape them with \ since you already use double quotes to delimit your string (in PHP). Another solution is to use single-quotes on the PHP side (echo ' ';) and use double quotes inside the string, so that you don't need escaping.
Also note that this code is vulnerable to XSS attacks, you can use htmlspecialchars() to prevent that, here's the corrected code (both the XSS and the quotes) :
echo '<input type="text" name="fname" value="'.htmlspecialchars($thefn).'" size="30" maxlength="30">';
Ignoring the obvious security red herring here (I assume the format of your $thefn variable is correct for going between single quotes in HTML), I would be wrapping the PHP variables inside of {} brackets, like so. This has two major advantages. One - it is easier to spot replaceable parts, plus, makes it crystal clear to PHP what part is dynamic. Two - you can use fancier variables, like arrays. {$my_array['my_key']}.
<td>
<?php
echo "<input type='text' name='fname' value='{$thefn}' size='30' maxlength='30'>";
?>
</td>
See also: PHP string parsing (in the manual)

Select one of multiple elements within a cell in xPath

I am using Behat and am trying to select some form elements.
My HTML is as follows - Basically I have two required fields, one an input and one a textarea, and a checkbox.
<table class="table">
<thead>
<tr>
<th>Delete</th>
<th>Question</th>
<th>Reference</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" name="delete" /></td>
<td><textarea name="question" required="required"></textarea></td>
<td><input type="text" required="required" name="reference" /></td>
</tr>
</tbody>
</table>
My xpath selector that gets the form elements is:
//table/tbody/tr/td/input
And this works fine for inputs obviously - but when I added the textarea and tried to check it, it can't find the textarea, because duh, it's not an input.
I tried this: //table/tbody/tr/td/(input or textarea) and several variations of using "or", |, etc. I can't figure out how to specify multiple types of elements to try to match.
Thanks In Advance! :)
PHP's XPath Processor only supports XPath 1.0, which does not allow alternations in path steps. A valid XPath 2.0 expression would have been
//table/tbody/tr/td/(input, textarea)
XPath 1.0 requires you to either provide full paths like this:
//table/tbody/tr/td/input | //table/tbody/tr/td/textarea
or use a predicate with name-test while using the wildcard node test:
//table/tbody/tr/td/*[local-name() = 'input' or local-name() = 'textarea']
The latter version will be probably preferable regarding performance as the XML file will only be scanned once.
Untested in Behat/PHP, but this is how it would look if following the XPath syntax.
//table/tbody/tr/td/input | //table/tbody/tr/td/textarea

disable html tag, php, script from input field [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What are the best practices for avoiding xss attacks in a PHP site
I have a form that user can fill in their personal information. The user submits the form and A web service will process these information and store the information in mysql database.
But what if users enter html tag, php code, or javascript in the input field. I would like to prevent that. I know in javascript there's a method call escapehtml, in php it's strip_tags.
I just want to know the correct way of disabling the abilities to type html, php, script from input field. Do I use strip_tags for all input I received?If I use strip_tags, how to disable script? Or there is away to do it in mysql?
Thank you
This is the form:
<div>
<label class='info-title whitetext' for="name">Full Name: </label>
<input type="text" name="name" id="name" size='25' maxlength="100" required />
</div>
<div>
<label class='info-title whitetext' for="phone">Phone: </label>
<input type='text' pattern='\d+' name='phone' id='phone' size='25' maxlength='12' />
</div>
<div>
<label class='info-title' for="email">Email: </label>
<input type="email" name="email" id="email" size='35' maxlength="60" required />
</div>
<div>
<label class='info-title' for="address">Address: </label>
<input type="text" name="address" id="address" size='45' maxlength="50" required />
</div>
Try htmlspecialchars($string);
That will encode all the HTML tags to character codes (<div> would become <div>, which will be displayed without being parsed as html) This way, script tags cannot be created as well.
Be sure to clean the content before supplying it to a database though, for example by escaping with mysqli_escape_string() (others will probably advice you to use prepare statements).
It is most likely not best practice to put HTML character encoded strings into the database, as it simply increases the string size unnecessarily. (And it doesn't provide protection against SQL injection on its own)
Personally, I just like to do $out = str_replace("<","<",$in). It provides the least possible disruption for the user, and they are most likely to get out what they typed in.
If the user input may end up in an HTML attribute (for whatever reason), you should also replace " with ".
Never put user-supplied content into a <script> tag, and never save it to a file without first performing the replacements.
You cannot disable "the abilities to type html, php, script from input field", unless you check users' input in real time and specifically block them when you detect that a tag is entered. Yet I don't see a reason why anyone would want that, the proper way is to properly process users' input when submitted.
For html tags or php codes or things like that you can definitely use escapehtml or strip_tags, but if you are later putting the content into mysql, I have to remind you of sql injection attack.
If you are not familiar with the term, users can type in mysql queries that interfere with your sql queries. If we blindly insert user provided content into our "INSERT" statements, those statements might be altered by sql keywords in user's input.
For ways to prevent sql injection attack, you can take a look at wiki's page for a good start: http://en.wikipedia.org/wiki/SQL_injection#Mitigation

Get a string from a large html variable [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to parse and process HTML with PHP?
How would I go about getting a certain string from a webpage that has been scraped?
I am using SimpleBrowser in PHP to download a webpage into a variable.
The resultant webpage at a certain part has the following:
<tr>
<td class="label" width="350">POD Receiver Name: </td>
<td class="field" align="left">
<b>KRISTY</b>
</td>
</tr>
I want to get the value KRISTY into a variable, but not really sure how.
I have no real experience with regex so I wouldnt know where to start.
Any help appreciated!
To pull one specific part out from a known location, I'd use xpath. Try a tutorial such as http://ditio.net/2008/12/01/php-xpath-tutorial-advanced-xml-part-1/
I am not sure why you are storing a page in a variable. But if you have a page stored as a string in a variable you can use Regular expression to extract string out of it. For this particular example you can use something like this.
$v = '<tr>
<td class="label" width="350">POD Receiver Name: </td>
<td class="field" align="left">
<b>KRISTY</b>
</td>
</tr>';
preg_match('/\<b\>(.*?)\<\/b\>/', $v, $matches);
$result = $matches[1];
This particular regular expression gets everything between the bold tags.
If the structure can be depended on, give SimpleXML a shot:
$xml = simplexml_load_string(html_entity_decode($v));
$name = strval($xml->td[1]->b);//KRISTY
http://php.net/manual/en/function.simplexml-load-string.php
http://www.php.net/manual/en/class.simplexmlelement.php

Categories