diff --git a/docs/src/content/docs/guides/raw-messages.mdx b/docs/src/content/docs/guides/raw-messages.mdx index 1bfecfd6e..22d3d3edd 100644 --- a/docs/src/content/docs/guides/raw-messages.mdx +++ b/docs/src/content/docs/guides/raw-messages.mdx @@ -38,8 +38,8 @@ func main() { Assets: application.AssetOptions{ Handler: application.BundledAssetFileServer(assets), }, - RawMessageHandler: func(window application.Window, message string) { - fmt.Printf("Raw message from window '%s': %s\n", window.Name(), message) + RawMessageHandler: func(window application.Window, message string, originInfo *application.OriginInfo) { + fmt.Printf("Raw message from window '%s': %s (origin: %+v)\n", window.Name(), message, originInfo.Origin) // Process the message and respond via events response := processMessage(message) @@ -67,13 +67,53 @@ func processMessage(message string) map[string]any { ### Handler Signature ```go -RawMessageHandler func(window Window, message string) +RawMessageHandler func(window Window, message string, originInfo *application.OriginInfo) ``` | Parameter | Type | Description | |-----------|------|-------------| | `window` | `Window` | The window that sent the message | | `message` | `string` | The raw message content | +| `originInfo` | `*application.OriginInfo` | Origin information about the message source | + +#### OriginInfo Structure + +```go +type OriginInfo struct { + Origin string + TopOrigin string + IsMainFrame bool +} +``` + +| Field | Type | Description | +|-------|------|-------------| +| `Origin` | `string` | The origin URL of the document that sent the message | +| `TopOrigin` | `string` | The top-level origin URL (may differ from Origin in iframes) | +| `IsMainFrame` | `bool` | Whether the message originated from the main frame | + +#### Platform-Specific Availability + +- **macOS**: `Origin` and `IsMainFrame` are provided +- **Windows**: `Origin` and `TopOrigin` are provided +- **Linux**: Only `Origin` is provided + +### Origin Validation + + + +**Always verify the origin of incoming messages before processing them.** The `originInfo` parameter provides critical security information that must be validated to prevent unauthorized access. +Malicious content, compromised content, or unintended scripts could send raw messages. Without origin validation, you may process commands from untrusted sources. Use `originInfo` to ensure messages come from expected sources. + +### Key Validation Points + +- **Always check `Origin`** - Verify the origin matches your expected trusted sources (typically `wails://wails` or `http://wails.localhost` for local assets or your app's specific origin) +- **Validate `IsMainFrame`** (macOS) - Be aware if the message comes from an iframe, as this may indicate embedded content with different security contexts +- **Use `TopOrigin`** (Windows) - Verify the top-level origin when dealing with framed content +- **Reject unexpected origins** - Fail securely by rejecting messages from origins you don't explicitly allow + :::note Messages prefixed with `wails:` are reserved for internal Wails communication and will not be passed to your handler. @@ -147,7 +187,7 @@ System.invoke(JSON.stringify(command)) ### Backend ```go -RawMessageHandler: func(window application.Window, message string) { +RawMessageHandler: func(window application.Window, message string, originInfo *application.OriginInfo) { var cmd struct { Action string `json:"action"` Payload struct { @@ -185,7 +225,7 @@ Raw messages can process significantly more messages per second compared to serv ```go // Raw message handler - minimal overhead -RawMessageHandler: func(window application.Window, message string) { +RawMessageHandler: func(window application.Window, message string, originInfo *application.OriginInfo) { // Direct string processing, no reflection or marshaling counter++ } @@ -226,7 +266,7 @@ func main() { Mac: application.MacOptions{ ApplicationShouldTerminateAfterLastWindowClosed: true, }, - RawMessageHandler: func(window application.Window, message string) { + RawMessageHandler: func(window application.Window, message string, originInfo *application.OriginInfo) { var cmd Command if err := json.Unmarshal([]byte(message), &cmd); err != nil { window.EmitEvent("error", map[string]string{"error": err.Error()}) @@ -337,7 +377,7 @@ The `window` parameter identifies which window sent the message, allowing you to - Track message sources for debugging ```go -RawMessageHandler: func(window application.Window, message string) { +RawMessageHandler: func(window application.Window, message string, originInfo *application.OriginInfo) { // Respond only to the sending window window.EmitEvent("response", result)