Firefox Developer Tools NOT complaining about NOT valid JSON - firefox-developer-tools

I have an API endpoint whose response comes from a secondary server through a transparent proxy. Let us say that normally the answer is
{ "hello": "world" }
Due to the architecture (and yes, it is bad practice, but I haven't authority over this), the "transparent proxy" violates standards, injecting HTML messages in whatever passes through (PNG images included!). The headers are sent from the backend and are not touched by the proxy.
Occasionally, in the obvious scenario, the answer is, almost literally,
<div class="red">ERROR: session token not found</div>
{ "hello": "foobar" }
What is happening is that the backend answers with HTTP/200 and application/json, because it doesn't (and shouldn't) care about the HTTP token. It simply answers with something that's logically garbage (imagine an ATM that, if your PIN is correct, tells you your balance; but if it is incorrect, answers "Balance: 0", because the unauthenticated customer has a balance of 0).
On these occasions, as expected, the front end jQuery throws a fit since the answer is definitely not valid JSON, and I am informed through a .catch(xhr) fallback, and parsing its errorText I can recover the error text. So, I can tell the user that there was a problem, and what the problem was. From the front-end and application points of view, everybody lives happily ever after.
My small problem here is when debugging, because Firefox accepts the answer and displays it as if it was valid JSON, hiding the HTML as if it didn't exist:
{
"hello": "foobar"
}
even if, toggling the [x] RAW switch in the same Firefox Developer Tools window, the non-JSON HTML preamble is displayed as expected, so I can see it's not JSON, albeit, jumbled as it is, I can't see much else:
<div class="red">ERROR: session token not found</div>
{"hello":"foob...
How can I ensure that Firefox Developer Tools will actually treat an invalid JSON as invalid, or show it visually (a flag, a red background...), without having to manually toggle the RAW switch off (to check for errors) and on (to inspect the contents) at each request? Which is unquestionably doable (indeed, it's what I'm doing now), but really irksome.
Example to reproduce
firefox_json_mangle_test.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>JSONFail</title>
<meta charset="utf-8">
</head>
<body>
<button onclick="json_test(0, '200 OK')">OK</button>
<button onclick="json_test(1, '200 OK')">FAIL 200</button>
<button onclick="json_test(2, '500 Some fail')">FAIL 500</button>
<script>
let XHR = (url) => {
console.debug(';; XHR', url);
return new Promise(function(resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function() {
if (xhr.status == 200) {
resolve(xhr);
} else {
reject(xhr);
}
};
xhr.send(null);
});
};
let json_test = (state, http_status) => {
let xhr = XHR('json_serve.php?state=' + state
+ '&http_status=' + escape(http_status)
);
xhr.then(
xhr => console.info(xhr)
).catch(
xhr => console.error(xhr)
);
};
</script>
</body>
</html>
json_serve.php (In same directory as html file)
<?php
header($_SERVER["SERVER_PROTOCOL"] . " " . $_GET['http_status']);
header('Content-Type: application/json;charset=utf-8');
if ($_GET['state'] == '0') {
echo '{"hello": "world"}';
} else {
echo '<div class="red">ERROR: session token not found</div>' . "\n";
echo '{"hello": "foobar"}';
}

This has been reported as bug 1708356. It is apparently an intentional (if overzealous) feature, meant to facilitate viewing JSON responses with XSSI mitigation sentinels. The discussion under the bug report does however suggest the feature is about to be limited.
Firefox ESR 78 is not affected, so until the ticket is resolved, you may consider downgrading; otherwise though, there is little you can do. Doing web development under the ESR version shouldn’t hurt either; since some users do prefer using the ESR version, it should pay off to keep compatibility with it.

Related

How to create a clickable, visible but obfuscated mailto:// link

I know there's already a lot about email obfuscation on this site. But recently I found this neat little CSS-trick that I hadn't encountered before.
It SHOWS the email address (here: user#domain.com), but sadly it doesn't produce a clickable mailto:// link. If one entered it as a href, of course the address would again be ready for bots to be picked up.
So I added a litte javascript routine, that adds an event listener to all .e-mail elements:
// Email de-obfuscation, start mail client, copy email to clipboard:
document.querySelectorAll('.e-mail').forEach(e => {
// get the encoded email address from ::after and decode:
function getDecodeEmail(event) {
z=event.currentTarget;
y=getComputedStyle(z,'::after');
x=y.getPropertyValue('content');
// reverse string rtl
v=x.split("").reverse().join("");
// remove all "
return v.replace(/['"]+/g, '');
};
// onClick start mail client with decoded email address:
e.addEventListener("click", event => {
// prevent href=#
event.preventDefault();
// get the (reversed) email address of the calling anchor
v=getDecodeEmail(event);
//window.location.href="mailto:"+v;
// former statement doesn't fire in SE code snippets,
// but you can try here: https://jsfiddle.net/jamacoe/Lp4bvn13/75/
// for now, let's just display the link:
alert("mailto:"+v);
});
// right mouse click copies email to clipboard:
e.addEventListener("contextmenu", event => {
// prevent href=#
event.preventDefault();
// get the (reversed) email address of the calling anchor
v=getDecodeEmail(event);
// copy v to clipboard
navigator.clipboard.writeText(v);
// just to check:
navigator.clipboard.readText().then( clipText => alert(clipText) );
// former statements don't work in SE code snippets,
// but you can try here: https://jsfiddle.net/jamacoe/Lp4bvn13/75/
});
});
.e-mail::after {
content: attr(data-mailSvr) "\0040" attr(data-mailUsr);
unicode-bidi: bidi-override;
direction: rtl;
}
<a class=e-mail data-mailUsr=resu data-mailSvr=moc.niamod href=""></a>
On the one hand side I'm very content with this solution. But on the other hand, I think my javascript spoils the elegance and simplicity of the HTML/CSS. Does anybody have an idea how to complement this approach of email obfuscation, only using pure CSS + HTML, resulting in a clickable and visable link that meets all common requirements (i.e. screen reader compatible, sufficiently obfuscated, correctly formatted, right clickable for copying)?
I have done something similar in the past. I needed a way to display my email address on one of my websites, but not get horribly spammed in the process. I implemented this 2 years ago, and I haven't received any spam. I didn't do this with CSS though... this is pure JS.
If you hover over the result, you'll see that it creates a clickable email address.
Hope this helps.
let fname = "first";
let lname = "last";
let domain = "gmail.com";
email.innerHTML = `${fname}.${lname}#${domain}`;
<span id="email"></span>

How to prevent users from going back to the previous page?

I am using ASP.NET MVC (latest version).
Imagine having 2 pages:
Page-1: "Enter data" >> Page-2: "Thank you"
After submitting Page-1 you are being redirected to Page-2.
My goal: I want to make sure that you can't go back to Page-1 when you hit the browser's back button once you made it to Page-2. Instead I want you rather to stay on Page-2 (or being pushed forward to Page-2 every time you hit the back button).
I have tried all different kind of things. The following is just some simplified pseudo code ...
[NoBrowserCache]
public ActionResult Page1(int userId)
{
var user = GetUserFromDb(userId);
if (user.HasAlreadySubmittedPage1InThePast)
{
// forward to page 2
return RedirectToAction("Page2", routeValues: new { userId = userId });
}
var model = new Page1Model();
return View("Page1", model);
}
[NoBrowserCache]
[HttpPost]
public ActionResult Page1(Page1Model model)
{
var user = GetUserFromDb(model.UserId);
if (user.HasAlreadySubmittedPage1InThePast)
{
// forward to page 2
return RedirectToAction("Page2", routeValues: new { userId = model.UserId });
}
// Save posted data to the db
// ...
return RedirectToAction("Page2", routeValues: new { userId = model.UserId });
}
public class NoBrowserCache : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Haha ... tried everything I found on the web here:
// Make sure the requested page is not put in the browser cache.
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetNoStore();
filterContext.HttpContext.Response.Cache.AppendCacheExtension("no-cache");
filterContext.HttpContext.Response.Cache.SetExpires(DateTime.Now);
filterContext.HttpContext.Response.Expires = 0;
}
}
If only I could make sure that a request is being sent to the server every time I hit the back button. But right now, clicking the back button just pulls Page-1 from my browser's cache without sending a request to the server. So currently, I have no chance to redirect you forward to Page-2 by server means.
Any ideas or suggestions?
Thanks, guys!
Btw: There is no login/authentication involved. So, I can't use Session.Abandon() or stuff like this. And I would rather use some server based code than javascript if possible.
EDIT 2017-5-12
Following #grek40, I made sure that the anti-chaching statements end up in the browser. I therefor completely removed the [NoBrowserCache]-ActionFilterAttribute from my C# code above. Instead I added the following statements in the <head> section of my _Layout.cshtml:
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
I confirm that these three lines are being rendered to my browser (used my browser's developer tools to inspect). However, caching still works. I can still move backward without any server requests. Tested this with Google Chrome v62, Firefox Quantum v57 and Microsoft Edge v41 (all on Win10). #
EDIT 2017-6-12
Again following #grek40's suggestions: tried Expires: 0 as well as Expires: -1. No difference. I still didn't manage, to turn off my browser's cache.
Finally I found a solution. It's javascript based, but very simple.
I just had to add the following snippet to my Page-2 (the page I don't want users to leave anymore once they got there):
<script type="text/javascript">
$(document).ready(function () {
history.pushState({ page: 1 }, "title 1", "#nbb");
window.onhashchange = function (event) {
window.location.hash = "nbb";
};
});
I found this here: how to stop browser back button using javascript
Thanks to all your support guys. But "my own" solution was the only one that worked.
This can be done by using javascript. Use the following code
<script type = "text/javascript" >
function preventBack(){window.history.forward();}
setTimeout("preventBack()", 0);
window.onunload=function(){null};
</script>
or check the following link1 and link2.
This little piece of code might help you in solving your issue.
<script type="text/javascript">
/*To retain on the same view on Back Click*/
history.pushState(null, null, window.location.href);
window.addEventListener('popstate', function (event) {
history.pushState(null, null, window.location.href);
event.preventDefault();
});
</script>
You can add a line of javascript to every page for a client-side solution:
history.forward();
See docs on MDN. When there is a page to go forward to (which is when the used pressed the BACK button), this will force the user to that page. When the user already is at the most recent page, this does nothing (no error).
Response.Cache.SetCacheability(HttpCacheability.NoCache); // HTTP 1.1.
Response.Cache.AppendCacheExtension("no-store, must-revalidate");
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.

hide iframe url in HTML source code

How to hide iframe url From HTML source code?
<iframe src="http://mysite.com" frameborder="0" scrolling="no" width="728" height="90"></iframe>
You can use javascript to load the source, and it will not be visible in iframe url in page source code.
For example with jQuery:
<script type="text/javascript">
$(document).ready(function(e) {
$('iframe').attr('src','http://www.flickr.com/');
});
</script>
<body>
<iframe src="" />
</body>
Example here.
You can combine it with $.post to get the value serverside:
$.post('get-iframe-src.php', function(data) {
$('iframe').attr('src',data);
});
You can even load iframe itself to some element like:
$.post('get-iframe.php', function(data) {
$('#element_id').html(data);
});
etc. solutions are many, this is just one of.
You can't. If the URL isn't in the HTML, how would the browser know where to get it?
One thing you could try is to obscure it to make it slightly harder for someone to find it. You could have the src attribute be blank and then when the document is ready fetch the URL value from the server in a separate AJAX request and update the iframe tag to include that value in the src.
This would be a fair amount of work, however, and wouldn't really accomplish anything. The only thing it would prevent is somebody finding it by viewing the page source. They can still look at the "current version" of the HTML in any web browser's debugging tools. (Right click on an element and inspect it, which is nearly ubiquitous at this point.) Or any other normal traffic-sniffing tools will see it plain as day.
Ultimately, if the web browser needs to know a piece of information, then that information needs to be visible on the client-side.
There's no way to fully block source viewing. But there are a couple ways to disable right-clicking:
1) Javascript:
<script language="JavaScript">
<!--
var message="Your message goes here.";
function click(e) {
if (document.all) {
if (event.button == 2) {
alert(message);
return false;
}
}
if (document.layers) {
if (e.which == 3) {
alert(message);
return false;
}
}
}
if (document.layers) {
document.captureEvents(Event.MOUSEDOWN);
}
document.onmousedown=click;
// -->
2) Add the following into your tag: oncontextmenu="return false"
reference https://forum.powweb.com/archive/index.php/t-36161.html
I decided for solution that does not use javascript, because most of the time it will be possible to read the "hidden" content.
Moreover, changing iframe SRC with javascript, will keep URL hidden when checking the source. However, inspecting the code will show the real URL.
My code is in PHP; however, I believe that the logic can be translated to other programming languages. This is how it works:
I kept the iframe tag as usual:
<iframe src="dash_url.php"></iframe>
The trick is inside the iframe_url.php, where I validate the referer. If it is valid, page is redirected to iframe URL. If it is not, than URL will be a message.
<?
$iframe_url = "https://example.com";
$Referer = #$_SERVER["HTTP_REFERER"];
$RefererHost = #explode(":", explode("/", explode("//", $Referer)[1])[0])[0];
if ($RefererHost == $_SERVER["SERVER_NAME"]) {
header("Location: " . $iframe_url);
} else {
echo "Invalid URL";
}
?>
If visitor inspects the page or checks the source, iframe tag will show SRC as dash_url.php.

Image load timeout in Internet Explorer

I have a page for an internal app that displays document images streamed from a document storage system using a web service. The problem I am having is that when a user does their search they may get hundreds of hits, which I have to display on one large page so they can print them all. This works fine in Firefox, but in IE it stops loading the images after a while so I get a hundred or so displayed and the rest just have the broken image symbol. Is there a setting somewhere that I can change this timeout?
If the issue is indeed a timeout, you might be able to work around it by using a "lazy load" script and adding new images to the document only after existing images have loaded.
There are a lot of ways to do this, but here's a simple example I threw together and tested. Instead of this:
<img src="image001.jpg" />
<img src="image002.jpg" />
<img src="image003.jpg" />
<img src="image004.jpg" />
<!-- Etc etc etc -->
You could do this:
<div id="imgsGoHere">
</div>
<script type="text/javascript">
function crossBrowserEventAttach(objectRef, eventName, functionRef)
{
try {
objectRef.addEventListener(eventName, functionRef, false);
}
catch(err) {
try {
objectRef.attachEvent("on" + eventName, functionRef);
}
catch(err2) {
// event attachment failed
}
}
}
function addImageToPage()
{
var newImageElement = document.createElement("img");
newImageElement.src = imageArray[nextImageNumber];
var targetElement = document.getElementById("imgsGoHere");
targetElement.appendChild(newImageElement);
nextImageNumber++;
if (nextImageNumber < imageArray.length) {
crossBrowserEventAttach(newImageElement, "load", addImageToPage);
crossBrowserEventAttach(newImageElement, "error", addImageToPage);
}
}
var nextImageNumber = 0;
var imageArray = new Array();
imageArray[imageArray.length] = "image001.jpg";
imageArray[imageArray.length] = "image002.jpg";
imageArray[imageArray.length] = "image003.jpg";
// .
// .
// .
// Snip hundreds of rows
// .
// .
// .
imageArray[imageArray.length] = "image999.jpg";
addImageToPage();
</script>
Each image is added to the page only after the previous image loads (or fails to load). If your browser is timing out, I think that will fix it.
Of course, the problem might actually not be a timeout, but rather that you're running out of memory/system resources and IE is giving up. Or there might be an IE DOM limitation like Sra said.
No final solution, but some hints...
I think the ie Dom hangs up. I,ve seen this in other cases. I needed simply to show the images and used a js which loads the image the time they came into focus, but that want work if you directly hit print I think. Can you use the new css ability to store imagedata directly instead of links. That should solve your problem. I am not quite sure but I think it is supported since ie 7
My guess is that you have to work around the IE setting, the easiest way to do it is simply not showing images that are not loaded or replacing them with a default image:
your html:
<img src="http://domain.com/image.jpg" />
your js:
$('img').load(function(){
// ... loaded
}).error(function(){
// ... not loaded, replace
$(this).attr('src','/whatever/default.jpg');
// ... not loaded, hide
$(this).hide();
});
That is a problem with microsoft. Unfortunately, this is a setting that would have to be changed on every single computer, as there is no remote way to alter it. To change it on your computer, try opening regedit and adding the RecieveTimeout DWORD with a Value of (#of minutes)*6000. Hope this helps-CodeKid1001
Edit: Sorry about that, I forgot to put in the file path:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\InternetSettings
I used something similar to laod HD pictures as a background using ASP Pages
But i used jQuery to handle the images and its loading. This is a sample for 1 image but with a bit of tweaking you can load dynamically
myImage = new Image();
$(myImage).load(function ()
{
$(this).hide(); //Stops the loading effect of large images. can be removed
$('.csBackground li').append(this); //Append image to where you need it
$(myImage).show();
}).attr('src', settings.images[0]) //I pass an array from ASP code behind so 0 can be 'i'
.error( function { checkImages(); } ) //try and relaod the image or something?
So instead of changing the timeout- just try and reload the images on error.
Otherwise i only found a solution that is client specific (HTTP Timeout)
http://support.microsoft.com/kb/813827

How to ignore "Content-Disposition: attachment" in Firefox

How can I cause Firefox to ignore the Content-Disposition: attachment header?
I find it absolutely annoying that I can't view an image in the browser, because it asks me to download it.
I don't want to download the file, I just want to view it in the browser. If the browser doesn't have a plugin to handle it, then it should ask to download.
E.g. I have Adobe Acrobat Reader installed as a plugin for Firefox. I click a link to a PDF, and it asks me to save it, when it should open in the browser using the plugin. This is the behaviour if the server does not send the Content-Disposition: attachment header in the response.
Firefox 3.6.6
Windows XP SP3
Legacy InlineDisposition 1.0.2.4 by Kai Liu can fix this problem.
In the Classic Add-ons Archive at:
caa:addon/inlinedisposition
The "Open in browser" extension is useful for formats supported natively by the browser, not sure about PDF.
Legacy version 1.18 (for users of browsers such as Waterfox Classic) is in the Classic Add-ons Archive at:
caa:addon/open-in-browser
I also found this tonight that totally prevents Firefox from littering your desktop with downloads. It's actually a redirect fix to the hidden /private/temp folder in MAC. Genius.
You can mimic the Windows behaviour simply by changing [Firefox's]
download directory to /tmp.
To do this, open Firefox's General preferences pane, under Save
Downloaded Files To select [choose].... In the dialog that appears,
hit Shift-Command-G to bring up the Go to Folder dialog.
In this dialog, simply type /tmp, hit OK, then hit Select in the
main window.
Well, that's the purpose of disposition type "attachment".
The default behavior (when the header is absent) should be to display in-line.
Maybe there's a configuration problem in your browser, or the Reader plugin?
For PDFs there is an addon called PDF-Download which overrides any attempt to download a PDF and lets the user decide how they want it downloaded (inline, save, external, etc). You could probably modify it to work for other filetypes too.
You could write a firefox extension that removes the disposition header for PDF files. This would be a fairly simple extension.
Since I was looking for a solution and no available add-on was actually working with my Firefox 31.0 (Ubuntu) I decided to try creating my own add-on.
The code if you want to archive a similar goal or just want to know how it works.
console.log("starting addon to disable content-disposition...");
//getting necessary objects
var {Cc, Ci} = require("chrome");
//creating the observer object which alters the Content-Disposition header to inline
var httpResponseObserver = {
//gets fired whenever a response is getting processed
observe: function(subject, topic, data) {
if (topic == "http-on-examine-response") {
var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
httpChannel.setResponseHeader("Content-Disposition", "inline", false);
}
},
//needed for this.observerServer.addObserver --> without addObserver will fail
get observerService() {
return Cc["#mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
},
//used to register with an observer
register: function() {
console.log("register with an observer to get response-events");
this.observerService.addObserver(this, "http-on-examine-response", false);
},
//used to unregister from the observer
unregister: function() {
console.log("unregister from observer");
this.observerService.removeObserver(this, "http-on-examine-response");
}
};
//gets called at enable or install of the add-on
exports.main = function(options, callbacks) {
console.log("content-dispostion main method got invoked");
//call register to make httpResponseObserver.observe get fired whenever a response gets processed
httpResponseObserver.register();
};
//gets called on disable or uninstall
exports.onUnload = function(reason) {
console.log("content-dispostion unloaded");
//unregister from observer
httpResponseObserver.unregister();
};
/*
//not needed!!! just test code for altering http-request header
var httpRequestObserver =
{
observe: function(subject, topic, data)
{
console.log("in observe...");
console.log("topic is: " + topic);
if (topic == "http-on-modify-request") {
var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
httpChannel.setRequestHeader("X-Hello", "World", false);
}
},
get observerService() {
return Cc["#mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
},
register: function()
{
this.observerService.addObserver(this, "http-on-modify-request", false);
},
unregister: function()
{
this.observerService.removeObserver(this, "http-on-modify-request");
}
};
httpRequestObserver.register();
*/
As an alternative you can get my xpi-File to directly install the add-on in Firefox. If you want to disable the "Content-Disposition" altering just deactivate the add-on ;-).
http://www.file-upload.net/download-9374691/content-disposition_remover.xpi.html

Resources