Jump to content

xss protection?


Go to solution Solved by Jacques1,

Recommended Posts

I did a xss test and it gets gives me error which is

 

<h5>Check In</h5> <div class="date_img"> <input class="date" id="from" name="from" type="text" value=""><br /> </div> <h5>Check Out</h5> <div class="date_img"> <input class="date" id="to" name="to" type="text" value="`\'\"><b><script>alert(document.cookie)</script></b>"><br /> </div> <h5>Room</h5> <select id="room_type" name="room_type"> <option valur="" >Super Club </option> <option valur="" >Club Room </option> <option valur="" >Mini Suite </option>

There is a JavaScript alert the checker put here, how do i make it secure someone can tell me?

 

Thanks

Link to post
Share on other sites
  • Solution

Using htmlspecialchars() directly is difficult and often leaves your application open to more subtle attacks. Use a proper wrapper:

/**
 * HTML-escapes a string so that it can safely be included in an HTML document
 *
 * @param string $unsafe_input the string which should be escaped
 * @param string $encoding     the character encoding of the input string
 *
 * @return string the escaped string
 */
function html_escape($unsafe_input, $encoding)
{
    return htmlspecialchars($unsafe_input, ENT_QUOTES | ENT_SUBSTITUTE, $encoding);
}

Note that escaping is dependend on the character encoding, so you should have a constant or configuration value for the encoding of your HTML documents:

<?php

// UTF-8 is recommended for modern applications
const APP_HTML_ENCODING = 'UTF-8';
<?php

// require_once the functions and constants here



// unless your webserver already sets the encoding attribute in the Content-Type header, do it here
header('Content-Type: text/html;charset=utf-8');

$test_input = '"></div><script>alert("XSS")</script><div data-dummy="';

?>
<!DOCTYPE HTML>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Page title</title>
    </head>
    <body>
        <!-- testing the escape function -->
        <div data-test="<?= html_escape($test_input, APP_HTML_ENCODING) ?>"></div>
    </body>
</html>
Link to post
Share on other sites
  • 1 month later...

@Jacques1,

What do you say about htmlspecialchars VS htmlentities? What is the deciding factors of using vs not using the  ENT_COMPAT instead of ENT_QUOTES?

 

Since >=5.4 defaults to UTF-8 isn't it redundant to set the char encoding?
(Assumes you are on >=5.4. Since you used ENT_SUBSTITUTE which is only available as of 5.4 that implies you would be on >=5.4.)

Edited by benanamen
Link to post
Share on other sites

htmlentities() escapes all characters for which there's a named entity, including characters that don't have any special meaning (like umlauts). I've never needed this and cannot think of any scenario where it might be useful. If you want to prevent attacks and accidental syntax clashes, use htmlspecialchars(). If you want to use HTML entities for other reasons (e. g. to support ASCII-only legacy applications), use mb_encode_numericentity().

 

ENT_QUOTES is critical for security, because ENT_COMPAT leaves single quotes unescaped and doesn't work for single-quoted HTML attributes. I have no idea why ENT_COMPAT is the default.

 

Since the character encoding is essential for escaping, I'd always set it explicitly and never rely on any defaults (particularly because those defaults have changed). I also use the encoding parameter as a placeholder so that people can insert their actual encoding. Not everybody uses UTF-8.

  • Like 2
Link to post
Share on other sites

Glad to see you made it back to the forum!

 

I have no idea why ENT_COMPAT is the default.

 

Funny you mentioned that. As I was reading the docs, that stood out to me as an odd choice for the default. 

Edited by benanamen
Link to post
Share on other sites
  • 2 months later...

@jaques1, just how many times and places do you actually need to set the character encoding?

 

So you have

header('Content-Type: text/html;charset=utf-8');

<meta charset="utf-8"

html_escape($test_input, APP_HTML_ENCODING)

$dsn = "mysql:host=$dbhost;dbname=$dbname;charset=$charset";  

 

And also have mentioned the server can set the character encoding. Seems redundant to have to explicitly set it in so many places. Not to mention Mysql as well, but I assume that is different.

Link to post
Share on other sites

If you use low-level PHP, you have to set the character encoding in every component that involves text. From PHP 5.6 on, a few cases can be covered with the default_charset directive, but this is still far from a universal setting and requires tight control over the environment.

 

Tedious tasks like this are the reason why frameworks exist. For example, a template engine with auto-escaping eliminates all htmlspecialchars() calls and allows you to put boilerplate markup like the meta element into a base template.

Link to post
Share on other sites

Per the manual: In PHP 5.6 onwards, "UTF-8" is the default value and its value is used as the default character encoding for htmlentities(), html_entity_decode() and htmlspecialchars() 

 

So isn't this unnecessary for output in >=5.6?

 

htmlspecialchars($some_var, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8')

Edited by benanamen
Link to post
Share on other sites

Technicall yes, but in practice I wouldn't recommend it.

 

I think it's perfectly fine to omit the charset parameter if you explicitly define the default_charset instead. This is unambiguous (always assuming PHP >= 5.6). But when you rely entirely on defaults with no explicit settings anywhere, this is confusing and risky. There's always a chance that the defaults have been overriden somewhere else, be it by the package maintainers or a confused coworker/customer. An explicit setting makes sure you get what you expect.

 

Besides that, I would always define a wrapper function for HTML-escaping and not call htmlspecialchars() directly. So the number of parameters isn't really an issue, anyway. If you have a configuration file, you could simply define your own default character set and use it in the wrapper:

function html_escape($raw_value)
{
    return htmlspecialchars($raw_value, ENT_QUOTES | ENT_SUBSTITUTE, get_config('my_default_charset'));
}

Personally, I'd go with that, simply because I want my application to be “self-contained” and not depend on specific ini settings.

Link to post
Share on other sites
This thread is more than a year old.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.