Displaying an image in Angular that was saved on node.js backend - javascript

So I have a question concerning security. Imagine that I have uploaded a picture of an animal to the server. I have saved 1545419953137bear.jpg on the backend in my uploads folder where I save all my images.
On the frontend I have this img element where I use [src] to dynamically create a path to this uploads folder to retrieve this image of a bear.
My question is now: Is this the correct way to do this or does this leave me vulnerable to security issues? And if so, what would be a better way to handle this?
on the left side you see the uploads folder of the backend, right side how I create this file
html code (angular)
<img [src]="linkImg(post.fileName)">
component method: this method returns a url that will display the image. Is this the right way to do this or is this lacking security?
linkImg(fileName) {
// base_URL returns localhost:3000 or the production URL
return `${this.BASE_URL}/uploads/${posterProfilePic}`;
}

Its a good way to handle the serve images. Keep in mind your server should be secure.
In case you want to protect the images for public display you need to make them secure through a middleware or any of the server technique and checking is an authenticated request or not.
From angular side it is good.
A read for security
https://nodesource.com/blog/nine-security-tips-to-keep-express-from-getting-pwned/

Related

Not allowed to load local resource: ReactJS

I am working on a real-time chat application, and I want to allow users to upload their own images to use as avatars. When a user uploads an image, the backend displays the following URL: file:///C:/fakepath/016CF4E2-65C6-46E1-8C5C-415E74970948.jpeg. When I log in to the app and check the console, however, I am greeted by the following message: Not allowed to load local resource: file:///C:/fakepath/016CF4E2-65C6-46E1-8C5C-415E74970948.jpeg. I was testing, and I then decided to change the input type from file to URL, and I then pasted the random address of a google image, and then when I loaded it back into the app the image had disappeared. Is there any way to allow for user-uploaded images to be displayed? I am using stream-chat API if that also helps, as well as Heroku and nodejs.
Keep the input as type="file". The user is picking a file from their disk. It won't have a URL.
fakepath comes from trying to treat the file input as a string instead of as a file. If you are using JavaScript, don't use the value property of the field as it is only useful for informational and debugging purposes. If you are submitting a form then it needs to be able to handle file inputs (and the default enctype doesn't).
Upload the image to a server. How you do this depends on your approach, if it is with a form then the enctype attribute needs to be set to multipart/form-data, if it is with Ajax then you should start with a FormData object.
On the server, parse the request (the specifics depend on your server side environment) and save the file somewhere.
Give the file a URL (either by saving it to a place that static files are served from or by having another server side process read the file (from wherever you saved it) on demand).

Securing image upload using Node and AWS Lambda

I'm implementing image upload via browser form and I'm working with AWS and NodeJS. The process is that user selects a file, provides additional info and it all is send to backend using multipart/form-data.
This works great so payload goes thru API Gateway ---> Lambda and this lambda uploads to S3 bucket. I'm using busboy to deal with multipart data and end up with nice JSON object containing all the data send from frontend, something like:
{
userName: "Homer Simpson",
file: base64endcoded_string,
}
Then I grab this base64endcoded_string and upload to S3 so file sits in there and I'm able to open it, download etc.
Now, obviously I don't trust any input from frontend and I wonder what is the best way to ensure that file being send is not malicious.
In this case I need to allow upload only images, say png,jpg/jpeg up to 2mb in size.
Busboy gives me the MIME type, encoding and other details but not sure if this is reliable enough or I should use something like mmmagick or else. How secure and reliable would these solutions be?
Any pointers would be much appreciated.
OWASP has a section on this with some ideas, anyways i found out that the best method to secure a image upload is to convert it, period, if you can convert it it's an image and you are sure that any attached info (code, hidden data, etc) is removed with the conversion process, if you can't it's not an image.
Another advantage is that you can strip exif info, add some data (watermarks for example), etc

Efficient way to display images(serve images) in MEAN stack application?

I am developing a MEAN stack application and i want to display the images with some responses.
Exact Requirement: There is search box , when user enter the name of the image , server should respond with that image and browser display that image.
I have maximum of 70 images with size 30kb maximum.
Should I store these inside the mongoDB and for every request node server hit the mongodb and serve that image in the response or I serve it with Angular.js?
Please recommend the efficient way to do that.
You can setup a folder for static content (CSS, images, etc) do it in your expess.js configuration probably you'll find something like this:
app.use(express.static(path.resolve('./public')));
app.use('/images',express.static(path.resolve('youPathToStaticimages')));
Then create a collection with the image metadata, like file name, size, uploaded date, friendly name and maybe tags or any other field that you can query.
Then use an endpoint / $resource combination and retrieve the data and display the images in the client with a simple HTML image tag (IMG) and use ng-src, probably within a ngRepeat.
For me that could be the easiest way to do it, also you can set some sort of cache policy to your image folder in apache or ngnix.
You've got a little over 2mb of data which can be easily cached. Transferring from the database to the web server or retrieving from disk is extra work. Load all the images into your node thread and when the keyword comes through send the cached image.

