-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Restore iframe support #784
Conversation
ee5da18
to
26d31aa
Compare
Bring back support for embedding Mattermost inside Microsoft Teams.
224fd21
to
f0fa078
Compare
f0fa078
to
ff03992
Compare
func (a *API) iFrame(w http.ResponseWriter, _ *http.Request) { | ||
config := a.p.API.GetConfig() | ||
siteURL := *config.ServiceSettings.SiteURL | ||
if siteURL == "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we don't have much control over this, but I believe we can at least verify that the URL is valid and since we set MMEMBED
to be Secure
, we can check that the scheme is https
.
Maybe something like:
parsedURL, err := url.Parse(siteURL)
if err != nil {
a.p.API.LogError("Invalid SiteURL for MS Teams iFrame", "error", err.Error())
http.Error(w, "Invalid SiteURL", http.StatusInternalServerError)
return
}
if parsedURL.Scheme != "https" {
a.p.API.LogError("SiteURL must use HTTPS for MS Teams iFrame", "scheme", parsedURL.Scheme)
http.Error(w, "SiteURL must use HTTPS", http.StatusInternalServerError)
return
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 for checking a valid SiteURL, but any objections on skipping the explicit SSL check? (I'll need to rewrite the testing framework to allow us to unit test this the way things are currently setup.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah okay that's fine
|
||
html := strings.ReplaceAll(iFrameHTML, "{{SITE_URL}}", siteURL) | ||
|
||
w.Header().Set("Content-Type", "text/html") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should set some additional security headers here but we will want to test how it behaves in Teams. After some back and forth with Aider, here is some sample code (NOTE: it uses parsedURL
from the validation code above):
// Get the origin (scheme + host) for CSP
origin := parsedURL.Scheme + "://" + parsedURL.Host
// Set a minimal CSP for the wrapper page
cspDirectives := []string{
"default-src 'none'", // Block all resources by default
"frame-src " + origin, // Only allow iframe to load content from Mattermost origin
"style-src 'unsafe-inline'", // Allow inline styles for the iframe positioning
}
w.Header().Set("Content-Security-Policy", strings.Join(cspDirectives, "; "))
// Set additional security headers w.Header().Set("X-Content-Type-Options", "nosniff")
w.Header().Set("X-Frame-Options", "SAMEORIGIN") // This is for the outer page, not the iframe content
w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to remove since it's covered in the CSP via frame-src (just repeating what I DMd you lol)
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0"> | ||
</head> | ||
<body> | ||
<iframe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I double checked that our content security policy allows us to be embedded in an iFrame within MS Teams (currently it has frame-ancestors 'self' teams.microsoft.com;
which is good - although we can probably have it be https://teams.microsoft.com
since I doubt Microsoft teams is ever over http
. That code lives in mattermost/server/channels/web/handlers.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I won't be able to fix this as part of this PR, but it's something we can patch the core app with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup just wanted to put that on your radar
Summary
Bring back the ability to embed Mattermost inside Microsoft Teams. For now, we're exposing just the endpoint to support embedding Mattermost as an iframe, and handling the manifest generation elsewhere.
Ticket Link
N/A