What I have been working on is a text input that narrows down <option> in a <select> as the user types. It is working, but my concern now is security, what a user passes into the input, and potential malicious entries.

I figured I could do something like <input placeholder='[a-zA-Z]' /> but it is still allowing other characters to be entered into the text box.

What am I doing wrong here, and what would be an alternative that would permit only alphanumeric being entered?

onInputChange(term) {
    this.setState({ term });

renderOptionsSelect(term) {
    return _.map(this.props.pos_list, p => {
        var searchTerm = this.state.term.toLowerCase();
        if (p.pos_code.toLowerCase().match(searchTerm)) {
            return (
                <option key={p.pos_code} value={p.pos_code}>{p.pos_code}</option>

// render the main element of the container
render() {
    return (
        <div className='panel panel-default'>
            <div className='panel-heading'>
                <h4><strong>Basic Query</strong></h4>

            <div className='panel-body'>
                    placeholder='Enter Keyword or Position Code' 
                    onChange={event => this.onInputChange(event.target.value)}

                <hr />
                <select className='form-control'>
                <br />
                <h4>Data Cut:</h4>
                <select className='form-control' disabled={true} />

  • 3
    The pattern attribute is only enforced when a form is submitted. It's not very easy to restrict the characters allowed in an input like this, it's much easier to validate the input upon submission. – Sidney Jan 12 '18 at 20:05
  • Hmmm... sounds like if I want the validation to happen instantaneously, I need to do JS validation probably in the onInputChange(term). – sockpuppet Jan 12 '18 at 20:15
  • What kind of malicious input are you worried about? The search looks like it's happening locally so you can just validate before you submit whatever this form is part of. You could validate on changes, but it will slow down your search even further and seems unnecessary. – Adrian Smith Jan 12 '18 at 20:17
  • Also, I don't know whether you are interested or don't want the dependency, but check this out: material-ui.com/#/components/auto-complete . It seems like what you want. – Adrian Smith Jan 12 '18 at 20:19
  • Malicious input, and also currently if someone enters any `()` it generates a RegEx error in the console which just looks unprofessional. Figure I can prevent that even if someone accidentally types one of those characters. (Yeah, most users aren't looking at the console). – sockpuppet Jan 12 '18 at 20:24

That's easy. You:

  1. Remove the pattern attribute.
  2. Register your onInputChange method for input events instead of change events (onInput={event => this.onInputChange(event.target.value)}).
  3. Clean up the received value in the onInputChange before changing the state.
  • 1
    But seriously, client side JS and security checks? :(. You should reconsider whether you need that in the first place. – Luka Žitnik Jan 14 '18 at 16:49
  • 1
    It's not about security - it's about UX. Would you rather wait for the server to validate your input when you could have it validated at an instant? – Hampus Ahlgren Apr 2 at 11:50
  • When you remove the onChange handler and use onInput instead, React will throw a console error complaining that onChange is missing. To suppress this, you can create an onChange handler that does nothing, like this: onChange={() => {}} – Derrick Miller Jun 6 at 18:33

So you currently have the functionality of narrowing down the options of the <select> as the user types, and now your concern is increasing security by limiting what the user is able to submit as input.

The answer to this concern is that it is not possible to secure input with client-side validation; it must be done with server-side validation.

Client-side security checks can easily be bypassed. The input must be checked when it is received by the server in order to make sure that it is not malicious.

Your Answer