Prevent Download Via URL

I currently have a PHP file asks you to login using a MySQL database. Once logged in, 3 links appear allowing me to download files. Although, if I access the file directly it will download without having to login. How would I prevent people from downloading via the URL bar, but still allow JavaScript to download the file?
If this isn't possible, is there something else I can do to allow download? For example, using PHP to download instead of JavaScript? I know JavaScript is client side, so I wonder if that will prevent it from accessing the download.
I can't really give much code, but here is the JavaScript that downloads it. The link basically calls the downloadLink function;
var downloadURL = function downloadURL(url) {
cLog("STDOUT: Attempting Download Of File: "+url);
var hiddenIFrameID = 'hiddenDownloader',
iframe = document.getElementById(hiddenIFrameID);
if (iframe === null) {
iframe = document.createElement('iframe');
iframe.id = hiddenIFrameID;
iframe.style.display = 'none';
document.body.appendChild(iframe);
}
iframe.src = url;
};
function downloadLink(fileLink) {
if (fileLink) {
cLog("STDOUT: File Link: "+fileLink);
downloadURL("/DownloadAssets/"+fileLink);
cLog("STDOUT: Function Finish, File Should Be Queded");
} else {
cLog("ERROR: No File Link");
}
}
Basically, you can't.
An HTTP server has absolutely no idea whether any given HTTP request is coming from the browser URL bar, an iframe in a page or from Javascript code. They are all just HTTP requests.
If you want to allow some types of access and prevent other types of access, then you have to implement access control on your server so that the HTTP request is not fulfilled unless the proper credentials are provided.
The challenge with the browser environment is that pretty much nothing in your client side code is secure (it is all available for inspection by anyone) so a determined hacker will be able to find any secret codes you put in your client-side javascript to be used as credentials and they can then use them whenever.
I can't tell exactly what you're really trying to do, but sites that want to provide downloads to only certain users, often do something like this:
Make the user login to your site
This provides a unique user ID in their cookie that comes with all HTTP requests from that user.
Then coin a unique download URL with some unique codes in it.
In your own database server-side, create a record that associates those download URL codes with the user ID that they belong to.
When an HTTP request comes in for that unique download URL, your server extracts the download codes from the URL, extracts the userID from the cookie with the request, looks the codes up in the database and check is this is the correct userID for those codes.
If they match, the server serves up the appropriate download file.
If they don't match, the server serves up a file advising the user that they are not authorized to download that file and instructs them what they have to do to obtain authorization.
A server will typically expire these download codes after some short period of time (e.g. a few days) so they can only be used in the short term.
This technique makes it so there is no universal download link that every one can use and it prevents one user from sharing the download link with other users.
This technique will not attempt to discern the difference between someone typing a request in a browser URL bar vs. one coming from an iframe or one coming from a Javascript request and generally, there should not be a need to know the difference. Any content that can be gotten any of these ways can be used the same so there is no real security benefit to allowing only one way and preventing the others.
This isn't really something you solve with javascript, since that is run client-side. When you have users login, you would need to place a cookie in their jar that signifies that they've logged in. On your webserver, only allow people to access that URL that have that auth cookie.
First you need some 'login system' to your site. Then you need Apache web server (or other that handle 'rewrite mod' rules, but in Apache configuration is super simple [just craete .htaccess file]).
All you need to do is to block access to files in folder with files (and give it only to logged users).
Create file .htaccess (hard to do on Windows [that name of file], try to download that file from internet) in folder with files to download with content:
http://paste.ots.me/562452/text
(this .htaccess file should redirect all HTTP requests to that folder to file download.php )
Create download.php file with content:
http://paste.ots.me/562451/text
// for unknown reason I cannot paste code in post.

Upload To Blob Storage With Javascript(Client Browser) With SAS

I'm trying to implement an HTML controller in my webapp that will upload files from the client to my azure blob storage.
I know how to do it in the server side with C# but this solution isn't right for me because i'm dealing with a large volume files(that the client uploads), so I don't want to upload them to my server side, I want that the client will upload them straight to the blob storage.
but here is where I'm lost, maybe you could help me.
Objective: I need to grant SAS for that user.
Solution: I call(using AJAX) to a server side method that generate the string (string - URL + SAS token)
Now all is left to do is split the files to chunks and upload them giving the URL with the token that I generate on the server side.
I read a lot of article about it but every article says different things, half of them was in the period that azure was not supporting CORS, so a huge amount of them out of date.
How can I do the last two things in the right way :
1.Chunk the file.
2.Upload the file.
One last thing i read in some article that i need to split the file to chunks and then upload all the chunks and then to commit or something all the chunks so its become one file in the storage.(maybe i got it in the worng way)
anyway if somebody could help me with guidelines or anything that will help me overcome this two last jobs needed to be done
*Update:
The errors I get(1.OPTION 2. headers):
Open the image in a new tab to see it properly
*Update 2:
This is how i set the CORS:

Categories