Skip to content
This repository has been archived by the owner on Nov 1, 2018. It is now read-only.

Discussion for: Publish for IIS changes to web.config location #158

Closed
danroth27 opened this issue Apr 27, 2016 · 34 comments
Closed

Discussion for: Publish for IIS changes to web.config location #158

danroth27 opened this issue Apr 27, 2016 · 34 comments

Comments

@danroth27
Copy link
Member

danroth27 commented Apr 27, 2016

Discussion for aspnet/Announcements#173

@tuespetre
Copy link

Does this mean contentLibPath or whatever that was introduced in Web Deploy 3.6 will eventually be deprecated?

@Kukkimonsuta
Copy link

I'm a bit concerned about this change. I was pretty happy seeing that IIS points directly to wwwroot because then even if I mess up there is no way IIS would serve logs, configs or other items if I use the default structure that seem to be look like:

/root
    /wwwroot/
        site.css
    /logs/
        log-with-private-data.txt
    web.config
    myapp.dll
    myconfig.json

Now to be 100% sure that iis will under no circumstances serve these files, we need to go back to blocking various path segments or extensions in IIS or go deeper with the structure to something like

/root
    /app
        /wwwroot/
            site.css
        web.config
        myapp.dll
    /logs/
        log-with-private-data.txt
    myconfig.json

Which makes me feel like the main point of wwwroot is gone and we are back where we started.

@tuespetre
Copy link

The module for ASP.NET core completely takes the request from IIS so there is no chance it would be served unless you configured IIS to specifically serve them.

@muratg muratg added this to the Discussions milestone Apr 27, 2016
@davidfowl
Copy link
Member

Does this mean contentLibPath or whatever that was introduced in Web Deploy 3.6 will eventually be deprecated?

Yes

@Kukkimonsuta
Copy link

@tuespetre I understand how it works in "well configured" scenarios, but imagine the deployment fails somewhere and for some reason deletes web.config. Now you have IIS with default configuration pointed in your directory with configs, logs and possibly other private data and IIS will be happy to serve them.

I agree, that this is scenario that's just not supposed to happen, but in real life these things >can< happen and when it comes to this sensitive information, one has to be extra careful. What I dislike about this change is that it decreases the convenience of achieving such security from the default back to the old asp.net where you have to rely on IIS being configured properly on machine level and not serve files from certain 'magic' paths or extensions or alter the project structure accordingly and do extra steps that are different on local vs staging/production environments (like locating configuration files).

@davidfowl
Copy link
Member

@Kukkimonsuta this is our new default because of the technology and ecosystem we've built around web hosting in IIS. If you control everything, you can certainly move the web.config back into the wwwroot folder and point IIS there.

@guardrex
Copy link
Contributor

Now you have IIS with default configuration pointed in your directory with configs, logs and possibly other private data and IIS will be happy to serve them.

Yeah ... This is kind'a serious (logs prob wouldn't have the right extension to pass, but JSON and XML is cool with IIS). If you don't have a web.config (or perhaps a malformed web.config), you might end up serving sensitive data from the allowed file extensions.

Just to demo this, I removed web.config from a test proj on the server and requested teststandalone.runtimeconfig.json, teststandalone.xml (xmlDoc comments), and teststandalone.deps.json.

... well ... this is a bit 💀 scary 💀 ... you know things are going to end badly for someone down the road.

cc/ @blowdart @danroth27 @Rick-Anderson ... at the very least I'll add a warning in the Publishing to IIS doc update for you cats to vet and mull over.

capture

capture2

capture3

@blowdart
Copy link
Member

Oh believe me I've already expressed my reservations about this change.

However a malformed web.config will just error out, and nothing gets past that.

@guardrex
Copy link
Contributor

@blowdart Almost true .... The schema will match and pass if the <aspNetCore> node is missing. If I merely change the file to this ...

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>

    </handlers>
    <aspNetCore processPath=".\teststandalone.exe" stdoutLogEnabled="true" stdoutLogFile=".\logs\teststandalone" />
  </system.webServer>
</configuration>

It will not error out and IIS will serve all of that content. Of course, that's an unlikely scenario.

It's much more likely that the file will just be absent or accidentally renamed. Once, I saw a web.config accidentally get moved on a server that completely disabled a production app. A dev was on a box doing something ... he was using one of those rack-mounted keyboards with a crappy trackpad built-in ... you know what I mean ... we've all had the displeasure many times ... and the dude accidentally dragged the web.config from one folder to another when moving some other file or files ... 💥 ... the absence of the web.config in that case resulted in the app failing. In the new .NET Core world order, such a mistake would result in these sensitive files becoming immediately available.

I can at the very least caution folks in the guidance about this, but this doesn't have any easy, obvious fix AFAICT. The second one makes the IIS website physical path the application base path containing JSON, XML, TXT, and other files that IIS will be happy to serve, this risk will present itself. @Kukkimonsuta is right on point.

@blowdart
Copy link
Member

