github.com/google/go-safeweb@v0.0.0-20231219055052-64d8cfc90fbb/safehttp/doc.go (about)

     1  // Copyright 2020 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //	https://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package safehttp provides a framework for building secure-by-default web
    16  // applications. See https://github.com/google/go-safeweb#readme to learn about
    17  // the goals and features.
    18  //
    19  // # Safe Responses
    20  //
    21  // HTTP responses need to be crafted carefully in order to prevent common web
    22  // vulnerabilities like Cross-site Scripting (XSS). To help with this, we use
    23  // Safe Responses.
    24  //
    25  // Safe Responses are HTTP responses which have been determined to be safe when
    26  // received by a modern, popular web browser. For example, we consider HTML
    27  // responses generated using a template system enforcing contextual autoescaping
    28  // to be safe, e.g. modern Angular or github.com/google/safehtml/template. Read
    29  // more about contextual autoescaping here:
    30  // https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/42934.pdf.
    31  //
    32  // The Go Safe Web ResponseWriter implementation only accepts Safe Responses
    33  // instead of byte slices.
    34  //
    35  // Since different projects will consider different ways of crafting a response
    36  // safe, we offer a way of configuring this in the framework. Whether a response
    37  // is considered safe or not is determined by the Dispatcher.
    38  //
    39  // # Dispatcher
    40  //
    41  // An implementation of a Dispatcher should be provided by security experts in
    42  // your project. The Dispatcher is called for every write method of the
    43  // ResponseWriter and is used to determine whether the passed response should be
    44  // considered safe. The Dispatcher is responsible for writing the response to
    45  // the underlying http.ResponseWriter in a safe way.
    46  //
    47  // Go Safe Web provides a DefaultDispatcher implementation which supports
    48  // github.com/google/safehtml responses.
    49  //
    50  // Warning: the security of the web application depends on a sound Dispatcher
    51  // implementation. Make sure it is security-reviewed and keep it simple.
    52  //
    53  // # Interceptors
    54  //
    55  // Not all security features can be implemented using the Dispatcher alone. For
    56  // instance, some requests should be rejected before they reach the handler in
    57  // order to prevent from Cross-site Request Forgery (CSRF, XSRF). To support
    58  // this, the framework uses Interceptors.
    59  //
    60  // An Interceptor implements methods that run before the request is passed to
    61  // the handler, and after the handler has committed a response. These are,
    62  // respectively, Before and Commit.
    63  //
    64  // # Life of a Request
    65  //
    66  // To tie it all together, we will explain how a single request goes through the
    67  // framework.
    68  //
    69  // When the request reaches the server, the following happens:
    70  //
    71  // 1. The ServeMux routes the request (i.e. picks the appropriate Handler that
    72  // will be eventually called). The HTTP method of the request is checked whether
    73  // it matches any registered Handler.
    74  //
    75  // 2. [Before phase] The request is passed to all installed Interceptors, via
    76  // their Before methods, in the order of installation on the ServeMux. Each of
    77  // the Before methods can either let the execution continue by returning
    78  // safehttp.NotWritten() (and not using any ResponseWriter write methods), or by
    79  // actually writing a response. This would prevent further Before method calls
    80  // of subsequent Interceptors.
    81  //
    82  // 3. The request is passed to the Handler. The Handler calls a write method of
    83  // the ResponseWriter (e.g. Write, WriteError, Redirect...).
    84  //
    85  // 5. [Commit phase] Commit methods of the installed Interceptors are called, in
    86  // LIFO order (i.e. first Interceptor to be called in Before phase is called
    87  // last in the Commit phase). Commit methods can no longer influence the flow of
    88  // the request, but can still set headers, cookies, response HTTP status code or
    89  // even modify the response (if its type allows it).
    90  //
    91  // 6. [Dispatcher] After all Commit methods have been called, the framework
    92  // passes the request to the Dispatcher. The Dispatcher determines the
    93  // Content-Type of the response and whether the response should be considered a
    94  // Safe Response. The Dispatcher is responsible for writing the response to the
    95  // underlying http.ResponseWriter in a safe way.
    96  //
    97  // 7. The Handler returns the value returned by the ResponseWriter write method
    98  // used. After the first write, any further writes are considered fatal errors.
    99  // It is safe to use defer statements for cleanup tasks (e.g. closing a file
   100  // that was used in a safehtml/template.Template response).
   101  //
   102  // Stack trace of the flow:
   103  //
   104  //	Mux.ServeHTTP()
   105  //	--+ Mux routes the request and checks the method.
   106  //	--+ InterceptorFoo.Before()
   107  //	--+ InterceptorBar.Before()
   108  //	--+ InterceptorBaz.Before()
   109  //	--+ Handler()
   110  //	----+ ResponseWriter.Write
   111  //	------+ InterceptorBaz.Commit()  // notice the inverted order
   112  //	------+ InterceptorBar.Commit()
   113  //	------+ InterceptorFoo.Commit()
   114  //	------+ Dispatcher.Write()
   115  //	----+ The result of the Response.Write() call is returned.
   116  //
   117  // # Error Responses
   118  //
   119  // Error responses are written using ResponseWriter.WriteError. They go through
   120  // the usual Commit and Dispatcher phases.
   121  //
   122  // # Configuring the Mux
   123  //
   124  // # TODO
   125  //
   126  // # Incremental Adoption
   127  //
   128  // In order to migrate your service using http.Handlers to the safehttp package,
   129  // we recommend you start doing that one endpoint at a time. Use
   130  // RegisteredHandler to do this.
   131  //
   132  //	safeMuxConfig := /* configured ServeMuxConfig, including interceptors */
   133  //	safeMuxConfig.Handle("/bar", safehttp.MethodGET, barGETSafeHandler)
   134  //	safeMuxConfig.Handle("/bar", safehttp.MethodPOST, barPOSTSafeHandler)
   135  //	safeMuxConfig.Handle("/xyz", safehttp.MethodPOST, xyzSafeHandler)
   136  //	safeMux := safeMuxConfig.Mux()
   137  //
   138  //	// old, not yet migrated
   139  //	http.Handle("/foo", fooHandler)
   140  //
   141  //	// new, migrated
   142  //	http.Handle("/bar", safehttp.RegisteredHandler(safeMux, "/bar"))
   143  //	http.Handle("/xyz", safehttp.RegisteredHandler(safeMux, "/xyz"))
   144  //
   145  // # Restricting Risky APIs
   146  //
   147  // Some APIs are easy-to-misuse in a security sensitive context. We choose to
   148  // restrict these and require a security review for their usage in order to
   149  // prevent vulnerabilities.
   150  //
   151  // cmd/bancheck allows you to restrict APIs and check for their usage as part
   152  // of the CI/CD pipeline and prevent potentially vulnerable code from being
   153  // deployed. For detailed usage instructions, please see:
   154  // https://pkg.go.dev/github.com/google/go-safeweb/cmd/bancheck
   155  package safehttp