Hello!
I am Titouan Galopin
Symfony UX initiative lead
Selency // Citipo
2
Slide 3
Slide 3 text
Agenda
1. Know your content
2. Security concerns
3. Choosing an editor
4. The state of the art: block-based editors
5. Live editing with Symfony UX and Mercure
3
Slide 4
Slide 4 text
1
Know your content
4
Slide 5
Slide 5 text
Content editing isn’t a technical
challenge, it’s an architecture one
5
Slide 6
Slide 6 text
● Article comments
● Restaurant reviews
● Social post
● Document writing
● CMS
● …
Many use cases
6
Slide 7
Slide 7 text
⬡ Stylable content vs Plain text?
Should your users be able to insert bold/italic? Links?
Images? …
Questions to ask yourself
7
Slide 8
Slide 8 text
Questions to ask yourself
8
⬡ Stylable content vs Plain text?
⬡ Feature-rich content vs Markdown?
Markdown is great but it’s difficult to use for non-technical
users, and will it be enough?
Slide 9
Slide 9 text
Questions to ask yourself
9
⬡ Stylable content vs Plain text?
⬡ Feature-rich content vs Markdown?
⬡ Programmatic content manipulation?
Will you need to manipulate the content programmatically
(move elements, migrate to a new editor, upgrade your
current editor, …)? (Most likely yes)
Slide 10
Slide 10 text
Questions to ask yourself
10
⬡ Stylable content vs Plain text?
⬡ Feature-rich content vs Markdown?
⬡ Programmatic content manipulation?
⬡ Translation?
Automatic/manual content translation?
Slide 11
Slide 11 text
Questions to ask yourself
11
⬡ Stylable content vs Plain text?
⬡ Feature-rich content vs Markdown?
⬡ Programmatic content manipulation?
⬡ Translation?
⬡ Different display on mobile vs desktop?
Should some blocks have a different structure on mobile?
Slide 12
Slide 12 text
Questions to ask yourself
12
⬡ Stylable content vs Plain text?
⬡ Feature-rich content vs Markdown?
⬡ Programmatic content manipulation?
⬡ Translation?
⬡ Different display on mobile vs desktop?
⬡ Display in non-Web contexts (mobile/desktop app, …)?
Slide 13
Slide 13 text
Answers to these questions are
both technical and human
Content editors are one of the
most complex UX challenge
13
Slide 14
Slide 14 text
2
Security concerns
14
Slide 15
Slide 15 text
A content editor is a big
security risk
You must implement
dedicated security
15
Slide 16
Slide 16 text
Biggest risk:
Cross-site scripting
Inject JavaScript code into Web pages viewed by
other users to extract information (session cookie,
password, emails, …) from your users.
16
Slide 17
Slide 17 text
But also …
CSS display attack
Inject CSS into pages to render them unusable or log
the keystrokes of visitors.
17
Slide 18
Slide 18 text
But also …
Click-hijacking attack
Inject HTML/CSS into pages to change the target of
a legitimate link somewhere in the page (for instance
the login button) to a phishing page.
18
Slide 19
Slide 19 text
But also …
DDoS attacks
Libraries to sanitize user content are complex and
CPU-intensive (HTML parsing and manipulation). It’s
a great place to DDoS a platform.
19
Slide 20
Slide 20 text
20
Implementing
security
Slide 21
Slide 21 text
Simplest option
Twig escape filter (or htmlentities) if you don’t need
to accept HTML (plain text/markdown/…).
You should use this when you can.
21
Slide 22
Slide 22 text
HTML sanitizing
When you need to accept HTML (rich-content), you
need to distinguish safe from unsafe HTML.
This is what’s called HTML Sanitizing.
22
Slide 23
Slide 23 text
Symfony HtmlSanitizer
The HTML Sanitizer component aims at sanitizing
untrusted HTML code (e.g. created by a WYSIWYG
editor in the browser) into HTML that can be trusted.
23
Slide 24
Slide 24 text
HtmlSanitizer is useful to:
● Prevent security issues (XSS, CSRF, data
extraction, …)
● Prevent display problems (ensure content
consistency)
● Output valid, standard HTML from potentially
invalid WYSIWYG editor one
24
Slide 25
Slide 25 text
Usage
25
Slide 26
Slide 26 text
26
Slide 27
Slide 27 text
27
As a service
Slide 28
Slide 28 text
28
In a form
Slide 29
Slide 29 text
29
As a Twig filter
Slide 30
Slide 30 text
Configuration
30
Slide 31
Slide 31 text
31
Create a custom sanitizer
Slide 32
Slide 32 text
32
Configure
allowed
…
Slide 33
Slide 33 text
33
Configure
allowed
…
and
forbidden
elements
Slide 34
Slide 34 text
34
Configure
allowed links to
prevent phishing
and privacy
issues
Slide 35
Slide 35 text
35
Configure
allowed media to
prevent phishing
and privacy
issues
Slide 36
Slide 36 text
Tip: you should apply
sanitizing before storing
and before display
36
Slide 37
Slide 37 text
Before storing
To store safe HTML in the database
37
Slide 38
Slide 38 text
Before displaying
Because:
1. Content can be manipulated from outside your
application (manually, script missing the sanitizer, …)
2. Because some databases have unpredictable
behaviors
Ex: MySQL transforms UTF-8 character ⟨ to ASCII < when storing in a non-UTF8 field
38
Slide 39
Slide 39 text
3
Choosing an editor
39
Slide 40
Slide 40 text
The editor you choose should match
your technical and UX needs
40
Slide 41
Slide 41 text
41
Plain-text
Slide 42
Slide 42 text
Simplest option (textarea)
● Easy-to-use for everyone
● Can be enough, especially with modern emoji
support
● Very limited styling
42
Great for technical users
● Great UX for tech users (ex: Markdown + CodeMirror)
● Flexible without too much JavaScript complexity
● Not usable by non-tech users
● Requires HTML sanitization for security
45
UX-friendly for everyone
● Easy-to-use by anyone
● Requires a complex JavaScript library
● Requires HTML sanitization for security
● Difficult to manipulate the generated content
51
around tweets on display?
2. How can I upgrade my editor version without
breaking existing content?
3. How can I display content in a non-Web context?
4. How can I allow multiple people to edit
collaboratively?
56
Slide 57
Slide 57 text
HTML is not easy to manipulate
57
Slide 58
Slide 58 text
4
The state of the art:
block-based editors
58
Slide 59
Slide 59 text
The idea
Content is stored as JSON
blocks, containing HTML only
when necessary
59
Slide 60
Slide 60 text
The rendered HTML is only built
at display
60
Slide 61
Slide 61 text
By using JSON blocks:
● Easier to manipulate (“add a
around tweets”)
● Can display content outside the Web
● Ease content migration during upgrades
● Make live collaboration possible
61
Slide 62
Slide 62 text
Example:
Quill Rich Text Editor
62
Slide 63
Slide 63 text
63
Slide 64
Slide 64 text
Deltas
Deltas are an expressive format to
describe Quill’s contents and changes
64
Slide 65
Slide 65 text
65
Describes content…
Slide 66
Slide 66 text
66
…but also changes
Slide 67
Slide 67 text
Security
Blocks content should still be:
● Escaped (Twig/htmlentities) if they
won’t contain any HTML
● Sanitized if they will
67
Slide 68
Slide 68 text
Implementation
Very similar to CKEditor: Symfony UX to
instantiate, Symfony Form to extract the
data
68
Slide 69
Slide 69 text
Storage
Store the content as JSON in your
database: easy manipulation!
69
Slide 70
Slide 70 text
Display
Use Quill JS library to render blocks as
safe HTML … or implement your own logic
to display on other platforms!
70
Slide 71
Slide 71 text
Solutions
1. How can I add a
around tweets on display?
2. How can I upgrade my editor version without
breaking existing content?
3. How can I display content in a non-Web context?
=> Now very easy!
4. How can I allow multiple people to edit the same
content collaboratively?
…
71
Slide 72
Slide 72 text
5
Live editing with Symfony UX
and Mercure
72
Slide 73
Slide 73 text
Deltas allow us to live stream
changes across users!
73
Slide 74
Slide 74 text
74
Collaborative editor
Slide 75
Slide 75 text
75
Collaborative editor
This is a Delta
change: small,
easy bit to
synchronize the
editor state
between users
Slide 76
Slide 76 text
Conclusion
76
Slide 77
Slide 77 text
Conclusion
● For simple needs: plain text + escape is enough (a
content editor isn’t necessarily worth it)
77
Slide 78
Slide 78 text
Conclusion
● For simple needs: plain text + escape is enough (a
content editor isn’t necessarily worth it)
● For tech users: Markdown + HtmlSanitizer with a
code editor is great and flexible
78
Slide 79
Slide 79 text
Conclusion
● For simple needs: plain text + escape is enough (a
content editor isn’t necessarily worth it)
● For tech users: Markdown + HtmlSanitizer with a
code editor is great and flexible
● Otherwise: always choose a block-based editor
(much more flexible) and use sanitization
79
Slide 80
Slide 80 text
80
Thanks!
Any questions?
You can find me at:
@tgalopin
[email protected]
Slides design by SlidesCarnival