mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-06-06 07:37:21 +02:00

- Merged #202 and optimized UI elements - Added HSTS headers toggle - Added permission policy injector in dynamicproxy - Fixed slow search LAN ip detection - Optimized UI for HTTP reverse proxy rules - Added wip permission policy and load balancer
198 lines
8.6 KiB
Go
198 lines
8.6 KiB
Go
package permissionpolicy
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
/*
|
|
Permisson Policy
|
|
|
|
This is a permission policy header modifier that changes
|
|
the request permission related policy fields
|
|
|
|
author: tobychui
|
|
*/
|
|
|
|
type PermissionsPolicy struct {
|
|
Accelerometer []string `json:"accelerometer"`
|
|
AmbientLightSensor []string `json:"ambient_light_sensor"`
|
|
Autoplay []string `json:"autoplay"`
|
|
Battery []string `json:"battery"`
|
|
Camera []string `json:"camera"`
|
|
CrossOriginIsolated []string `json:"cross_origin_isolated"`
|
|
DisplayCapture []string `json:"display_capture"`
|
|
DocumentDomain []string `json:"document_domain"`
|
|
EncryptedMedia []string `json:"encrypted_media"`
|
|
ExecutionWhileNotRendered []string `json:"execution_while_not_rendered"`
|
|
ExecutionWhileOutOfView []string `json:"execution_while_out_of_viewport"`
|
|
Fullscreen []string `json:"fullscreen"`
|
|
Geolocation []string `json:"geolocation"`
|
|
Gyroscope []string `json:"gyroscope"`
|
|
KeyboardMap []string `json:"keyboard_map"`
|
|
Magnetometer []string `json:"magnetometer"`
|
|
Microphone []string `json:"microphone"`
|
|
Midi []string `json:"midi"`
|
|
NavigationOverride []string `json:"navigation_override"`
|
|
Payment []string `json:"payment"`
|
|
PictureInPicture []string `json:"picture_in_picture"`
|
|
PublicKeyCredentialsGet []string `json:"publickey_credentials_get"`
|
|
ScreenWakeLock []string `json:"screen_wake_lock"`
|
|
SyncXHR []string `json:"sync_xhr"`
|
|
USB []string `json:"usb"`
|
|
WebShare []string `json:"web_share"`
|
|
XRSpatialTracking []string `json:"xr_spatial_tracking"`
|
|
ClipboardRead []string `json:"clipboard_read"`
|
|
ClipboardWrite []string `json:"clipboard_write"`
|
|
Gamepad []string `json:"gamepad"`
|
|
SpeakerSelection []string `json:"speaker_selection"`
|
|
ConversionMeasurement []string `json:"conversion_measurement"`
|
|
FocusWithoutUserActivation []string `json:"focus_without_user_activation"`
|
|
HID []string `json:"hid"`
|
|
IdleDetection []string `json:"idle_detection"`
|
|
InterestCohort []string `json:"interest_cohort"`
|
|
Serial []string `json:"serial"`
|
|
SyncScript []string `json:"sync_script"`
|
|
TrustTokenRedemption []string `json:"trust_token_redemption"`
|
|
Unload []string `json:"unload"`
|
|
WindowPlacement []string `json:"window_placement"`
|
|
VerticalScroll []string `json:"vertical_scroll"`
|
|
}
|
|
|
|
// GetDefaultPermissionPolicy returns a PermissionsPolicy struct with all policies set to *
|
|
func GetDefaultPermissionPolicy() *PermissionsPolicy {
|
|
return &PermissionsPolicy{
|
|
Accelerometer: []string{"*"},
|
|
AmbientLightSensor: []string{"*"},
|
|
Autoplay: []string{"*"},
|
|
Battery: []string{"*"},
|
|
Camera: []string{"*"},
|
|
CrossOriginIsolated: []string{"*"},
|
|
DisplayCapture: []string{"*"},
|
|
DocumentDomain: []string{"*"},
|
|
EncryptedMedia: []string{"*"},
|
|
ExecutionWhileNotRendered: []string{"*"},
|
|
ExecutionWhileOutOfView: []string{"*"},
|
|
Fullscreen: []string{"*"},
|
|
Geolocation: []string{"*"},
|
|
Gyroscope: []string{"*"},
|
|
KeyboardMap: []string{"*"},
|
|
Magnetometer: []string{"*"},
|
|
Microphone: []string{"*"},
|
|
Midi: []string{"*"},
|
|
NavigationOverride: []string{"*"},
|
|
Payment: []string{"*"},
|
|
PictureInPicture: []string{"*"},
|
|
PublicKeyCredentialsGet: []string{"*"},
|
|
ScreenWakeLock: []string{"*"},
|
|
SyncXHR: []string{"*"},
|
|
USB: []string{"*"},
|
|
WebShare: []string{"*"},
|
|
XRSpatialTracking: []string{"*"},
|
|
ClipboardRead: []string{"*"},
|
|
ClipboardWrite: []string{"*"},
|
|
Gamepad: []string{"*"},
|
|
SpeakerSelection: []string{"*"},
|
|
ConversionMeasurement: []string{"*"},
|
|
FocusWithoutUserActivation: []string{"*"},
|
|
HID: []string{"*"},
|
|
IdleDetection: []string{"*"},
|
|
InterestCohort: []string{"*"},
|
|
Serial: []string{"*"},
|
|
SyncScript: []string{"*"},
|
|
TrustTokenRedemption: []string{"*"},
|
|
Unload: []string{"*"},
|
|
WindowPlacement: []string{"*"},
|
|
VerticalScroll: []string{"*"},
|
|
}
|
|
}
|
|
|
|
// ToKeyValueHeader convert a permission policy struct into a key value string header
|
|
func (policy *PermissionsPolicy) ToKeyValueHeader() []string {
|
|
policyHeader := []string{}
|
|
|
|
// Helper function to add policy directives
|
|
addDirective := func(name string, sources []string) {
|
|
if len(sources) > 0 {
|
|
if sources[0] == "*" {
|
|
//Allow all
|
|
policyHeader = append(policyHeader, fmt.Sprintf("%s=%s", name, "*"))
|
|
} else {
|
|
//Other than "self" which do not need double quote, others domain need double quote in place
|
|
formatedSources := []string{}
|
|
for _, source := range sources {
|
|
if source == "self" {
|
|
formatedSources = append(formatedSources, "self")
|
|
} else {
|
|
formatedSources = append(formatedSources, "\""+source+"\"")
|
|
}
|
|
}
|
|
policyHeader = append(policyHeader, fmt.Sprintf("%s=(%s)", name, strings.Join(formatedSources, " ")))
|
|
}
|
|
} else {
|
|
//There are no setting for this field. Assume no permission
|
|
policyHeader = append(policyHeader, fmt.Sprintf("%s=()", name))
|
|
}
|
|
}
|
|
|
|
// Add each policy directive to the header
|
|
addDirective("accelerometer", policy.Accelerometer)
|
|
addDirective("ambient-light-sensor", policy.AmbientLightSensor)
|
|
addDirective("autoplay", policy.Autoplay)
|
|
addDirective("battery", policy.Battery)
|
|
addDirective("camera", policy.Camera)
|
|
addDirective("cross-origin-isolated", policy.CrossOriginIsolated)
|
|
addDirective("display-capture", policy.DisplayCapture)
|
|
addDirective("document-domain", policy.DocumentDomain)
|
|
addDirective("encrypted-media", policy.EncryptedMedia)
|
|
addDirective("execution-while-not-rendered", policy.ExecutionWhileNotRendered)
|
|
addDirective("execution-while-out-of-viewport", policy.ExecutionWhileOutOfView)
|
|
addDirective("fullscreen", policy.Fullscreen)
|
|
addDirective("geolocation", policy.Geolocation)
|
|
addDirective("gyroscope", policy.Gyroscope)
|
|
addDirective("keyboard-map", policy.KeyboardMap)
|
|
addDirective("magnetometer", policy.Magnetometer)
|
|
addDirective("microphone", policy.Microphone)
|
|
addDirective("midi", policy.Midi)
|
|
addDirective("navigation-override", policy.NavigationOverride)
|
|
addDirective("payment", policy.Payment)
|
|
addDirective("picture-in-picture", policy.PictureInPicture)
|
|
addDirective("publickey-credentials-get", policy.PublicKeyCredentialsGet)
|
|
addDirective("screen-wake-lock", policy.ScreenWakeLock)
|
|
addDirective("sync-xhr", policy.SyncXHR)
|
|
addDirective("usb", policy.USB)
|
|
addDirective("web-share", policy.WebShare)
|
|
addDirective("xr-spatial-tracking", policy.XRSpatialTracking)
|
|
addDirective("clipboard-read", policy.ClipboardRead)
|
|
addDirective("clipboard-write", policy.ClipboardWrite)
|
|
addDirective("gamepad", policy.Gamepad)
|
|
addDirective("speaker-selection", policy.SpeakerSelection)
|
|
addDirective("conversion-measurement", policy.ConversionMeasurement)
|
|
addDirective("focus-without-user-activation", policy.FocusWithoutUserActivation)
|
|
addDirective("hid", policy.HID)
|
|
addDirective("idle-detection", policy.IdleDetection)
|
|
addDirective("interest-cohort", policy.InterestCohort)
|
|
addDirective("serial", policy.Serial)
|
|
addDirective("sync-script", policy.SyncScript)
|
|
addDirective("trust-token-redemption", policy.TrustTokenRedemption)
|
|
addDirective("unload", policy.Unload)
|
|
addDirective("window-placement", policy.WindowPlacement)
|
|
addDirective("vertical-scroll", policy.VerticalScroll)
|
|
|
|
// Join the directives and set the header
|
|
policyHeaderValue := strings.Join(policyHeader, ", ")
|
|
return []string{"Permissions-Policy", policyHeaderValue}
|
|
}
|
|
|
|
// InjectPermissionPolicyHeader inject the permission policy into headers
|
|
func InjectPermissionPolicyHeader(w http.ResponseWriter, policy *PermissionsPolicy) {
|
|
//Keep the original Permission Policy if exists, or there are no policy given
|
|
if policy == nil || w.Header().Get("Permissions-Policy") != "" {
|
|
return
|
|
}
|
|
headerKV := policy.ToKeyValueHeader()
|
|
//Inject the new policy into the header
|
|
w.Header().Set(headerKV[0], headerKV[1])
|
|
}
|