jekyll-seo-tag 2.9.0 → 2.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae62628d6361490afa3b9bca552e3fc3c8201b112b8e1b30a14b84092b36c7c8
4
- data.tar.gz: 2c7f7ab30d0ba11907f8ae5280ac3c092156b77a5d3881f172eb867bf966fdd3
3
+ metadata.gz: dbad211fe69342707356ae1396328e40f6d0c14f0568500f1618fb1cea736435
4
+ data.tar.gz: 03a10838603f66d37891bb919d0a170b968de42553bee688721b4f6ad455800f
5
5
  SHA512:
6
- metadata.gz: 2e10720b542ef334d0041261ee0b993e0520011df7f4458e644fd076c4d3d11fb18d4af8cf501cfab88d23539e4047f81e63d62d19277689c7085fb1c02627f6
7
- data.tar.gz: 992867ebeb0d2120b942f0fe55d7e3478823fb103c09f31ec9088a0f39e77ace5de0b5901c54e03030695d71b8b4fbe4c270f65bc4493187e525d22aeb502a23
6
+ metadata.gz: f81c5cf300ff43b6a2cf93da21428cb6e5479b15d446abf6f4f5219cd1f9d728c191792a1329037bcaf619230c68c2a86a428880e376d3f56e396872db683eec
7
+ data.tar.gz: 052b68ba6509c071cf6280b92dde6c9a3c1709e6137a68ed89339db2420025c200a04ce156e389100cd93c5ccf1f1a1d38e23a857cb1283d3ce1d3b50cada47b
data/History.markdown CHANGED
@@ -1,3 +1,9 @@
1
+ ## 2.9.1 / 2026-09-29
2
+
3
+ ### Security
4
+
5
+ * Escape all metadata attribute outputs, and make the JSON-LD block safe inside its script tag (GHSA-572m-7cg5-6j5r)
6
+
1
7
  ## 2.9.0 / 2026-05-08
2
8
 
3
9
  ### Minor Enhancements
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ class SeoTag
5
+ # Liquid filters used by the SEO tag template
6
+ module JSONFilters
7
+ # Characters which could end a <script> element or start an HTML comment
8
+ # within it, plus the line terminators which are invalid in JavaScript
9
+ # strings. They can only appear inside JSON strings, where they are
10
+ # replaced by their equivalent \u escapes.
11
+ JSON_ESCAPE = {
12
+ "<" => "\\u003c",
13
+ ">" => "\\u003e",
14
+ "&" => "\\u0026",
15
+ "\u2028" => "\\u2028",
16
+ "\u2029" => "\\u2029",
17
+ }.freeze
18
+ JSON_ESCAPE_REGEX = Regexp.union(JSON_ESCAPE.keys).freeze
19
+
20
+ # Makes a JSON string safe to embed in an HTML <script> element
21
+ def seo_json_escape(input)
22
+ input.to_s.gsub(JSON_ESCAPE_REGEX, JSON_ESCAPE)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -5,6 +5,6 @@ module Liquid; class Tag; end; end
5
5
 
6
6
  module Jekyll
7
7
  class SeoTag < Liquid::Tag
8
- VERSION = "2.9.0"
8
+ VERSION = "2.9.1"
9
9
  end
10
10
  end
@@ -12,6 +12,7 @@ module Jekyll
12
12
  autoload :UrlHelper, "jekyll-seo-tag/url_helper"
13
13
  autoload :Drop, "jekyll-seo-tag/drop"
14
14
  autoload :Filters, "jekyll-seo-tag/filters"
15
+ autoload :JSONFilters, "jekyll-seo-tag/json_filters"
15
16
 
16
17
  attr_accessor :context
17
18
 
@@ -65,7 +66,7 @@ module Jekyll
65
66
  def info
66
67
  {
67
68
  :registers => context.registers,
68
- :filters => [Jekyll::Filters],
69
+ :filters => [Jekyll::Filters, JSONFilters],
69
70
  }
70
71
  end
71
72
 
data/lib/template.html CHANGED
@@ -6,39 +6,39 @@
6
6
  <meta name="generator" content="Jekyll v{{ jekyll.version }}" />
7
7
 
8
8
  {% if seo_tag.page_title %}
9
- <meta property="og:title" content="{{ seo_tag.page_title }}" />
9
+ <meta property="og:title" content="{{ seo_tag.page_title | escape_once }}" />
10
10
  {% endif %}
11
11
 
12
12
  {% if seo_tag.author.name %}
13
- <meta name="author" content="{{ seo_tag.author.name }}" />
13
+ <meta name="author" content="{{ seo_tag.author.name | escape_once }}" />
14
14
  {% endif %}
