Search code examples
javascripthtmlencodingowaspesapi

I am using the OWASP ESAPI encodeForHTMLAttribute however symbols are displaying as their html entity number instead of symbol


I am just learning about the OWASP ESAPI for XSS prevention and I am using the Javascipt version within my app

According to Rule #2 in the XSS prevention cheat sheet you should "Attribute Escape" before inserting untrusted data into attribute values like "width, name or value" and I am working on this at the moment.

However when using encodeForHTMLAttribute() before inserting an email address as a value of an input field in a contact form, the @ symbol is displaying as it's corresponding html entity #&x40; as you can see in this screenshot image:

screenshot image

Am I missing something?

I have made sure the charset of the document is set to utf-8 as follows:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

I have also added in the accept-charset="UTF-8" Attribute to the form in question.

HTML form:

<form id="contact_form" name="contact_form" method="post" action="" accept-charset="UTF-8">
    <div class="form_divider">  
        <label for="contact_form_email"><span class="asterisk">*</span>E-mail</label>       
        <input id="contact_form_email" tabindex="1" name="contact_form_email" type="email" data-role="none" maxlength="254" placeholder="E-mail" required/>
    </div><!--/form_divider-->  

</form>

Data flow of my app:

Within my app, an ajax request is performed to submit the login details and after successful authentication, I retrieve their details from the database and send back to the client side in json format. I then insert these details to the html where applicable

Javascript:

     $.ajax({
            url: app_root_url + 'login_registration/user_processing.php',
            data: JSON.stringify(params), 
            type: "POST",
            dataType: "json",
            contentType: "application/json;charset=utf-8",
            success: function(data){
            //data will be the user details such as userID, display name, email
            var result = data;
            prepareAppAfterLogin(result);

            }           

    });//end ajax


function prepareAppAfterLogin(result){
    var userDetails = result.userDetails;
    generateUserProfilePage(userDetails);

}

function generateUserProfilePage(userDetails){
    var userID = userDetails.userID;
    var display_name = userDetails.display_name;
    var email_address = userDetails.email_address;

    var profile_image = userDetails.profile_image;
    $("#profile_pic").attr('src', profile_image);

    var safe_email_address_for_html = $ESAPI.encoder().encodeForHTML(email_address);
    $("#profile_email_address").html(safe_email_address_for_html);

    var safe_email_for_attribute = $ESAPI.encoder().encodeForHTMLAttribute(email_address);
    $("#hidden_input_for_email").val(safe_email_for_attribute);
    $("#contact_form_email").val(safe_email_for_attribute);

}

Edit: I have just found documentation that supports what @Cheran Shunmugavel said in his comment below: Rule #2 here: https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet "It is important to note that when setting an HTML attribute which does not execute code, the value is set directly within the object attribute of the HTML element so there is no concerns with injecting up."... "The appropriate encoding to use would be only JavaScript encoding to disallow an attacker from closing out the single quotes and in-lining code, or escaping to HTML and opening a new script tag."

following this rule I have just tried to encode the email address for Javascript instead of encoding for html attribute as follows:

function generateUserProfilePage(userDetails){
      var safe_email_address = $ESAPI.encoder().encodeForJavaScript(userDetails.email_address);
      $("#contact_form_email").val(safe_email_address);

}

However it seems doing this also creates display problems: JS encode display problems

Can you confirm do I need to javascript encode here? thanks


Solution

  • The encodeForHTML and encodeForHTMLAttribute functions are not necessary if you are using the jQuery val method to insert the data in the document. I can't find anything in the official documentation, but there is a good explanation on this StackOverflow question: Do jQuery's val() and prop() methods html-escape values?. The important takeaway is that val sets the DOM value property internally, and that property will never attempt to interpret text as HTML markup, so escaping is not necessary.