Skip to content

Commit

Permalink
Attempt to sanitize rendered SVGs (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
felixvanoost authored Oct 23, 2023
1 parent b846f88 commit ede514c
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 6 deletions.
2 changes: 2 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ Style/StringLiteralsInInterpolation:

Layout/LineLength:
Max: 120
Metrics/MethodLength:
Max: 12
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
jekyll-kroki (0.1.0)
jekyll-kroki (0.2.0)
faraday (~> 2.7)
faraday-retry (~> 2.2)
jekyll (~> 4)
Expand Down Expand Up @@ -64,7 +64,7 @@ GEM
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.4.0)
minitest (5.14.2)
minitest (5.20.0)
nokogiri (1.15.4-x86_64-linux)
racc (~> 1.4)
parallel (1.23.0)
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ jekyll-kroki:
This is useful if you want to run a Kroki instance locally or your organisation maintains its own private Kroki server. `jekyll-kroki` will use the public Kroki instance https://kroki.io by default if a URL is not specified.

### Security

Embedding diagrams as SVGs directly within HTML files can be dangerous. You should only use a Kroki instance that you trust (or run your own!). For additional security, you can configure a [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) using custom Webrick headers in the Jekyll `_config.yml` file:

```yaml
webrick:
headers:
Content-Security-Policy: "Add a policy here"
```

## Contributing

Bug reports and pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
23 changes: 20 additions & 3 deletions lib/jekyll/kroki.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,29 @@ def embed_page(connection, parsed_doc)
# @return [String] The rendered diagram in SVG format
def render_diagram(connection, diagram_desc, language)
begin
encoded_diagram = encode_diagram(diagram_desc.text)
response = connection.get("#{language}/svg/#{encoded_diagram}")
response = connection.get("#{language}/svg/#{encode_diagram(diagram_desc.text)}")
rescue Faraday::Error => e
raise e.response[:body]
end
response.body
expected_content_type = "image/svg+xml"
returned_content_type = response.headers[:content_type]
if returned_content_type != expected_content_type
raise "Kroki returned an incorrect content type: " \
"expected '#{expected_content_type}', received '#{returned_content_type}'"

end
sanitise_diagram(response.body)
end

# Sanitises a rendered diagram. Only <script> elements are removed, which is the most minimal / naive
# implementation possible and is definitely not secure.
#
# @param [String] The diagram to santise in SVG format
# @return [String] The sanitized diagram in SVG format
def sanitise_diagram(diagram_svg)
parsed_svg = Nokogiri::XML(diagram_svg)
parsed_svg.xpath('//*[name()="script"]').each(&:remove)
parsed_svg.to_xml
end

# Encodes the diagram into Kroki format using deflate + base64.
Expand Down
2 changes: 1 addition & 1 deletion lib/jekyll/kroki/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

module Jekyll
class Kroki
VERSION = "0.1.0"
VERSION = "0.2.0"
end
end

0 comments on commit ede514c

Please sign in to comment.