I've read that files in the public folder are accessible via a web browser in Laravel. When I type in the path to files in my public folder, I don't see the file, unless I defined the path in the routes.
I am making a downloads page so that a user can download encrypted/classified materials via a from.
I do not want the ability for a user to access the files in any other way other than the download form or other controlled methods.
Do I need to create lets say a private folder and store the files their. If I do, will I still have access to the files in the back end?
Or are files in the public folder not accessible unless defined by the routes? If thats right could I just store the files under public?
Files under public folder are accessible by anyone, unless your webserver has a policy set to a particular directory.
If you are currently not able to access a file in your public folder is because, maybe, you are not writing the url correctly, ie:
A file in
/var/www/myapp/public/img/logo.png
Will be accessible via:
http://myapp.com/img/logo.png
Note that the public part of your folder is not present in your URL ONLY IF your webserver is correctly configured and your .htaccess file is in place and able to rewrite your URL.
For sensitive files, what you can do is to store them insite your app folder (or any other folder outside public), where just your application will have access to, something like this can be ok:
/var/www/myapp/app/storage/<create a new folder here>
And then, yes, create a route to read and present your secure files:
Route::get('readfile/{fileName}', ['before' => 'auth', 'use' => 'ReadFileController#read']);
The filter 'before' => 'auth' will assure that one not authenticated will never be able to access a file.
In your controller you could do something like this to check if one can see a file:
class ReadFileController extends Controller {
public function read($fileName)
{
if(Auth::user()->id == 1) // of course this is not a good way, just an example
{
return $this->getFile($fileName);
}
else
{
return Response::make(null, 403); // forbidden
}
}
private function getFile($fileName)
{
...
}
}
Also, you can use authentication "middelware" in your routes to add better access control.
Route::get('routeName', ['middleware' => 'auth', 'uses' =>'XController#action']);
Related
I have a security question regarding the access of Next.JS directories, and their access requirements. I have a root folder that has my pages, public, src, styles, models folders. In the src folder I have a settings.json file that is a empty JavaScript object. The idea is that settings would be added to this file and accessed by api routes, to check settings that could be modified on this settings.json file... What I am wondering is if the client can actually somehow just read/access the src directory and get the settings.json file. I want to put secret key's here that way I can easily change secret keys without having to restart my server. So I could just update the secret key live, and have it applied to the settings.json file. Then the update would be live immediately and I don't have to change the environment variables and restart the server.
Is it safe to keep and use a json file in the src directory to store confidential data? If not, is there a way to keep and use a json file for this purpose?
Thanks for the help and info.
As juliomalves pointed out client code won't be able to access a directory or file that you have on the server with the exception of the public directory.
Next gives you the ability to serve static assets from [root]/public as documented here
Note: Only assets that are in the public directory at build time will be served by Next.js.
If this directory is ever renamed, these assets are no longer available from a client.
Note: Don't name the public directory anything else. The name cannot be changed and is the only directory used to serve static assets.
"I put a settings.json file right next to that .env file and required it in an api route, could the client somehow download that settings.json file without me purposely sending them the contents/file itself?"
The only way information can be served from an api route is by expressly creating a route to call res[ponse].send() (or res.json()) with data imported from that file. Api routes are not ever bundled on the client side and only ever exist on the server as noted here.
Any file inside the folder pages/api is mapped to /api/* and will be treated as an API endpoint instead of a page. They are server-side only bundles and won't increase your client-side bundle size.
"What I am wondering is if the client can actually somehow just read/access the src directory and get the settings.json file."
As noted above only assets in the /public directory are accessible as files by path. Directories are never accessible in Next as static assets. This is even pointed out in the source code.
send(req, path)
.on('directory', () => {
// We don't allow directories to be read.
const err: any = new Error('No directory access')
err.code = 'ENOENT'
reject(err)
})
I'm running a few node.js servers on the same framework right now. Somewhere along the lines of code of the framework I have this little snippet:
//...
if (subdomain.staticFolder) {
let relativePath = subdomain.staticFolder + path.sep + path.normalize(url);
if (fs.existsSync(relativePath)) {
let fileStats = fs.statSync(relativePath);
if (fileStats.isFile()) {
//...
This snippet is located inside the handler that manages request traffic. In a nutshell, what it's doing is looking inside a static/ folder for the domain and seeing if any file matches the request.
My concern is that a malicious user may come along and attempt to gain access to the web server's files, exploiting this lookup method of static files. For example:
https://www.example.com/../index.js
https://www.example.com/../serverStructure.json
Is this possible, or am I just worrisome? And, if it is possible, what are some potential solutions? Would moving static files to an S3 bucket be viable? Even if it isn't possible, is this still bad backend practice anyway?
I have deployed an ASP.NET CORE web API project on Azure app services. I have copied a file using an FTP client to /site/wwwroot. Now let suppose file name is xyz.jpg, so it should be accessible with link somename.azurewebsites.net/xyz.jpg but ITS NOT. I have tried pasting the file in other folders to but nothing works.
I also have a controller for uploading pictures. It's also working fine. It uploads the picture in desired folder, i can see the picture via FTP client but still the picture is not accessible via any link. What am I doing wrong here ?
For a Web API application, you have to define the request and response yourself in the controller, or your link can't be recognized by the application.
For example, you can add the method to your controller. It works on my side.
[Route("myroute/{pic}")]
public IActionResult Get(string pic)
{
Byte[] b = System.IO.File.ReadAllBytes("image/"+pic);
return File(b, "image/jpeg");
}
In my code, pictures are stored in the folder called image in the root directory, and I define a route called myroute.
Here's my link to access the picture.https://myappname.azurewebsites.net/myroute/mypicname.jpg
Hope it helps.
I'm doing a node project where I expose my public folder like:
app.use(express.static(path.join(__dirname, '/public')))
So now, all my public files are accessible through localhost:8080/*
I have also created a folder called "views" where I save private views, javascript and css files associated with them. They are private views so I don't want any user to access them.
As I have html linked with my css files and javascript, when the browser try to GET them, it says "not found" because they are not in the public folder.
I'm sending the html as sendFile in the express route.
Is there any way to put all files in the public folder and then protect them for not being accessible to public users? Or is there any alternative to sendFile, so the file is rendered locally and it doesn't need to request the css and javascript files
Thank you in advance
Views are technically private. Because they are rendered server-side, and not directly accessible by the visitors.
But you generally don't want stuff like Javascript, CSS nor views to be private. They will be seen anyway by the user. The only reason to have things like Node.js views private is the fact that they need be rendered by Node.js prior sending them to the user.
If you have private files, you might want to do same.
Otherwise, simply place them on the /public folder. You should not be hiding any secrets inside your JS / CSS code.
Edit (following comment):
You have a couple ways to do that.
Either you build a unique response that contains all necessary HTML / views - CSS - JS.
render('view.ejs', { css: 'body { color: blue }' })
You will need render that variable into your view, just like you might already be doing with your other views.
You might also want to read it from a file:
fs.readFile(`${__dirname}/css/style.css`, (error, styles) => { ... }
Or you handle each file request separately:
Node.js - external JS and CSS files (just using node.js not express)
(if you use Node.js views simply render these one instead of HTML files)
What is the procedure for securing static assets (javascript and css) behind the firewall?
I have an admin section which uses javascript heavily. I don't really want to expose the code to the public.
I currently compile all my javascript using assetic to files in /web/admin/js/xyz.js
Is there a simple way to do this that I'm overlooking?
You could use a controller to serve the static file and secure that controller. Something like:
/**
* Serves static javascript file.
* We have configured /secure to be secured by some firewall
*
* #Route("/secure/xyz.js", name="static_xyz")
*/
public function staticXyzAction()
{
$headers = array(
'Content-Type' => 'text/javascript',
);
return new Response(file_get_contents($this->get('kernel')
->getRootDir().'../web/admin/js/xyz.js'), 200, $headers);
}
This is just an example with the data you provided. Obviously in your final code the file being served should be located in some directory which is not directly accesible by the web server.
The obvious downside to this approach is performance. PHP is much slower for serving an static file than your web server but depending on your load this may not be an issue.
Why do you want to "hide" these admin js files? The js should not perform critical auth or check rights, but just converse with your Sf2 Apis / Controllers which do that, and should not be critical if read. This is a conception matter.
If you are afraid that a lambda user / hacker sees these js files, you could set a very complicated random js output in Assetic. The Symfony .htaccess allows user to access static files only if they know their exact url, they cannot list your repository where you store your builded assets, the firewall catch that.
And last security mesure, use yui-minifier with Assetic to minify and obfusacate your builded js files.