Hello folks,


In short, this code is vulnerable:

<div class="search">
        <form action="/search" method="get" name="header_search">
            <label>{l t='Search Business'} <input name="searchtext" type="text" id="searchtext" placeholder="{l t='e.g.Marriott'}" /></label>
            <label>{l t='City'} <input name="cityname" type="text" id="Hsearchcity" autocomplete="off" placeholder="{l t='All Cities'}" class="commentColor cityname"/>
            </label>
             
            <a onclick="header_search.submit()" href="javascript:void(0)">{l t='Search'}</a>
        </form>
    </div>

I have been trying to implement unhtmlentities(), or htmlspecialchars() functions with no success, how can it be done please ??

Dani AI

Generated

Quick diagnosis and the root cause (short): the XSS is happening when server-side values are written straight into the page and into an inline JavaScript context (your suggestion list / onClick parameters). Escaping at the wrong time or using only generic sanitizers (filtering on input) often fails because different output contexts need different escaping rules. See the OWASP XSS rules about context-aware output encoding. (cheatsheetseries.owasp.org)

Concrete fixes to apply (minimal, safe changes)

  • Validate the input shape (only allow letters/numbers where appropriate) but do not rely on that alone. filter_var is useful for validation, not a single XSS cure. (php.net)

  • Stop emitting unescaped values into inline JavaScript attributes. Instead put data into safe HTML attributes (HTML-escape them) and attach events from JavaScript. Example safe rendering:

    <li data-id="<?php echo (int)$row['business_id']; ?>"
        data-name="<?php echo htmlspecialchars($row['business_name'], ENT_QUOTES, 'UTF-8'); ?>">
      <?php echo htmlspecialchars($row['business_name'], ENT_QUOTES, 'UTF-8'); ?>
    </li>
    <script>
    document.addEventListener('click', function(e){
      var li = e.target.closest('li[data-id]');
      if(!li) return;
      fillBiz(li.dataset.id, li.dataset.name);
    });
    </script>

    Use htmlspecialchars with ENT_QUOTES and the correct charset when putting values into HTML. (php.net)

If the UI uses AJAX, return JSON (not raw HTML) and use json_encode with the JSONHEX* flags (and proper Content-Type) so strings cannot close a script block. Example: set header and echo json_encode($rows, JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT). Also avoid innerHTML/text insertion of untrusted HTML; prefer textContent or DOM methods. (php.net)

Other practical points: use prepared statements (PDO or MySQLi) not addslashes/mysql_* to avoid SQL issues; the old mysql extension is deprecated. Audit the DB for already-stored payloads (do not double-decode existing entities). For a full checklist and rules, read the OWASP XSS Prevention and DOM XSS cheat sheets. (php.net)

Notes on the thread: was right to suggest validating input; was right that HTML-encoding helps — the actionable rule is: validate input, use parameterized queries, then perform context-aware escaping at output.

Recommended Answers

All 21 Replies

I have been trying to implement unhtmlentities(), or htmlspecialchars() functions with no success, how can it be done please ??

What is the definition of with no success? You need to be explicit here!

It is either I Implemented it in the wrong way, OR, it gave no results.

My implementation was lacking the variable that takes the searchtext, or is it the $searchtext itself ??

Or to be precise, how to implement the mentioned functions in my code ?

what are you trying to do?

Prevent XSS, in other words, Sanitize Tags ( <, >, ", etc...)

I read that before, but how to use it in the context of my code ? what's the variable that will be sanitized ?

Member Avatar for Member #120589

You don't show your data handling code, only the input form. The sanitizing occurs with the validating of the $_GET vars.

Thanks ardav, things have become easier now, yet, here is my code:

if($_POST['type']=='biz')
{
					
	$keyword = $_POST['biz'];
	//NEWLY ADDED
	$keyword= filter_var($keyword, FILTER_SANITIZE_URL, FILTER_FLAG_STRIP_LOW);
	$keyword= filter_var($keyword, FILTER_SANITIZE_URL, FILTER_FLAG_STRIP_HIGH);
	$keyword= filter_var($keyword, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_HIGH);
	$keyword= filter_var($keyword, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_LOW);
	//ADD END
	$keyword = addslashes(str_replace("||sp_rp_and||", "&", $keyword));
	if($keyword=="")
	$query="select * from `business` order by business_id DESC LIMIT 0,20";
	else
	$query="select * from `business` where business_name like '%".$keyword."%' ORDER BY business_name asc limit 0,20";
	
	$rc=mysql_query($query);
	$i=0;
	while($row = mysql_fetch_array($rc))
	{
		$array[$row['business_id']]=$row;
	}
	if(!$array) exit;
	
	
		$str="<ul>";
		foreach($array as $business_id => $row)
		{
			$showName=preg_replace("/(".$keyword.")/i","<abbr>$1</abbr>",$row['business_name']);
			
			$str.="<li onClick=\"fillBiz('".$business_id."','".addslashes($row['business_name'])."','".addslashes($row['permalink'])."')\">".$showName."</li>";
		}
		$str.= "</ul>";
		
	echo $str;
}

Am I close ?

Don't sanitize verything. If the field is EMAIL sanitize it as EMAIL filter.
You have to know the type expected!
For your case $keyword= filter_var($keyword, FILTER_SANITIZE_SPECIAL_CHARS, FILTER_FLAG_STRIP_LOW); seems to be the right. If you put into my sql don't forget to escape it using mysql_real_escape_string()

Thanks,
I don't expect the user to enter anything but names and numbers, so I guess no harm with filtering.

But that doesn't seem to work anyway, I still get XSS upon entering a script in the keyword field, tried str_replace() as well, and it doesn't work, this is confusing!

ok, try reading

Thanks,
I don't expect the user to enter anything but names and numbers, so I guess no harm with filtering.

But that doesn't seem to work anyway, I still get XSS upon entering a script in the keyword field, tried str_replace() as well, and it doesn't work, this is confusing!

What is your current code and how do you test it?

I test it by inserting the following in the search field / or url:

"><script>alert(document.cookie);</script>"

and I receive the pop-up showing the cookie info.


I tried working on mod_security level but didn't work as well ( didn't validate the input)

Member Avatar for Member #120589

OK I see, it's what the DB is spitting out that's causing the problem. Why not use htmlentities() on input? This should only kill off html (script) - should be none of that in your input fields right?

You don't need to html_decode_entity() to output as no html should be included.


I use mysql_real_escape_string() to stop SQL injection and htmlentities to avoid xss.

OK I see, it's what the DB is spitting out that's causing the problem. Why not use htmlentities() on input? This should only kill off html (script) - should be none of that in your input fields right?

You don't need to html_decode_entity() to output as no html should be included.


I use mysql_real_escape_string() to stop SQL injection and htmlentities to avoid xss.

Tried htmlentities() on every possible input, nothing but the bloody pop-up after testing.

Nothing is working, this is frustrating !!

Member Avatar for Member #120589
$input = mysql_real_escape_string(htmlentities($var));

Doesn't work?

Here is the combination:

$keyword = $_POST['biz'];
	$keyword = mysql_real_escape_string(htmlentities($keyword)); //this

or

$keyword = $_POST['biz'];
	$keyword = htmlentities($keyword, ENT_QUOTES); //this

Doesn't do anything.

put your full code!

Member Avatar for Member #120589

htmlentities() works for me.

htmlentities() works for me.

may be his tests are flawed

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.