15
15
 
16
- <meta property="og:locale" content="{{ seo_tag.page_locale }}" />
16
+ <meta property="og:locale" content="{{ seo_tag.page_locale | escape_once }}" />
17
17
 
18
18
  {% if seo_tag.description %}
19
- <meta name="description" content="{{ seo_tag.description }}" />
20
- <meta name="twitter:description" property="og:description" content="{{ seo_tag.description }}" />
19
+ <meta name="description" content="{{ seo_tag.description | escape_once }}" />
20
+ <meta name="twitter:description" property="og:description" content="{{ seo_tag.description | escape_once }}" />
21
21
  {% endif %}
22
22
 
23
23
  {% if site.url %}
24
- {% if seo_tag.canonical? %}<link rel="canonical" href="{{ seo_tag.canonical_url }}" />
25
- {% endif %}<meta property="og:url" content="{{ seo_tag.canonical_url }}" />
24
+ {% if seo_tag.canonical? %}<link rel="canonical" href="{{ seo_tag.canonical_url | escape_once }}" />
25
+ {% endif %}<meta property="og:url" content="{{ seo_tag.canonical_url | escape_once }}" />
26
26
  {% endif %}
27
27
 
28
28
  {% if seo_tag.site_title %}
29
- <meta property="og:site_name" content="{{ seo_tag.site_title }}" />
29
+ <meta property="og:site_name" content="{{ seo_tag.site_title | escape_once }}" />
30
30
  {% endif %}
31
31
 
32
32
  {% if seo_tag.image %}
33
- <meta property="og:image" content="{{ seo_tag.image.path }}" />
33
+ <meta property="og:image" content="{{ seo_tag.image.path | escape_once }}" />
34
34
  {% if seo_tag.image.height %}
35
- <meta property="og:image:height" content="{{ seo_tag.image.height }}" />
35
+ <meta property="og:image:height" content="{{ seo_tag.image.height | escape_once }}" />
36
36
  {% endif %}
37
37
  {% if seo_tag.image.width %}
38
- <meta property="og:image:width" content="{{ seo_tag.image.width }}" />
38
+ <meta property="og:image:width" content="{{ seo_tag.image.width | escape_once }}" />
39
39
  {% endif %}
40
40
  {% if seo_tag.image.alt %}
41
- <meta property="og:image:alt" content="{{ seo_tag.image.alt }}" />
41
+ <meta property="og:image:alt" content="{{ seo_tag.image.alt | escape_once }}" />
42
42
  {% endif %}
43
43
  {% endif %}
44
44
 
@@ -53,79 +53,79 @@
53
53
  {% endif %}
54
54
 
55
55
  {% if paginator.previous_page %}
56
- <link rel="prev" href="{{ paginator.previous_page_path | absolute_url }}" />
56
+ <link rel="prev" href="{{ paginator.previous_page_path | absolute_url | escape_once }}" />
57
57
  {% endif %}
58
58
  {% if paginator.next_page %}
59
- <link rel="next" href="{{ paginator.next_page_path | absolute_url }}" />
59
+ <link rel="next" href="{{ paginator.next_page_path | absolute_url | escape_once }}" />
60
60
  {% endif %}
61
61
 
62
62
  {% if seo_tag.image %}
63
- <meta name="twitter:card" content="{{ page.twitter.card | default: site.twitter.card | default: "summary_large_image" }}" />
64
- <meta name="twitter:image" content="{{ seo_tag.image.path }}" />
63
+ <meta name="twitter:card" content="{{ page.twitter.card | default: site.twitter.card | default: "summary_large_image" | escape_once }}" />
64
+ <meta name="twitter:image" content="{{ seo_tag.image.path | escape_once }}" />
65
65
  {% else %}
66
66
  <meta name="twitter:card" content="summary" />
67
67
  {% endif %}
68
68
 
69
69
  {% if seo_tag.image.alt %}
70
- <meta name="twitter:image:alt" content="{{ seo_tag.image.alt }}" />
70
+ <meta name="twitter:image:alt" content="{{ seo_tag.image.alt | escape_once }}" />
71
71
  {% endif %}
72
72
 
73
73
  {% if seo_tag.page_title %}
74
- <meta name="twitter:title" content="{{ seo_tag.page_title }}" />
74
+ <meta name="twitter:title" content="{{ seo_tag.page_title | escape_once }}" />
75
75
  {% endif %}
76
76
 
77
77
  {% if site.twitter %}