I think we could go further in documentation, and at least walk people through how to configure IIS not to serve .json files

@guardrex
Copy link
Contributor

It could complicate matters if the app is supposed to serve dev-sanctioned JSON files to enforce a blanket extension filter; as you know, IIS would stop all such requests dead in their tracks.

It feels like you almost end up having to tell server admins to make an IIS server-wide change and add these sensitive known filenames of known config files to the Hidden Segments of Request Filtering ... either through the UI at the server level or in machine.config.

Even that leaves a hole where devs may come along and not realize what they're doing by adding a custom-named JSON or XML config file anywhere in the app that they didn't explicitly tell IIS not to serve. If the web.config goes MIA (accidentally moved or renamed) sometime down the road, IIS will be quite happy to serve any of these files from anywhere. This was always a concern, and it's still going to be a concern. Devs will just need to be careful.

Anywho ... I'll try to craft some good language on this one. I'll ping you back on it when I get some draft language in the draft PR, which I might have by the end of the day.

@tuespetre
Copy link

tuespetre commented Apr 28, 2016

  • Nothing really changed with logs. The target location of the logs needed to be configured to point outside of the wwwroot folder to avoid being served anyways, even before this change. The default was to just spit them out right there in the wwwroot folder. Edit: This assumes that the application used the static file middleware with the default configuration
  • Would the team consider changing wwwroot back to a default name of Content since it's not truly a 'wwwroot folder' anymore? This would be more familiar to those coming from ASP.NET 4.x and earlier.
  • The real cat's meow would be for Web Deploy to support deploying to a folder above the 'web root' without having to invoke a separate handler. I don't see any reason why the good ol' contentPath handler couldn't just be modified to support that scenario; ACLs could take care of file system security (making sure a deploy doesn't reach up further than it should be able to.) With this approach we might be able to have our cake and eat it too, although it does lead me to ask: was the contentLibPath approach ditched because it was 'dirty' to have to make two web deploy calls, or was it ditched because the team doesn't want users to have to install yet another thing (in this case, a Web Deploy update) to be able to use ASP.NET Core?

@Bartmax
Copy link

Bartmax commented May 7, 2016

3 words:

lazy, stupid and non-sense.

@davidfowl
Copy link
Member

davidfowl commented May 8, 2016

Would the team consider changing wwwroot back to a default name of Content since it's not truly a 'wwwroot folder' anymore? This would be more familiar to those coming from ASP.NET 4.x and earlier.

Nope, it is the wwwroot folder as IIS still isn't responsible for servicing static files.

The real cat's meow would be for Web Deploy to support deploying to a folder above the 'web root' without having to invoke a separate handler. I don't see any reason why the good ol' contentPath handler couldn't just be modified to support that scenario; ACLs could take care of file system security (making sure a deploy doesn't reach up further than it should be able to.) With this approach we might be able to have our cake and eat it too, although it does lead me to ask: was the contentLibPath approach ditched because it was 'dirty' to have to make two web deploy calls, or was it ditched because the team doesn't want users to have to install yet another thing (in this case, a Web Deploy update) to be able to use ASP.NET Core?

It was a hack and didn't work well with most hosters configuration. With the new layout things were being dumped one folder up from the wwwroot. We looked at a few options but ultimately this one had the best set of trade offs and on the plus side required no server side changes to web deploy.

@buraktamturk
Copy link

buraktamturk commented May 8, 2016

@davidfowl but this way we can't really ensure the hosting provider's IIS config, therefore it's more possible to serve the code or the config as static files than the old way. It is fairly possible to a broken IIS extension, that would try to serve our private files to public, could be installed to the hosting.

I agree with your point, but every option has some advantages and disadvantages in computer field, why wouldn't we just consider two approaches and find the best one here (or better, two approaches, but what developer choices for)?

@guardrex
Copy link
Contributor

guardrex commented May 8, 2016

Referencing other issue for moving the web.config file back to wwwroot -OR- using Hidden Segments of Request Filtering to stop IIS from serving sensitive files: #164

@davidfowl
Copy link
Member

davidfowl commented May 8, 2016

@davidfowl but this way we can't really ensure the hosting provider's IIS config, therefore it's more possible to serve the code or the config as static files than the old way. It is fairly possible to a broken IIS extension, that would try to serve our private files to public, could be installed to the hosting.

If you control the hosting environment, then as @guardrex mentions, you'll be able to go back to the former model which is safer as IIS never sees anything but the wwwroot folder.

I agree with your point, but every option has some advantages and disadvantages in computer field, why wouldn't we just consider two approaches and find the best one here (or better, two approaches, but what developer choices for)?

Yep, we chose the best one given the trade offs. This is what we do everyday (as you mentioned).

@Bartmax
Copy link

Bartmax commented May 8, 2016

why the @guardrex approach (if it works) cannot be the default?

@davidfowl
Copy link
Member

@Bartmax because we can't change every hoster and IIS server that exists on the planet. When you host node on IIS it's the same idea (and it sucks) but that's just how IIS runs.

@giggio
Copy link

giggio commented May 14, 2016

The wwwroot name makes absolutely no sense, now, as it is not the site's root, anymore.
Now that the name is meaningless, change this directory name to public, which is what everyone else uses. You are already moving people from Content, why not move them to the proper name used by all other stacks?

@guardrex
Copy link
Contributor

@giggio I did a search, and it looks like that particular design decision was made in ancient times. It would be interesting to hear the history and reasoning on wwwroot. I get the approot ... webroot play on root, but it definitely could have been approot ... public or publicroot back then. It's very webbish today! (maybe toooo webbish)

@buraktamturk
Copy link

@davidfowl That was should to be said when HttpPlatformHandler was introduced (and AspNetCoreModule).

@tuespetre
Copy link

@danroth27 @davidfowl @blowdart

What about the 'bin' folder? Chatting with @guardrex, we're seeing that it appears to be a default 'hidden segment' configured in IIS -- and while static files and view templates technically aren't binaries, that could offer a more secure 'easy default' for IIS deployments. What do you think? Publish outputs into a bin folder with a sibling web.config that points into it?

@guardrex
Copy link
Contributor

Let's also consider the guidance to remove the IIS static file module from
either the app or server.
On May 20, 2016 1:18 PM, "Derek" [email protected] wrote:

@danroth27 https://github.com/danroth27 @davidfowl
https://github.com/davidfowl @blowdart https://github.com/blowdart

What about the 'bin' folder? Chatting with @guardrex
https://github.com/guardrex, we're seeing that it appears to be a default
'hidden segment' configured in IIS -- and while static files and view
templates technically aren't binaries, that could offer a more secure 'easy
default' for IIS deployments. What do you think? Publish outputs into a bin
folder with a sibling web.config that points into it?


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#158 (comment)

@blowdart
Copy link
Member

Wait, why are views being served anyway? .cshtml should be in the unsafe list.

@blowdart
Copy link
Member

Removing the IIS module sounds like a good idea, if the hoster supports it, and that section isn't locked :)

@guardrex
Copy link
Contributor

@blowdart right ... if they can do it. Otherwise, they will prob only have one option .... the workaround that moves web.config back to wwwroot.

@tuespetre
Copy link

@blowdart I was commenting more about "those other files that aren't binaries" being deployed into the bin folder.

@guardrex
Copy link
Contributor

For the unofficial Slack #iis channel "IIS Hotline! Links, Notes & Tips," I say ...

There is only one comprehensive way to secure files from accidental file serving by the IIS static file module: Remove the IIS static file module from the website (or remove it at the server level). We expect that most .NET Core apps that will serve static files will do so out of wwwroot via the Static File Middleware. Therefore, removing the IIS static file module should not pose a problem for the typical .NET Core app. [Note that removing the module in IIS is not official Microsoft guidance at this time. This subject is currently under discussion with Microsoft team members.]

Alternative Approach: It should be possible for one to move the web.config file back to the webroot folder (usually wwwroot). This approach has not been thoroughly explored for local and remote debugging, but you can learn more about this approach at Head-check on moving web.config back to wwwroot.

@AR1ES
Copy link

AR1ES commented May 22, 2016

What about URL rewrite?
Condition IsFile does not work, because it does not match the physical path.
My rule:

        <rule name="Add trailing slash" stopProcessing="true">
          <match url="^((?!api).*[^/])$" />
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          </conditions>
          <action type="Redirect" redirectType="Permanent" url="{R:1}/" />
        </rule>

@guardrex
Copy link
Contributor

guardrex commented May 22, 2016

@AR1ES I don't have too much experience with needing to mod the default behavior with regard to trailing slashes; but having said that, I take it you aren't interested in going with route options ...

using Microsoft.AspNetCore.Routing;

services.Configure<RouteOptions>(options =>
{
    options.AppendTrailingSlash = true;
});

-- OR --

services.AddRouting(options => {
    options.AppendTrailingSlash = true;
});

[EDIT] dotnet/aspnetcore#1459

@AR1ES
Copy link

AR1ES commented May 22, 2016

@guardrex These options are responsible only for the links on the site but not for real redirects. Of course I can write a few lines of code for this purpose. But I'm sure it's not the only problem, which is caused by the change of the app root folder. And I would like to use the standard IIS capabilities.

@guardrex
Copy link
Contributor

@AR1ES I haven't had to achieve the type of redirects that you're going for here ... I don't even understand what you're trying to achieve. My recommendation is to open an issue over in https://github.com/aspnet/IISIntegration/issues and hit up The Honorable Mr. Chris @Tratcher, Esq. 😎, who can provide more assistance than I on this one.

@muratg
Copy link
Contributor

muratg commented May 12, 2017

We are closing this issue because no further action is planned for this issue. If you still have any issues or questions, please log a new issue with any additional details that you have.

@muratg muratg closed this as completed May 12, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests