why is this toDataURL line a security error? - security

If an image from another site, is loaded to a page, and then written to canvas as a partial ingredient in a composite, using:
context.drawImage(image, 0, 0, w, h);
it would seem anything insecure would already have occurred on the draw to the canvas.
Why then would
window.location = canvas.toDataURL('image/png');
present an error message. SECURITY_ERR; DOM Exception 18. It doesn't seem any more insecure than the extra step of saving the external site image elsewhere first.
My question is not how to get around this, so much, or what the error means, but rather,
Why is this insecure? If the page is loaded by the server the action is surely expected by the author.

As per the spec, information leakage can occur if scripts from one origin can access information (e.g. read pixels) from images on another origin. The worry is that a malicious app could deduce information that it otherwise wouldn't have access to by loading in an image from another domain/origin (easily done with images) and reading the pixel content. XHR has protections built in place to prevent XD leakage. Images do not.

Related

How to force to show image orientation?

I'm using multer node and express to upload a image to my app. But some images shows rotate 90 degrees when it's on the client.
why is this happening?, how can I fix it?
By the way I'm using vue on the client and for the upload process, of course I use formdata
UPDATE
After research and comments from the guys above, its a EXIF problem. Any code ideas to solve this?
The behaviour you are experiencing is probably caused by the Exif Orientation metadata.
There is another question here on Stackoverflow about this problem: JS Client-Side Exif Orientation: Rotate and Mirror JPEG Images
The selected answer points to a project called Javascript-Load-Image as a possible solution, that basically means you will have to take the orientation in consideration when rendering the images to get a consistent behaviour.
Another possible alternative would be to edit/remove the orientation metadata in your backend.
Check the following resource for more information:
JPEG Image Orientation and Exif
This is most likely caused by Exif metadata (just like #Romulo suggested).
Browsers ignore Exif metadata when displaying images and that's why you're getting this behaviour.
To check that this is related to Exif take 4 pictures with different phone orientation (landscape left, landscape right, portrait, upside down). One of them will be shown properly, while the other 3 will be rotated. (Also note that if you're using the front camera, the image will also get mirrored).
Not all camera phones do this, but iOS does it consistently. The reason for this is performance. When rotation the phone the sensor also rotates and the picture taken doesn't take the rotation into consideration.
To properly show the photo, the image needs to be rotated, but if you just change the Exif metadata then you don't need to do it. Of course, any client that shows the image needs to be aware of this information (and iOS Photos and such are aware).
This has nothing to do with multer, but with the images are stored.
The bottom line is that you need to rotate the image to compensate for this.
Take a look over this npm package to adjust your image on the server side.

How to speed up Inline SVG changes

In my hybrid Android app I use inline SVG to display images that are large (of the order of 2Mb) and complex (several hundred SVG elements per image). When I need to change the image I do the following
var puzzle = document.createElementNS(SVGNS,'svg'),
kutu = document.getElementById('kutu');
puzzle.id = 'puzzle';
puzzle.setAttribute('preserveAspectRatio','none');
puzzle.setAttribute('width','100vw');
puzzle.setAttribute('height','85.5vh');
puzzle.setAttribute('xmlns',SVGNS);
puzzle.setAttribute('xmlns:xlink',XLINK);
puzzle.setAttribute('fill-rule','evenodd');
puzzle.setAttribute('clip-rule','evenodd');
puzzle.setAttribute('stroke-linejoin','round');
puzzle.setAttribute('stroke-miterlimit','1.414');
puzzle.setAttribute('viewBox','0 0 1600 770');
puzzle.innerHTML = SVG;
//SVG here is the SVG image content shorn off the outer <svg>..</svg>
if (0 < kutu.children.length) kutu.children[0].remove();
//remove old image, iff any
kutu.appendChild(puzzle);
//append the new image
While this is working the process of displaying the new image is slow. I suspect it is because of the innerHTML assignment above. Recreating through a sequence of createElementNS, puzzle.àppendChild would require me to first parse the incoming raw SVG content etc. Is that the way to go or would there be a faster way to display the content.
Once again for clarity - SVG here is the content of the new SVG image to be displayed shorn of its outer <svg>...</svg> wrrapper.
Just a side note it would probably be better to use setAttributeNS in place of setAttribute for consistency purpose since createElementNS is used, though it might not make a difference in speeding up the SVG image change.
In the case of a native app, a tool like the Android Profiler if using Android Studio 3.0 and higher can be used to analyze performance bottleneck. However since your app is a hybrid app, some sort of performance profiler that's applicable to the hybrid app (Whether it's Ionic or Cordova, etc.) can help to pinpoint where your performance bottleneck is.
Since your app is a hybrid, without knowing the resource capacity of your android app session, the guess is it seems to be a possible cause that it calls something like .setAttribute to set session-level attributes on the fly during the change of the image and the session resource might not be enough, and also the DOM has to perform .innerHTML and appendChild, which are dynamic operations. DOM manipulation is known to be slow.
Conversion of attributes of all the SVGs and store the result in some sort of storage or cache, and when needed, call it from the persistent storage or cache might be helpful.
Or consider using AngularJS to do the SVG change beforehand and preload the SVG images, refer to easily preload images in your Angular app. Here is another similar code to yours except it's using AngularJS to add SVG for starters.
Another simpler way, without changing your code, if you could minify the incoming SVGs beforehand, is to use SVG Optimizer or SVGO, a node.js open source project to compress your SVGs. Quoted from the SVGO link it says:
"SVG files, especially those exported from various editors, usually contain a lot of redundant and useless information. This can include editor metadata, comments, hidden elements, default or non-optimal values and other stuff that can be safely removed or converted without affecting the SVG rendering result." Although the performance gain might not be obvious going this route.

How can I capture an Image for post processing in OSG

I need to capture an Image from my viewer and need to do some post processing and display it back on it.
Right now am more interested in the first part of it. That is to capture Image from the viewer.
While going through the OSG I came across ScreenCaptureHandler.
But am not able to get an Image out of it.
I am still working to get it done but in case any of you have any other way of how it can be done or an Example for screencapturehandler that you can share.
To capture the rendered view into an image I use a custom osg::Camera::DrawCallback.
To capture the view at any point, set the drawCallback on the camera, force rendering, restore to a NULL callback.
Notice that the following code is part of a member function of a custom viewer (that's probably not your case):
osgViewer::View::getCamera()->setFinalDrawCallback(new ViewCaptureCallback(img));
osgViewer::Viewer::renderingTraversals();
osgViewer::View::getCamera()->setFinalDrawCallback(NULL);
The ViewCaptureCallback basically uses image->readPixels() to read from the backbuffer.
glReadBuffer( GL_BACK );
osg::GraphicsContext* gc = renderInfo.getState()->getGraphicsContext();
// Here you should process the backbuffer's size and format
image->readPixels(0, 0, gc->getTraits()->width, gc->getTraits()->height, pixelFormat, GL_UNSIGNED_BYTE);
Hope it helps

<a4j:mediaoutput , loads images slowly? what can be the reason?

I am inspecting a portal's page for loading of images ,its loading very slow.
We pick images from a filesystem , images name from database and read them, create a list and show results using a4j:mediaOutput tag. but the images are being loaded very slowly.
http://www.easyrenting.com/list-detail/3bhk-ardee-city-sector-52/6263
The first problem I see is that all your pictures are high-res (1800px x 2400px).
You really should create thumbnails server side to meet your view requirement and load images according of the size you want to show on the client size.
Have you only verified that your web page weight about 6.5MB including all images? (Check with Firebug).
I would recommand you a custom servlet like this one FileServlet supporting resume and caching with GZIP, and create a URL pattern according to load full res or thumbnail depending of the requirement.
There is no problem using the a4j:mediaOutput tag.
The images are getting loaded slowly because the size is too large, you need to find out a way to optimize the image size. Probably you can re-size the images before saving it to your file system.
Unless you are giving the zoom functionality, you do not need these big images.
That should help!

Is there a way to lazyload images before they become visible in the viewport using mod_pagespeed?

I configured my .htaccess to lazyload images using mod_pagespeed, but I don't want to affect the user experience by showing an image that is not loaded yet.
Is there a way to set a configuration and lazyload images some pixels before they become visible in the viewport using mod_pagespeed?
If you enable image lazy-loading in mod_pagespeed, the default behavior is to load images on "on scroll". We do have existing code paths to change this to "onload" - aka, load images after onload has fired, but unfortunately we haven't yet exposed it as a configuration flag. A feature for one of the upcoming releases! :-)
Current filter documentation:
https://developers.google.com/speed/docs/mod_pagespeed/filter-lazyload-images
Unfortunately, there is no current way to add an "offset" to when lazyload starts loading the image. It's currently set to the bottom of the viewport, and no option is exposed to configure this. However, I think this would be a valuable option to expose, and I've recorded your feature request at https://code.google.com/p/modpagespeed/issues/detail?id=644.

Resources