Jarad
Jarad

Reputation: 18893

What Javascript / jQuery Event Should I Look For To Detect Form Field Filled Programmatically by Javascript / jQuery?

If this is an email input field on my form:

<input autofocus="" class="emailinput form-control" id="id_email"
       maxlength="254" name="email" required="" type="email">

I am trying to detect if the value changes AT ALL - particularly if the user used Javascript / jQuery / whatever to change it.

I watch for these events:

$("#id_email").on('input blur change paste keyup keydown keypress DOMAttrModified propertychange', function(e) {
    console.log('Email field value changed!');
})

Then do this...

$('#id_email').val('" onMouseOver="alert(1);')

and sure enough, the text " onMouseOver="alert(1); gets inserted without being detected.

What event should I be looking for to detect if a form field changes as the result of programmatically being inserted (by Javascript / jQuery for example)?

Edit

What is my use-case?

I am trying to provide a stupid-simple first line of defense against Cross-site Scripting (Reflected) attacks that prevent bots / tools from programmatically submitting known vulnerabilities into forms.

A bot / tool is going to try to do this undetected. That's why I was wondering if there's a way to detect if a field changes as a result of javascript.

Upvotes: 1

Views: 209

Answers (3)

Jarad
Jarad

Reputation: 18893

I think I might have found a solution parsed from this answer. It seems to prevent me from fill the form fields with Javascript / jQuery ($('#id_email').val('" onMouseOver="alert(1);')).

No idea about the implications though.

Object.defineProperty(document.querySelector("#id_email"), "value", {
    set: function (text) {
        return this.defaultValue = "";
    }
});

or just remove the return completely?.

Upvotes: 0

As far as I know, there's no native way to detect programatic changes on inputs, the events have to be emitted manually from the code that modifies the input's value.

To force the event emission programmatically use jQuery's trigger function as in:

$('#id_email').val('" onMouseOver="alert(1);');
$('#id_email').trigger('input');

You can trigger any event and the attached handlers would execute.

For detecting programatic changes you can see this answer: https://stackoverflow.com/a/16013352/1714951, although it has side effects of disrupting the interaction on the input and I'd recommend against it because it modifies the DOM element.

Another approach you could take is to "poll" for the value of the input with an interval to detect changes, but that adds too much load to my liking in terms of performance.

I'm not sure what your usecase is though.

Upvotes: 0

joshmoto
joshmoto

Reputation: 5088

input event should work every direct input change, but running jquery .val changes will not fire the input change event.

You can manually trigger the value change event on input using .trigger('input').

$("#id_email").on('input', function(e) {
    console.clear();
    console.log('Email field value changed! - ' + e.target.value);
})

$("#id_email").val('[email protected]').trigger('input');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input autofocus="" class="emailinput form-control" id="id_email" maxlength="254" name="email" required="" type="email">

Upvotes: 1

Related Questions