Git Product home page Git Product logo

Comments (12)

kele avatar kele commented on April 28, 2024

Currently, the safehtml/template API supports parsing templates from TrustedSources. The fs.FS is an interface that can be arbitrarily implemented, therefore it cannot be trusted as is.

The way to go could be implementing it using embed.FS as the parameter instead.

from safehtml.

jba avatar jba commented on April 28, 2024

I actually need to use embed.FS in a project (golang/go#48410), so I'm willing to make this happen. Here are two designs. The first is minimal:

func ParseFS(fs embed.FS, patterns ...string) (*Template, error)
func (*Template) ParseFS(fs embed.FS, patterns ...string) (*Template, error)

That mimics the standard library changes, except for using embed.FS instead of fs.FS.

But I think it would be worth doing something more general, in anticipation of other trusted FSs. This would also let code be agnostic about where the FS came from, much like you can do with file paths now:

type TrustedFS
func TrustedFSFromConstant(stringConstant) TrustedFS
// perhaps TrustedFSFrom{Flag,EnvVar}, etc.
func TrustedFSFromEmbed(embed.FS) TrustedFS

func ParseFS(fs TrustedFS, patterns ...string) (*Template, error)
func (*Template) ParseFS(fs TrustedFS, patterns ...string) (*Template, error)

A third design would allow you to create a TrustedSource from an FS. I haven't thought through whether that can work—does every operation on a TrustedSource make sense with an FS as well as with a file path? For example, what would

func TrustedSourceFromConstantDir(dir stringConstant, src TrustedSource, filename string) (TrustedSource, error)

do if the middle argument was an FS? Although it seems more elegant to have a single concept, it may end up being more confusing.

from safehtml.

aantelov87 avatar aantelov87 commented on April 28, 2024

I do prefer the second design. In my opinion, it is the most clear and simple.

from safehtml.

jba avatar jba commented on April 28, 2024

I realized that if we add

func ToTrustedFS(TrustedSource) TrustedFS

then we don't need any TrustedFSFromXXX functions, so that makes it even simpler.

from safehtml.

kele avatar kele commented on April 28, 2024

I see the use case of embed.FS and having specialized functions to support this.

What is the use case of the other helpers, taking into account that we have ParseGlob?

from safehtml.

jba avatar jba commented on April 28, 2024

@kele, none right now that couldn't be done in other ways, but I see two reasons to generalize to TrustedFS now:

  1. It would allow for easier testing, because the same call to ParseFS could take an embed.FS in production code or ToTrustedFS(TrustedSourceFromConstant("testdir")) in test code.
  2. It would open the door to other FS implementations. For example, there's no reason to disallow parsing templates from a zip file under the programmer's control. If you wanted to support that you would just need to add a function to convert a zip.Reader (which implements fs.FS) to a TrustedFS.

I think the argument for TrustedFS is stronger than the one for ToTrustedFS (that is, converting an existing TrustedSource to a TrustedFS).

from safehtml.

kele avatar kele commented on April 28, 2024
  1. It would allow for easier testing, because the same call to ParseFS could take an embed.FS in production code or ToTrustedFS(TrustedSourceFromConstant("testdir")) in test code.

Shouldn't one swap out the whole Template instead of the filesystem?

  1. It would open the door to other FS implementations. For example, there's no reason to disallow parsing templates from a zip file under the programmer's control. If you wanted to support that you would just need to add a function to convert a zip.Reader (which implements fs.FS) to a TrustedFS.

How exactly would that work? Would we (a) keep adding more and more types to convert from to a TrustedFS, or (b) we'd allow users to somehow implement a TrustedFS themselves?

For (a): I assume we'd limit who could implement TrustedFS by e.g. adding a private method? If yes, I'd be okay with that from a security point of view, but I wonder whether we have enough cases to justify adding a layer of abstraction here.

For (b): How could we make sure we won't get unsafe TrustedFS implementations?

from safehtml.

jba avatar jba commented on April 28, 2024

@kele TrustedFS cannot be an interface, because that can't be done in a safe way. Even with a private method, clients could still embed the interface in their own structs. It would instead look like TrustedSource:

type TrustedFS struct {
    fsys fs.FS
}

from safehtml.

kele avatar kele commented on April 28, 2024

In this case, we will own all the constructors of TrustedFS and provide functions like FromEmbed(TrustedFS), FromConstantPath(stringConstant), FromZip(???), correct?

I struggle to see how we could provide any constructors other than from a string constant and an embed.FS. If these are the only two we can support, then I'm not sure it's worth it to introduce the a TrustedFS type, because this is one more thing that a developer needs to understand in order to use the API.

from safehtml.

jba avatar jba commented on April 28, 2024

Yes, you would own all the constructors.

I can't think of other constructors either at present. I see TrustedFS as future-proofing. If you don't think that's worth it, I'm fine with using an embed.FS directly.

from safehtml.

jba avatar jba commented on April 28, 2024

@kele, I pushed #8 but can't add reviewers. PTAL.

from safehtml.

aantelov87 avatar aantelov87 commented on April 28, 2024

Closing the issue. Feature implemented in commit d6f0e11.

from safehtml.

Related Issues (8)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.