140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
352cc112dSEd Tanous #pragma once
452cc112dSEd Tanous
53ccb3adbSEd Tanous #include "http_response.hpp"
652cc112dSEd Tanous
7*d7857201SEd Tanous #include <boost/beast/http/field.hpp>
8*d7857201SEd Tanous
addSecurityHeaders(crow::Response & res)989cda63dSEd Tanous inline void addSecurityHeaders(crow::Response& res)
1052cc112dSEd Tanous {
1152cc112dSEd Tanous using bf = boost::beast::http::field;
1252cc112dSEd Tanous
131d9502bbSJoseph Reynolds // Recommendations from https://owasp.org/www-project-secure-headers/
141d9502bbSJoseph Reynolds // https://owasp.org/www-project-secure-headers/ci/headers_add.json
15d8139c68SEd Tanous res.addHeader(bf::strict_transport_security, "max-age=31536000; "
16d8139c68SEd Tanous "includeSubdomains");
17d8139c68SEd Tanous
18d8139c68SEd Tanous res.addHeader(bf::pragma, "no-cache");
19d8139c68SEd Tanous
20499b5b4dSEd Tanous if (res.getHeaderValue(bf::cache_control).empty())
21499b5b4dSEd Tanous {
22499b5b4dSEd Tanous res.addHeader(bf::cache_control, "no-store, max-age=0");
23499b5b4dSEd Tanous }
24d8139c68SEd Tanous res.addHeader("X-Content-Type-Options", "nosniff");
25d8139c68SEd Tanous
26c056aa7aSEd Tanous std::string_view contentType = res.getHeaderValue("Content-Type");
27c056aa7aSEd Tanous if (contentType.starts_with("text/html"))
28c056aa7aSEd Tanous {
29c056aa7aSEd Tanous res.addHeader(bf::x_frame_options, "DENY");
301d9502bbSJoseph Reynolds res.addHeader("Referrer-Policy", "no-referrer");
31bd79bce8SPatrick Williams res.addHeader(
32bd79bce8SPatrick Williams "Permissions-Policy",
33bd79bce8SPatrick Williams "accelerometer=(),"
341d9502bbSJoseph Reynolds "ambient-light-sensor=(),"
351d9502bbSJoseph Reynolds "autoplay=(),"
361d9502bbSJoseph Reynolds "battery=(),"
371d9502bbSJoseph Reynolds "camera=(),"
381d9502bbSJoseph Reynolds "display-capture=(),"
39d8139c68SEd Tanous "document-domain=(),"
401d9502bbSJoseph Reynolds "encrypted-media=(),"
411d9502bbSJoseph Reynolds "fullscreen=(),"
42d8139c68SEd Tanous "gamepad=(),"
431d9502bbSJoseph Reynolds "geolocation=(),"
441d9502bbSJoseph Reynolds "gyroscope=(),"
45d8139c68SEd Tanous "layout-animations=(self),"
46d8139c68SEd Tanous "legacy-image-formats=(self),"
471d9502bbSJoseph Reynolds "magnetometer=(),"
481d9502bbSJoseph Reynolds "microphone=(),"
491d9502bbSJoseph Reynolds "midi=(),"
50d8139c68SEd Tanous "oversized-images=(self),"
511d9502bbSJoseph Reynolds "payment=(),"
521d9502bbSJoseph Reynolds "picture-in-picture=(),"
531d9502bbSJoseph Reynolds "publickey-credentials-get=(),"
549bdc8b55SJoseph Reynolds "speaker-selection=(),"
55d8139c68SEd Tanous "sync-xhr=(self),"
56d8139c68SEd Tanous "unoptimized-images=(self),"
57d8139c68SEd Tanous "unsized-media=(self),"
58d8139c68SEd Tanous "usb=(),"
59d8139c68SEd Tanous "screen-wak-lock=(),"
601d9502bbSJoseph Reynolds "web-share=(),"
61d8139c68SEd Tanous "xr-spatial-tracking=()");
62d8139c68SEd Tanous res.addHeader("X-Permitted-Cross-Domain-Policies", "none");
63d8139c68SEd Tanous res.addHeader("Cross-Origin-Embedder-Policy", "require-corp");
64d8139c68SEd Tanous res.addHeader("Cross-Origin-Opener-Policy", "same-origin");
65d8139c68SEd Tanous res.addHeader("Cross-Origin-Resource-Policy", "same-origin");
66bd79bce8SPatrick Williams res.addHeader("Content-Security-Policy",
67bd79bce8SPatrick Williams "default-src 'none'; "
6852cc112dSEd Tanous "img-src 'self' data:; "
6952cc112dSEd Tanous "font-src 'self'; "
7052cc112dSEd Tanous "style-src 'self'; "
7152cc112dSEd Tanous "script-src 'self'; "
7209e7afdcSBasheer Ahmed Muddebihal "connect-src 'self' wss:; "
7309e7afdcSBasheer Ahmed Muddebihal "form-action 'none'; "
7409e7afdcSBasheer Ahmed Muddebihal "frame-ancestors 'none'; "
7591ac2e57SJiaqing Zhao "object-src 'none'; "
7609e7afdcSBasheer Ahmed Muddebihal "base-uri 'none' ");
7752cc112dSEd Tanous // The KVM currently needs to load images from base64 encoded
7852cc112dSEd Tanous // strings. img-src 'self' data: is used to allow that.
7909e7afdcSBasheer Ahmed Muddebihal // https://stackoverflow.com/questions/18447970/content-security-polic
8009e7afdcSBasheer Ahmed Muddebihal // y-data-not-working-for-base64-images-in-chrome-28
810260d9d6SEd Tanous }
82c056aa7aSEd Tanous }
83