1
\$\begingroup\$

I tried to prevent XSS attacks by adding

// prevent XSS
$_GET   = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
$_POST  = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);

to the top of the .PHP File. It works, but I don't think that this is the best practice.

What I need to do is improve the way this code handles the data:

    if (empty($_POST['telefonnummer']) || !isset($_POST['telefonnummer'])) {
        $this->setStatusMessage($translator->translate('Bitte geben Sie Ihre Telefonnummer ein.'));
        $this->setStatus(KDatabase::STATUS_FAILED);

        return false;
    }else{
      $this->telefonnummer = $_POST['telefonnummer'];
    }
\$\endgroup\$
1
\$\begingroup\$

Find purpose-built libraries which are actively maintained. For example, anti-xss:

$harm_string = "Hello, i try to <script>alert('Hack');</script> your site";
$harmless_string = $antiXss->xss_clean($harm_string);

$harm_string = "<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>";
$harmless_string = $antiXss->xss_clean($harm_string);

$harm_string = "<a href='&#x2000;javascript:alert(1)'>CLICK</a>";
$harmless_string = $antiXss->xss_clean($harm_string);

$harm_string = "<a href=\"\u0001java\u0003script:alert(1)\">CLICK<a>";
$harmless_string = $antiXss->xss_clean($harm_string);

$harm_string = '<li style="list-style-image: url(javascript:alert(0))">';
$harmless_string = $antiXss->xss_clean($harm_string);

$harm_string = '<li style="list-style-image: url(javascript:alert(0))">';
$antiXss->removeEvilAttributes(array('style')); // allow style-attributes
$harmless_string = $antiXss->xss_clean($harm_string);

$harm_string = "\x3cscript src=http://www.example.com/malicious-code.js\x3e\x3c/script\x3e";
$harmless_string = $antiXss->xss_clean($harm_string);

$harm_string = "<iframe width="560" onclick="alert('xss')" height="315" src="https://www.youtube.com/embed/foobar?rel=0&controls=0&showinfo=0" frameborder="0" allowfullscreen></iframe>";

$antiXss->removeEvilHtmlTags(array('iframe'));

And a UTF8 library for data you are sending:

UTF8::json_enocde(array(1, '¥', 'ä')); // '[1,"\u00a5","\u00e4"]'

UTF8::html_encode('中文空白'); // '&#20013;&#25991;&#31354;&#30333;'

UTF8::utf8_decode(UTF8::utf8_encode('-ABC-中文空白-')); // '-ABC-中文空白-'

Implement Content Security Policy(CSP) on the web server as well. For example:

default-src 'self' https:; connect-src 'self' https: http:; font-src 'self' https:; frame-src *; img-src
 'self' https: http: data:; media-src 'self' https:; object-src 'self' https:; script-src 'sha256-q590j1fW
+aERb666H10h55ePy0sxRjUYCiOmJPftXDs=' 'self' https: 'unsafe-eval' 'unsafe-inline' http:; style-src 'self'
 https: 'unsafe-inline' http:; report-uri /tracking/csp?action=listing_frame&controller=embed&req_uuid
=cff37d5d-4c12-4c8b-b288-1ce0d103a25c&version=c7fc601874a5350c79eceb33ba6d4c09a433035f;

default-src is set to 'self' which means it's setting all CSP rules to only allow src attribute from a same-origin. In short, you should only be able to load src from a relative endpoint. frame-src is set to wildcard (*) so we can load external src links in frames (iframe, frame, frameset). Because we're injecting HTML past the body element, we cannot use frame or frameset. The WAF has made it next to impossible to use iframe. script-src has 'self' supplied after the sha256 hashed script for unsafe-inline and unsafe-eval, but https does not have 'self' supplied meaning we can load external scripts for execution.

References

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

It is not your input which is prone to XSS but only output.

So you should leave input alone and sanitize the output. For the purpose I would recommend a template engine with auto-escaping feature, for example Twig.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.