I'm building a simple HTML page, and I have an input field followed by a search button; this is the code:
<input type="text" id="sfield" placeholder="Write something">
<button id="search">Search!</button>
I'm currently writing the javascript to assign some actions to the button and to the input field, when I thought that it would be a good idea to add a feature that needs the cursor to be on the field for the search to start. I'll explain it better: if someone wants to search something, it will appear just like a normal input field and work like that. However, if someone tries to launch a script for auto-submitting the form, it'll act like no input was inserted.
For example, if someone tries to inject this script:
document.getElementById('sfield').value="Some stuff";
document.getElementById('search').click();
the search would start but the "Some stuff" string wouldn't be saved, as if the user clicked the search button without writing in the search field. Furthermore, adding the line
document.getElementById('sfield').focus();
should also do nothing, so that the only way to put the cursor in the field would be a manual action by the user.
I'm wondering if it's possible to make such thing; I already managed to get the search field blank with EventListener, but I don't have a clue about making the script discern whether the user put the cursor on the field or not.
I'd prefer not using JQuery but it's ok also with it. Any idea would be greatly accepted. Thanks.
In that case, the program needs to retain state. I'd do it like this...
http://jsbin.com/hopicucuyi/edit?js,console,output
<input type="text" id="sfield" placeholder="Write something" data-validated = "false">
<button id="search">Search!</button>
<script>
const inputField = document.getElementById('sfield');
const searchButton = document.getElementById('search');
inputField.onfocus = () => {
inputField.setAttribute("data-validated", "true")
}
searchButton.onclick = () => {
const isValidated = inputField.getAttribute("data-validated");
console.log('Is Validated: ' + isValidated);
}
</script>
Generally neither of these solutions will stop a bot that uses a browser (which is a bot that runs javascript). There is no 100% solution, but there are stronger solutions than checking if something has focus or not. Remember the javascript environment is completely controllable from the browser side of things. For instance, all I would have to do to get past your security is change the state of the input in question to data-validated="true" and your security falls apart.
However, the browser vendors have taken this possibility into account and provide you with a little-known solution. Look at the event data coming from a mouse click or a keystroke. This event data can be generated. It used to be easier in the older browsers to spoof an event just by using new Event(), but now modern browsers use specific events for keyboard and mouse. The part that makes spoofing these very hard is that in the event there are properties that are read-only. More specifically there is an event property called "trusted" that cannot be set by javascript. If you spoof a MouseEvent or KeyboardEvent, the "trusted" property is set to false, but if you use the actual mouse or keyboard "trusted" is set to true.
Info on the isTrusted property here: https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted
Note: this is also not 100% as the bot can run a keyboard/mouse macro that creates genuine "trusted" events. However, it does make the system much harder to crack as many people dont know about this security trick, and most bots will not have mouse/keyboard control built in. If you encounter a bot that uses mouse/keyboard, you've reduced the security playing-field and further analysis of the events and interface usage can take place.
If you combine this method with other methods like browser fingerprinting etc. it makes your overall anti-bot security that much stronger and discourages many more possible bots.
Edit: Don't just use this method and others, obfuscate your code so that any attacker will have to take the time to deobfuscate and wade through a bunch of poorly labeled functions and encrypted strings if they want to see how your security works.
Related
I have html input[type=text] element.
I want user NOT TO use voice input / voice typing (actually I need to prevent voice input provided by Android/iOS on-screen keyboard) on my input element or entire document at all.
// Tryed hard to find any answers, but it looks like no one else got the problem.
// I've already put other preventive attribs on the input so it looks exactly:
<input type="text" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false">
And yes, I understand this feature is up to mobile's keyboard, not browser.
Anyway, please suggest any workarounds.
Update: The interface exactly needs user to type words with their hands. There are no accessibility issues due to interface's purpose.
This is simply not possible because of sandboxing. It's also an awful idea because it ruins accessibility.
You could try using Javascript to only listen to keydown events, but this depends on the voice-to-text program not emulating key presses, and also removes the ability to copy-and-paste.
You could have an on-screen keyboard which requires users to click the buttons instead of using their own keyboard, But you won't be able to override the native keyboard without accessing the phone's API, which is usually only exposed to native apps.
You're really playing with fire in terms of UX with either of those solutions, though. Is there any reason you can't allow voice-to-text, or are you trying to reduce errors?
This is a fairly straight forwards question, but I cannot find the answer in the documentation.
I know it is possible to detect clicks, but is it possible to detect a key press using an InDesign script?
For example, if the user creates a text box, and types 'a' into it, I would like to capture that and do something with it.
Perhaps this can be done using hotkeys, where for example one script on startup adds a hotkey for each keyboard button, each hot key fires a script for handling it. This seems a bit of a hack (if it would even work). Is there not a on key press listener I can add?
Any help is much appreciated.
I have found this so far in the documentation:
Most of the things scripting cannot do—like setting up a workspace or
defining a set of keyboard shortcuts—are things that have to do with
the user interface.
For the specific example you give (typing something into a text frame), you can use the afterSelectionChanged event listener (whose parent can be the application, or a layout window, amongst others).
How I can know if a click event was generated by the user? (They used the mouse).
The opposite would be a click event triggered by a piece of JavaScript.
Think in a JavaScript library that displays advertisements. You wont want that anyone who uses the library fool you.
You need to make sure that the event is not forged.
Client code can never be trusted by the server. Anyone can open up their browser console and totally change the code.
You might be able to do different things to confuse robots or automated scripts, but you're helpless if you are trying to prevent a forgery that targets your site specifically.
To be honest, ANY attempt to making this tamper-proof will fail unless you follow these pretty simple advises:
don't do anything client-side, this problem family is a cognate of security, so you want to do everything server-side without relying on anything on the client;
don't trust the input you receive, doubt about its origin (e.g. user-agent, cookies, HTTP request, ecc. may all be forged into a key that perfectly fits your keyhole);
you do not really want to detect a mouse click, what you want is discriminate between human and machine, so use common techniques for that problem;
a CAPTCHA or other task that is currently next-to-impossible to solve for machines allows you to distinguish a real human from a machine.
That said, the easiest for your use case (advertisement) is a floating button embedded in an image that randomly changes position. On click you send the coordinates and a code that you use server-side to reconstruct the position of the button and thus if the coordinates are inside the buttons boundaries.
A machine will send wrong (random) coordinates with the code and server-side you will discriminate it because the click was not inside the boundaries.
This solution obviously can be enhanced:
smaller button on larger image (lower probability to have a lucky "false positive");
move the button over time (this requires an SWF plugin or HTML5 canvas);
avoid contrast that may be exploited to find the button in the image (e.g. a red button over a blue sky).
All you have to do is go to any website that has advertisements and look what they do: SWF plugins with micro-games that entice you to click it.
BTW: I don't like advertisements on web pages so maybe it's better you don't even implement that stuff...
You can check if the string 'Mouse' is found within the string representation of e.toString():
document.addEventListener('click', function(e){
console.log(e.toString().indexOf('Mouse') !== -1)
});
If the event was generated by code then e.toString() returns [object Event], but if it was a real mouse event it would return [object MouseEvent]. All I am doing is checking whether 'Mouse' is in that string to determine if it was indeed a real mouse click.
You might want to try like this:
document.addEventListener('click', function(e){
var w=[]["filter"]["constructor"]("return this")();//returns window, thanks to JSFuck
console.log(e instanceOf MouseEvent && e.view==w && e.srcElement && e.srcElement.ownerDocument.parentWindow==w && e.target && e.target.ownerDocument.parentWindow==w);
});
It checks if it is an instance of the MouseEvent object, then checks if the window is the same, the e.srcElement exists and if it is in the same window and if e.target exists and is in the same window.
So I have looked through most of the facebook questions here and it has absolutely confirmed my thoughts. Facebook development may be among some of the worst I've ever used. I'll avoid my rant for now, but as a note to where I'm coming from: tried php sdk, worked decently out of the box, found out I need to put the functionality on a pages tab, can't iframe on pages tab, have to use FBML (which they are retiring in two months, yet I can't start testing the iframe approach yet)
Anyway, I run into FBJS at this point. It works "good enough" for most things, but for some reason I can't get an event registered to an object (a select box in particular interest) by adding a listener (as per FBJS documentation). I am able to add it directly to the html object and have it work, but this is not desirable and I would really like to know what I consider the proper way to do it, which involves seperation of logic and display.
What I want to happen: click on the select box, make a selection, display the text of the selection in an empty div (later on adding Ajax but one step at a time here)
Code:
<script>
var obj = document.getElementById('select-id');
obj.addEventListener('onchange',my_func);
function my_func(evt){
var inner = document.getElementById('div-id');
inner.setTextValue('hey'); // for testing purposes
}
</script>
The above code doesn't do anything when I make a change to the select box. However, this behaves as planned:
<select name="find_state" id="find_state" onchange="my_func();">
I will be grudgingly using this method as I develop, but would really love to know what I might be doing wrong or if anyone else has this issue? And if anyone has any opinions on the matter I would love to know of some form of facebook development recommendations as applications, pages, and tabs all appear to behave totally different from eachother, yet it seems that they all should be doing the same thing to me? Is there any unified way to develop across all three of these things, or am I missing something?
Thanks in advance, as well as for the past help!
I think it should be:
obj.addEventListener('change',my_func);
(instead of onchange)
Straight from Facebook documentation:
The third parameter [to addEventListener], boolean useCapture is required (it does not have a default value)
That means that you should have:
obj.addEventListener('change', my_func, false);
Use the following html and your events attached with .addEventListener() start to work. This seems to be undocumented "feature".
<select name="find_state" id="find_state" onmousedown="return true;">
This also enables the event to fire first time the user changes the value of select. Otherwise it would fire only on second onchange event.
I am writing an application in JavaScript (with JQuery). The application has a lot of functionality that the user needs to access quickly and possibly at the same time (you could think of it as a game, even though it's not a game) so I've set it up to use the keyboard. I've got a prototype of the system working (in Chrome, at least), but there is a problem in that when I press, for example, Ctrl-T, it opens a new tab. I would like to use this as part of my application to, for example, toggle some setting. In general, I would like to disable the Ctrl-key functionality of the browser. This goes for Alt and Shift, too. In a different way, I would also like to disable the browser's usage of the Tab key. Basically, I want my application to have complete control over the keyboard while it's being used (if they want to navigate away, they will still be able to do so with the mouse). I will add the caveat that I don't care about some of the less-common keys (F1-F12, Windows/Mac-Command, Menu, anything right of the Enter key) because my application mainly targets laptops and many don't have those keys, so they won't be used.
My question is, how can I disable this browser functionality with JavaScript/JQuery/DOM?
I understand that taking over browser functionality in this way this sounds very authoritarian, but it's actually quite necessary. From the prototype and some target-audience test users (my family) everyone has agreed that this was a good idea.
I've also considered moving my application out of the browser and writing it in some application language (probably Java), but I want to find out if this kind of functionality is possible in JavaScript before making that kind of switch. This is prototyping time, though, so every idea is still up for consideration!
Basically, you return false at the right time. See this: How to create Ctrl+Key shortcuts in Javascript.
I should add and say sometimes this doesn't work - it's up to the browser to allow this.
Also, it is sometimes possible to change e.which to another key, but again, this wouldn't always work.