1

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.

Jarad
  • 17,409
  • 19
  • 95
  • 154
  • Did you check [this](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) ? – Swati Feb 19 '21 at 04:45
  • @Swati I came across this about [MutationObserver](https://stackoverflow.com/questions/32383349/detect-value-change-in-input-tag-with-vanilla-javascript-and-mutationobserver) cannot observe changes to the value property (if I'm saying that right). – Jarad Feb 19 '21 at 05:45

3 Answers3

1

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('test@test.com').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">
joshmoto
  • 4,472
  • 1
  • 26
  • 45
  • You need to trigger event manually. It should detect automatically. – anand shukla Feb 19 '21 at 04:37
  • @anandshukla but the jquery value change doesn't fire the input event. You need to trigger the event to capture the value. – joshmoto Feb 19 '21 at 04:39
  • Yes, but question is asked like that only. It should detect automatically. We don't know how it changed, it should detect automatically. – anand shukla Feb 19 '21 at 04:41
  • @anandshukla i see what you mean, I've elaborated my answer. – joshmoto Feb 19 '21 at 04:45
  • Thanks for your answer. I edited my question with my use-case. When I do `$('#id_email').val('" onMouseOver="alert(1);')` in my question, I'm simulating what a malicious user might do to test known vulnerabilities and submit the form. A malicious actor wouldn't try to trigger the input event since they want to avoid being detected. – Jarad Feb 19 '21 at 05:27
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.

  • I updated my question with my use-case. Thanks for your ideas. My use-case is to detect bots or even real users that use Javascript / jQuery and either manually or automatically enter data into forms and submit them looking for vulnerabilities. In both cases, the attacker wouldn't manually trigger an event, since they want to be undetected. I was wondering how to detect this regardless. – Jarad Feb 19 '21 at 05:24
0

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?.

Jarad
  • 17,409
  • 19
  • 95
  • 154