78
- <meta name="twitter:site" content="@{{ site.twitter.username | remove:'@' }}" />
78
+ <meta name="twitter:site" content="@{{ site.twitter.username | remove:'@' | escape_once }}" />
79
79
 
80
80
  {% if seo_tag.author.twitter %}
81
- <meta name="twitter:creator" content="@{{ seo_tag.author.twitter | remove:'@' }}" />
81
+ <meta name="twitter:creator" content="@{{ seo_tag.author.twitter | remove:'@' | escape_once }}" />
82
82
  {% endif %}
83
83
  {% endif %}
84
84
 
85
85
  {% if site.facebook %}
86
86
  {% if site.facebook.admins %}
87
- <meta property="fb:admins" content="{{ site.facebook.admins }}" />
87
+ <meta property="fb:admins" content="{{ site.facebook.admins | escape_once }}" />
88
88
  {% endif %}
89
89
 
90
90
  {% if site.facebook.publisher %}
91
- <meta property="article:publisher" content="{{ site.facebook.publisher }}" />
91
+ <meta property="article:publisher" content="{{ site.facebook.publisher | escape_once }}" />
92
92
  {% endif %}
93
93
 
94
94
  {% if site.facebook.app_id %}
95
- <meta property="fb:app_id" content="{{ site.facebook.app_id }}" />
95
+ <meta property="fb:app_id" content="{{ site.facebook.app_id | escape_once }}" />
96
96
  {% endif %}
97
97
  {% endif %}
98
98
 
99
99
  {% if site.webmaster_verifications %}
100
100
  {% if site.webmaster_verifications.google %}
101
- <meta name="google-site-verification" content="{{ site.webmaster_verifications.google }}" />
101
+ <meta name="google-site-verification" content="{{ site.webmaster_verifications.google | escape_once }}" />
102
102
  {% endif %}
103
103
 
104
104
  {% if site.webmaster_verifications.bing %}
105
- <meta name="msvalidate.01" content="{{ site.webmaster_verifications.bing }}" />
105
+ <meta name="msvalidate.01" content="{{ site.webmaster_verifications.bing | escape_once }}" />
106
106
  {% endif %}
107
107
 
108
108
  {% if site.webmaster_verifications.alexa %}
109
- <meta name="alexaVerifyID" content="{{ site.webmaster_verifications.alexa }}" />
109
+ <meta name="alexaVerifyID" content="{{ site.webmaster_verifications.alexa | escape_once }}" />
110
110
  {% endif %}
111
111
 
112
112
  {% if site.webmaster_verifications.yandex %}
113
- <meta name="yandex-verification" content="{{ site.webmaster_verifications.yandex }}" />
113
+ <meta name="yandex-verification" content="{{ site.webmaster_verifications.yandex | escape_once }}" />
114
114
  {% endif %}
115
115
 
116
116
  {% if site.webmaster_verifications.baidu %}
117
- <meta name="baidu-site-verification" content="{{ site.webmaster_verifications.baidu }}" />
117
+ <meta name="baidu-site-verification" content="{{ site.webmaster_verifications.baidu | escape_once }}" />
118
118
  {% endif %}
119
119
 
120
120
  {% if site.webmaster_verifications.facebook %}
121
- <meta name="facebook-domain-verification" content="{{ site.webmaster_verifications.facebook }}" />
121
+ <meta name="facebook-domain-verification" content="{{ site.webmaster_verifications.facebook | escape_once }}" />
122
122
  {% endif %}
123
123
  {% elsif site.google_site_verification %}
124
- <meta name="google-site-verification" content="{{ site.google_site_verification }}" />
124
+ <meta name="google-site-verification" content="{{ site.google_site_verification | escape_once }}" />
125
125
  {% endif %}
126
126
 
127
127
  <script type="application/ld+json">
128
- {{ seo_tag.json_ld | jsonify }}
128
+ {{ seo_tag.json_ld | jsonify | seo_json_escape }}
129
129
  </script>
130
130
 
131
131
  <!-- End Jekyll SEO tag -->
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-seo-tag
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.0
4
+ version: 2.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Balter
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-08 00:00:00.000000000 Z
11
+ date: 2026-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -117,6 +117,7 @@ files:
117
117
  - lib/jekyll-seo-tag/drop.rb
118
118
  - lib/jekyll-seo-tag/filters.rb
119
119
  - lib/jekyll-seo-tag/image_drop.rb
120
+ - lib/jekyll-seo-tag/json_filters.rb
120
121
  - lib/jekyll-seo-tag/json_ld.rb
121
122
  - lib/jekyll-seo-tag/json_ld_drop.rb
122
123
  - lib/jekyll-seo-tag/url_helper.rb