Related
I'm developing a web application and since it has access to a database underneath, I require the ability to disable the developer tools from Safari, Chrome, Firefox and Internet Explorer and Firebug in Firefox and all similar applications. Is there a way to do this?
Note: The AJAX framework provided by the database requires that anything given to the database to be in web parameters that can be modified and that anything it returns be handled in JavaScript. Therefore when it returns a value like whether or not a user has access to a certain part of the website, it has to be handled in JavaScript, which developer tools can then access anyway. So this is required.
UPDATE: For those of you still thinking I'm making bad assumptions, I did ask the vendor. Below is their response:
Here are some suggestions for ways of mitigating the risk:
1) Use a javascript Obfuscator to obfuscate the code and only provide
the obfuscated version with the sold application; keep the non
obfuscated version for yourself to do edits. Here is an online
obfuscator:
How can I obfuscate (protect) JavaScript?
http://en.wikipedia.org/wiki/Obfuscated_code
http://javascriptobfuscator.com/default.aspx
2) Use a less descriptive name; maybe 'repeatedtasks.js' instead of
'security.js' as 'security.js' will probably stand out more to anyone
looking through this type of information as something important.
No you cannot do this.
The developer menu is on the client side and is provided by the user's browser.
Also the browser developer should have nothing to do with your server side database code, and if it does, you need some maaaaaajor restructuring.
If your framework requires that you do authorization in the client, then...
You need to change your framework
When you put an application in the wild, where users that you don't trust can access it; you must draw a line in the sand.
Physical hardware that you own; and can lock behind a strong door. You can do anything you like here; this is a great place to keep your database, and to perform the authorization functions to decide who can do what with your database.
Everything else; Including browsers on client computers; mobile phones; Convenience Kiosks located in the lobby of your office. You cannot trust these! Ever! There's nothing you can do that means you can be totally sure that these machines aren't lying to cheat you and your customers out of money. You don't control it, so you can't ever hope to know what's going on.
In fact this is somehow possible (how-does-facebook-disable-developer-tools), but this is terribly bad idea for protecting your data. Attacker may always use some other (open, self written) engines that you don't have any control on. Even javascript obfuscation may only slow down a bit cracking of your app, but it also gives practically no security.
The only reasonable way to protect your data is to write secure code on server side.
And remember, that if you allow someone to download some data, he can do with it whatever he wants.
There's no way your development environment is this brain-dead. It just can't be.
I strongly recommend emailing your boss with:
A demand for a week or two in the schedule for training / learning.
A demand for enough support tickets with your vendor to figure out how to perform server-side validation.
A clear warning that if the tool cannot do server-side validation, that you will be made fun of on the front page of the Wall Street Journal when your entire database is leaked / destroyed / etc.
No. It is not possible to disable the Developer Tools for your end users.
If your application is insecure if the user has access to developer tools, then it is just plain insecure.
Don't forget about tools like Fiddler. Where even if you lock down all the browsers' consoles, http requests can be modified on client, even if you go HTTPS. Fiddler can capture requests from browser, user can modify it and re-play with malicious input. Unless you secure your AJAX requests, but I'm not aware of a method how to do this.
Just don't trust any input you receive from any browser.
you cannot disable the developer tool. but you can annoys any one who try to use the developer tool on your site, try the javascript codes blow, the codes will break all the time.
(function () {
(function a() {
try {
(function b(i) {
if (('' + (i / i)).length !== 1 || i % 20 === 0) {
(function () { }).constructor('debugger')()
} else {
debugger
}
b(++i)
}
)(0)
} catch (e) {
setTimeout(a, 5000)
}
}
)()
}
)();
Update at the time (2015) when this answer was posted, this trick was possible. Now (2017) browsers are mature. Following trick no longer works!
Yes it is possible. Chrome wraps all console code in
with ((console && console._commandLineAPI) || {}) {
<code goes here>
}
... so the site redefines console._commandLineAPI to throw:
Object.defineProperty(console, '_commandLineAPI',
{ get : function() { throw 'Nooo!' } })
This is the main trick!
$('body').keydown(function(e) {
if(e.which==123){
e.preventDefault();
}
if(e.ctrlKey && e.shiftKey && e.which == 73){
e.preventDefault();
}
if(e.ctrlKey && e.shiftKey && e.which == 75){
e.preventDefault();
}
if(e.ctrlKey && e.shiftKey && e.which == 67){
e.preventDefault();
}
if(e.ctrlKey && e.shiftKey && e.which == 74){
e.preventDefault();
}
});
!function() {
function detectDevTool(allow) {
if(isNaN(+allow)) allow = 100;
var start = +new Date();
debugger;
var end = +new Date();
if(isNaN(start) || isNaN(end) || end - start > allow) {
console.log('DEVTOOLS detected '+allow);
}
}
if(window.attachEvent) {
if (document.readyState === "complete" || document.readyState === "interactive") {
detectDevTool();
window.attachEvent('onresize', detectDevTool);
window.attachEvent('onmousemove', detectDevTool);
window.attachEvent('onfocus', detectDevTool);
window.attachEvent('onblur', detectDevTool);
} else {
setTimeout(argument.callee, 0);
}
} else {
window.addEventListener('load', detectDevTool);
window.addEventListener('resize', detectDevTool);
window.addEventListener('mousemove', detectDevTool);
window.addEventListener('focus', detectDevTool);
window.addEventListener('blur', detectDevTool);
}
}();
https://github.com/theajack/disable-devtool
This tool just disabled devtools by detecting if its open and then just closing window ! Very nice alternative. Cudos to creator.
I found a way, you can use debugger keyword to stop page works when users open dev tools
(function(){
debugger
}())
Yeah, this is a horrible design and you can't disable developer tools. Your client side UI should be sitting on top of a rest api that's designed in such a way that a user can't modify anything that was already valid input anyways.
You need server side validation on inputs. Server side validation doesn't have to be verbose and rich, just complete.
So for example, client side you might have a ui to show required fields etc. But server side you can just have one boolean set to true, and set it to false if a field fails validation and then reject the whole request.
Additionally your client side app should be authenticated. You can do that 100 thousand ways. But one I like to do is use ADFS passthrough authentication. They log into the site via adfs which generates them a session cookie. That session cookie get's passed to the rest api (all on the same domain) and we authenticate requests to the rest api via that session cookie. That way, no one that hasn't logged in via the login window can call the rest api. It can only be called form their browser context.
Developer tool wise, you need to design your app in such a way that anything that a user can do in the developer console is just a (feature) or a breaking thing. I.e. say they fill out all the fields with a js snippet, doesn't matter, that's valid input. Say they override the script and try to send bad data to the api calls. Doesn't matter, your server side validation will reject any bad input.
So basically, design your app in such a way that developer tool muckery either brakes their experience (as it won't work), or lets them make their lives a little easier, like auto selecting their country every time.
Additionally, you're not even considering extensions... Extensions can do anything and everything the developer console can do....
I am just throwing a random Idea maybe this will help.
If someone tries to open the developer tool just redirect to some other site.
I don't know how much this is gonna effective for you but at least they can't perform something on your site.
You can not block developer tools, but you can try to stop the user to enter them. You can try to customize a right-click menu and block the keystrokes for developer tools.
You can't disable developer tools
However...
I saw one website uses a simple trick to make devtools unusable. It worked like this - when the user opens devtools the whole page turns into blank page, and the debugger in devtools is stuck in a loop on a breakpoint. Even page refresh doesn't get you out of that state.
Yes. No one can control client browser or disable developer tool or debugger tool.
But you can build desktop application with electron.js where you can launch your website. Where you can stop debugger or developer tool.
Our team snippetbucket.com had build plenty of solution with electron.js, where similar requirement was their. as well restructure and protect website with many tools.
As well with electron.js many web solution converted and protected in well manner.
You can easily disable Developer tools by defining this:
Object.defineProperty(console, '_commandLineAPI', { get : function() { throw 'Nooo!' } })
Have found it here: How does Facebook disable the browser's integrated Developer Tools?
I'm writing a webscraper/automation tool. This tool needs to use POST requests to submit form data. The final action uses this link:
<a id="linkSaveDestination" href='javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("linkSaveDestination", "", true, "", "", false, true))'>Save URL on All Search Engines</a>
to submit data from this form:
<input name="sem_ad_group__destination_url" type="text" maxlength="1024" id="sem_ad_group__destination_url" class="TextValueStyle" style="width:800px;">
I've been using requests and BeautifulSoup. I understand that these libraries can't interact with Javascript, and people recommend Selenium. But as I understand it Selenium can't do POSTs. How can I handle this? Is it possible to do without opening an actual browser like Selenium does?
Yes. You can absolutely duplicate what the link is doing by just submitting a POST to the proper url (this is, in reality, eventually going to be the same thing that the javascript that fires when the link is clicked does).
You'll find the relevant section in the requests docs here: http://docs.python-requests.org/en/latest/user/quickstart/#more-complicated-post-requests
So, that'll look something like this for your particular case:
payload = {'sem_ad_group__destination_url': 'yourTextValueHere'}
r = requests.post("theActionUrlForTheFormHere", data=payload)
If you're having trouble figuring out what url it is actually be posted to, just monitor the network tab (in chrome dev tools) while you manually click the link yourself, you should be able to find the right request and pull any information off of that.
Good Luck!
With selenium you mimic the real-user interactions in a real browser - tell it to locate an input, write a text inside, click a button etc - high-level approach - you don't even need to know what is there under-the-hood, you see what a real user sees. The downside here is that there is a real browser involved which, at least, slows things down. You can though, automate a a headless browser (PhantomJS), or use a Xvfb virtual framebuffer if you don't have conditions to open up a browser with a UI. Example:
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.get('url here')
button = driver.find_element_by_id('linkSaveDestination')
button.click()
With requests+BeautifulSoup, you are going down to the bare metal - using browser developer tools you research/analyze what requests are made to a server and mimic them in your code. Sometimes the way a page is constructed and requests made are too complicated to automate, or there are anti-web-scraping technique used.
There are pros & cons about both approaches - which option to choose depends on many things.
I am developing a website.
What does mailto: open in if there is no email client (like Outlook, Thunderbird, etc.)?
It works on my computer, which has Outlook, but what if one wants mailto: to open in, say, gmail.com?
What do I need to put in the mailto: statement for that to happen?
As a web developer you don't have any control over the software that a user chooses to open their email, since it's handled by that user's web browser settings, or the OS. If a user has no email program installed on their machine and no operation defined for "mailto" links in their browser, nothing would happen.
The following solution works for me:
(function($)) {
$('a[href^=mailto]').each(function() {
var href = $(this).attr('href');
$(this).click(function() {
var t;
var self = $(this);
$(window).blur(function() {
// The browser apparently responded, so stop the timeout.
clearTimeout(t);
});
t = setTimeout(function() {
// The browser did not respond after 500ms, so open an alternative URL.
document.location.href = '...';
}, 500);
});
});
})(jQuery);
For more info see: https://www.uncinc.nl/articles/dealing-with-mailto-links-if-no-mail-client-is-available
I believe you can use this. https://mail.google.com/mail/?view=cm&fs=1&to=email#domain.com
This however does have its flaws in which the user must be already signed into gmail. Hope this helps!
What happens is entirely up to the client. The OS defines protocol handlers for protocols like mailto: or tel:, etc.
You would need access to the client's registry (in case of a Windows system) to manipulate the handling application for your protocol handler.
For Outlook 2013 as the designated handler, the according Registry structure looks like this:
[HKEY_CLASSES_ROOT\mailto]
#="URL:mailto"
"EditFlags"=hex:02,00,00,00
"URL Protocol"=""
[HKEY_CLASSES_ROOT\mailto\DefaultIcon]
#="C:\\PROGRA~2\\MICROS~1\\Office15\\OUTLOOK.EXE,-9403"
[HKEY_CLASSES_ROOT\mailto\shell]
#="open"
[HKEY_CLASSES_ROOT\mailto\shell\open]
[HKEY_CLASSES_ROOT\mailto\shell\open\command]
#="\"C:\\PROGRA~2\\MICROS~1\\Office15\\OUTLOOK.EXE\" -c IPM.Note /mailto \"%1\""
with a corresponding structure under HKCU.
The mailto URI scheme doesn't decide what happens-- it simply instructs the browser you're using to do whatever it's been configured to do to send e-mails (see the IETF proposed standard for more info). Therefore, you'll have to consult the browser itself to see what it does if no e-mail client is configured.
According to the documentation and to my personal experience, I don't see any way of manually setting an action: It might be possible with certain browsers with some non-standard syntax, but this is unlikely since this would open up a huge potential security problem by being able to execute an arbitrary command by click (such as downloading a virus or something like that).
Since 12 june 2012 11:20 TU, I see very weirds errors in my varnish/apache logs.
Sometimes, when a user has requested one page, several seconds later I see a similar request but the all string after the last / in the url has been replaced by "undefined".
Example:
http://example.com/foo/bar triggers a http://example.com/foo/undefined request.
Of course theses "undefined" pages does not exist and my 404 page is returned instead (which is a custom page with a standard layout, not a classic apache 404)
This happens with any pages (from the homepage to the deepest)
with various browsers, (mostly Chrome 19, but also firefox 3.5 to 12, IE 8/9...) but only 1% of the trafic.
The headers sent by these request are classic headers (and there is no ajax headers).
For a given ip, this seems occur randomly: sometimes at the first page visited, sometimes on a random page during the visit, sometimes several pages during the visit...
Of course it looks like a javascript problem (I'm using jquery 1.7.2 hosted by google), but I've absolutely nothing changed in the js/html or the server configuration since several days and I never saw this kind of error before. And of course, there is no such links in the html.
I also noticed some interesting facts:
the undefined requests are never found as referer of another pages, but instead the "real" pages were used as referer for the following request of the same IP (the user has the ability to use the classic menu on the 404 page)
I did not see any trace of these pages in Google Analytics, so I assume no javascript has been executed (tracker exists on all pages including 404)
nobody has contacted us about this, even when I invoked the problem in the social networks of the website
most of the users continue the visit after that
All theses facts make me think the problem occurs silently in the browers, probably triggered by a buggy add-on, antivirus, a browser bar or a crappy manufacturer soft integrated in browsers updated yesterday (but I didn't find any add-on released yesterday for chrome, firefox and IE).
Is anyone here has noticed the same issue, or have a more complete explanation?
There is no simple straight answer.
You are going to have to debug this and it is probably JavaScript due to the 'undefined' word in the URL. However it doesn't have to be AJAX, it could be JavaScript creating any URL that is automatically resolved by the browser (e.g. JavaScript that sets the src attribute on an image tag, setting a css-image attribute, etc). I use Firefox with Firebug installed most of the time, so my directions will be with that in mind.
Firebug Initial Setup
Skip this if you already know how to use Firebug.
After the installs and restarting Firefox for Firebug, you are going to have to enable most of Firebug's 'panels'. To open Firebug there will be a little fire bug/insect looking thing in the top right corner of your browser or you can press F12. Click through the Firebug tabs 'Console', 'Script', 'Net' and enable them by opening them up and reading the panel's information. You might have to refresh the page to get them working properly.
Debugging User Interaction
Navigate to one of the pages that has the issue with Firebug open and the Net panel active. In the Net panel there will be a few options: 'Clear', 'Persist', 'All', 'Html', etc. Make sure ALL is selected. Don't do anything on the page and try not to mouse over anything on it. Look through the requests. The request for the invalid URL will be red and probably have a status of 404 Not Found (or similar).
See it on load? Skip to the next part.
Don't see it on initial load? Start using your page and continue here.
Start clicking on every feature, mouse over everything, etc. Keep your eyes on the Net panel and watch for a requests that fail. You might have to be creative, but continue using your application till you see your browser make an invalid request. If the page makes many requests, feel free to hit the 'Clear' button on the top left of the Net panel to clear it up a bit.
If you submit the page and see a failed request go out really quick but then lose it because the next page loads, enable persistence by clicking 'Persist' in the top left of the Net panel.
Once it does, and it should, consider what you did to make that happen. See if you can make it happen again. After you figure out what user interaction is making it happen, dive into that code and start looking for things that are making invalid requests.
You can use the Script tab to setup breakpoints in your JavaScript and step through them. Investigate event handlers done via $(elemment).bind/click/focus/etc or from old school event attributes like onclick=""/onfocus="" etc.
If the request is happening as soon as the page loads
This is going to be a little harder to peg down. You will need to go to the Script tab and start adding break points to every script that runs on load. You do this by clicking on the left side of the line of JavaScript.
Reload your page and your break points should stop the browser from loading the page. Press the 'Continue' button on the script panel. Go to your net panel and see if your request was made, continue till it is found. You can use this to narrow down where the request is being made from by slowly adding more and more break points and then stepping into and out of functions.
What you are looking for in your code
Something that is similar to the following:
var url = workingUrl + someObject['someProperty'];
var url = workingUrl + someObject.someProperty;
Keep in mind that someObject might be an object {}, an array [], or any of the internal browser types. The point is that a property will be accessed that doesn't exist.
I don't see any 404/red requests
Then whatever is causing it isn't being triggered by your tests. Try using more things. The point is you should be able to make the request happen somehow. You just don't know yet. It has to show up in the Net panel. The only time it won't is when you aren't doing whatever triggers it.
Conclusion
There is no super easy way to peg down what exactly is going on. However using the methods I outlined you should be at least be able to get close. It is probably something you aren't even considering.
Based on this post, I reverse-engineered the "Complitly" Chrome Plugin/malware, and found that this extension is injecting an "improved autocomplete" feature that was throwing "undefined" requests at every site that has a input text field with NAME or ID of "search", "q" and many others.
I found also that the enable.js file (one of complitly files) were checking a global variable called "suggestmeyes_loaded" to see if it's already loaded (like a Singleton). So, setting this variable to false disables the plugin.
To disable the malware and stop "undefined" requests, apply this to every page with a search field on your site:
<script type="text/javascript">
window.suggestmeyes_loaded = true;
</script>
This malware also redirects your users to a "searchcompletion.com" site, sometimes showing competitors ADS. So, it should be taken seriously.
You have correctly established that the undefined relates to a JavaScript problem and if your site users haven't complained about seeing error pages, you could check the following.
If JavaScript is used to set or change image locations, it sometimes happens that an undefined makes its way into the URI.
When that happens, the browser will happily try to load the image (no AJAX headers), but it will leave hints: it sets a particular Accept: header; instead of text/html, text/xml, ... it will use image/jpeg, image/png, ....
Once such a header is confirmed, you have narrowed down the problem to images only. Finding the root cause will possibly take some time though :)
Update
To help debugging you could override $.fn.attr() and invoke the debugger when something is being assigned to undefined. Something like this:
(function($, undefined) {
var $attr = $.fn.attr;
$.fn.attr = function(attributeName, value) {
var v = attributeName === 'src' ? value : attributeName.src;
if (v === 'undefined') {
alert("Setting src to undefined");
}
return $attr(attributeName, value);
}
}(jQuery));
Some facts that have been established, especially in this thread: http://productforums.google.com/forum/#!msg/chrome/G1snYHaHSOc/p8RLCohxz2kJ
it happens on pages that have no javascript at all.
this proves that it is not an on-page programming error
the user is unaware of the issue and continues to browse quite happily.
it happens a few seconds after the person visits the page.
it doesn't happen to everybody.
happens on multiple browsers (Chrome, IE, Firefox, Mobile Safari, Opera)
happens on multiple operating systems (Linux, Android, NT)
happens on multiple web servers (IIS, Nginx, Apache)
I have one case of googlebot following the link and claiming the same referrer. They may just be trying to be clever and the browser communicated it to the mothership who then set out a bot to investigate.
I am fairly convinced by the proposal that it is caused by plugins. Complitly is one, but that doesn't support Opera. There many be others.
Though the mobile browsers weigh against the plugin theory.
Sysadmins have reported a major drop off by adding some javascript on the page to trick Complitly into thinking it is already initialized.
Here's my solution for nginx:
location ~ undefined/?$ {
return 204;
}
This returns "yeah okay, but no content for you".
If you are on website.com/some/page and you (somehow) navigate to website.com/some/page/undefined the browser will show the URL as changed but will not even do a page reload. The previous page will stay as it was in the window.
If for some reason this is something experienced by users then they will have a clean noop experience and it will not disturb whatever they were doing.
This sounds like a race condition where a variable is not getting properly initialized before getting used. Considering this is not an AJAX issue according to your comments, there will be a couple of ways of figuring this out, listed below.
Hookup a Javascript exception Logger: this will help you catch just about all random javascript exceptions in your log. Most of the time programmatic errors will bubble up here. Put it before any scripts. You will need to catch these on the server and print them to your logs for analysis later. This is your first line of defense. Here is an example:
window.onerror = function(m,f,l) {
var e = window.encodeURIComponent;
new Image().src = "/jslog?msg=" + e(m) + "&filename=" + e(f) + "&line=" + e(l) + "&url=" + e(window.location.href);
};
Search for window.location: for each of these instances you should add logging or check for undefined concats/appenders to your window.location. For example:
function myCode(loc) {
// window.location.href = loc; // old
typeof loc === 'undefined' && window.onerror(...); //new
window.location.href = loc; //new
}
or the slightly cleaner:
window.setLocation = function(url) {
/undefined/.test(url) ?
window.onerror(...) : window.location.href = url;
}
function myCode(loc) {
//window.location.href = loc; //old
window.setLocation(loc); //new
}
If you are interested in getting stacktraces at this stage take a look at: https://github.com/eriwen/javascript-stacktrace
Grab all unhandled undefined links: Besides window.location The only thing left are the DOM links themselves. The third step is to check all unhandeled DOM links for your invalid URL pattern (you can attach this right after jQuery finishes loading, earlier better):
$("body").on("click", "a[href$='undefined']", function() {
window.onerror('Bad link: ' + $(this).html()); //alert home base
});
Hope this is helpful. Happy debugging.
I'm wondering if this might be an adblocker issue. When I search through the logs by IP address it appears that every request by a particular user to /folder/page.html is followed by a request to /folder/undefined
I don't know if this helps, but my website is replacing one particular *.webp image file with undefined after it's loaded in multiple browsers. Is your site hosting webp images?
I had a similar problem (but with /null 404 errors in the console) that #andrew-martinez's answer helped me to resolve.
Turns out that I was using img tags with an empty src field:
<img src="" alt="My image" data-src="/images/my-image.jpg">
My idea was to prevent browser from loading the image at page load to manually load later by setting the src attribute from the data-src attribute with javascript (lazy loading). But when combined with iDangerous Swiper, that method caused the error.
I'm using a page unload trigger to warn the user of unsaved changes while leaving the page/closing the tab/etc... and this works fine.
//Exit event
if (!changes_saved) {
window.onbeforeunload = confirmExit;
}
function confirmExit()
{
return "Your changes will be lost if you leave this page!";
}
My problem is that the browser (both Firefox and IE) enwraps the custom message with
"Are you sure you want to navigate away from this page" in the beginning and with "Press OK to continue, or Cancel to stay on current page." at the end.
My question:
is there any way to avoid this and completely customize the message in the dialog?
Need for this isn't abstract, I'm developing a multi language interface and localized message mixed with the enforced one just looks silly.
Thank you.
This question has been asked before.
Apparently, modifying this standard dialog is not possible because of browser security. If it were possible, it would allow a malicious site to fool you into staying on a page.
However, the language of the message is based on the language settings of the user's machine just like any other standard dialog.
I am afraid this is not possible. Had the same problem once, googled around for it and found a link on the msdn saying it cannot be done (for IE atleast which I was concerned about by then).
I can't find this link again though.