erb_safe_ext 1.0.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9640d5151b33178ab899dc49ead4fcaa156c873d
4
- data.tar.gz: 9526e84f5cb6bc45b697d37304b82f069c5d2003
3
+ metadata.gz: cbac85e6c4525ea6453f8c540faec4c117a0e9a5
4
+ data.tar.gz: 091cbfca9bcac393e36d3f7d2fb13f3f173f5635
5
5
  SHA512:
6
- metadata.gz: ae4dac2679ad428b821d2960d39e4a6fa8e045335ff4c2e8573e2a96b5bf8948f24134a0c6eb2744c2b60d8ed0ce18d852fc50cf1ab3715d085494cd7eff922a
7
- data.tar.gz: 0b9d7e9198b49e3c0837e970155bee80ad397c0427c296fef183f1d5d57acd1e671f3ff2cf2d340d6ce852b5578b3848cd5882876a8ff0ec9b07f9055cf8d188
6
+ metadata.gz: daf0a0c99d16be082a70f8a0830cb4eb1df13b9408a6bef6f6bf07f68084914c772375f1ae5b7989f95bdca0d68ff4bf41c7d7efa9efd76ec474425423645e8c
7
+ data.tar.gz: 533d66182bef84054e88cb8398721aafb8efa2a4f89d87759b94984f2245ac4848cf697321fe6d2df977f0820eec63361e2d52735c91043850bff5ccfa9ae004
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # erb_safe_ext
2
2
 
3
- a gem make ERB html safe default.Protect from XSS attack.
3
+ add method to erb. Protect from XSS attack.
4
+
5
+ I think change the origin `<%=` method is not always good. maybe add a `<%~` method is better.
4
6
 
5
7
  ## Install
6
8
 
@@ -10,6 +12,33 @@ $ gem install erb_safe_ext
10
12
 
11
13
  ## Introduction
12
14
 
15
+ ``` erb
16
+ <%~ "<script>alert('safety:)');</script>" %>
17
+ ## &lt;script&gt;alert(&#39;safety:)&#39;);&lt;/script&gt;
18
+ ```
19
+
20
+ ``` erb
21
+ <%= "<script>alert('danger!');</script>" %>
22
+ ## <script>alert('danger!');</script>
23
+ ```
24
+
25
+
26
+ ## Test code
27
+
28
+ ``` ruby
29
+ require 'erb_safe_ext'
30
+ template = ERB.new <<-EOF
31
+ <%~ "<script>alert('safety:)');</script>" %>
32
+ <%= "<script>alert('danger!');</script>" %>
33
+ ----finish----
34
+ EOF
35
+ puts template.result
36
+ ```
37
+
38
+ # readme about version <= 1.0.4
39
+
40
+ ## Introduction
41
+
13
42
  ``` erb
14
43
  <%= "<script>alert('safety:)');</script>" %>
15
44
  ## &lt;script&gt;alert(&#39;safety:)&#39;);&lt;/script&gt;
@@ -19,8 +48,6 @@ it will default wrap the dangerous code with `ERB::Util.html_escape(code)`
19
48
 
20
49
  works fine with ruby2.0.
21
50
 
22
- I didn't test this code with other version ruby, you may test yourself.
23
-
24
51
  the `<%==` is the backup of ERB's original `<%=` function.
25
52
 
26
53
  ``` erb
@@ -28,7 +55,6 @@ the `<%==` is the backup of ERB's original `<%=` function.
28
55
  ## <script>alert('danger!');</script>
29
56
  ```
30
57
 
31
-
32
58
  ## Test code
33
59
 
34
60
  ``` ruby
@@ -45,28 +71,16 @@ puts template.result
45
71
  ## About Sinatra
46
72
  work fine with sinatra(current version is 1.4.4).
47
73
 
48
- but you should know that sinatra use [tilt](http://rubygems.org/gems/tilt) to render template.
49
-
50
- and sinatra also got Runtime Dependencies with `tilt >= 1.3.4, ~> 1.3`, that will do something make this gem lose effectiveness when you got `erubis` in your environment.
51
-
52
- So don't do following things:
74
+ but don't do following things:
53
75
 
54
76
  1. `require 'erubis'`
55
77
 
56
78
  2. add gems that dependent on erubis, such as `better_errors` (you may find out all dependences in file `Gemfile.lock`)
57
79
 
58
-
59
80
  ### Sinatra exception template
60
81
  the original sinatra exception template display ugly with erb_safe_ext, so I rewrite it.
61
82
 
62
83
  ``` ruby
63
84
  require 'sinatra/base'
64
85
  require 'erb_safe_ext/sinatra/exception_template'
65
- ```
66
-
67
-
68
- yeah.happy coding:)
69
-
70
-
71
-
72
-
86
+ ```
@@ -5,16 +5,15 @@ require 'sinarey_cache/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "erb_safe_ext"
8
- spec.version = "1.0.4"
8
+ spec.version = "2.0.0"
9
9
  spec.authors = ["Jeffrey"]
10
10
  spec.email = ["jeffrey6052@163.com"]
11
- spec.description = "make ERB default html safe.protect from XSS attack."
11
+ spec.description = "add method to erb, protect from XSS attack."
12
12
  spec.summary = "wrap the dangerous code with ERB::Util.html_escape()"
13
13
  spec.homepage = "https://github.com/Jeffrey6052/erb_safe_ext"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = ['lib/erb_safe_ext.rb',
17
- 'lib/erb_safe_ext/sinatra/exception_template.rb',
18
17
  'test/erb_safe_test.rb',
19
18
  'erb_safe_ext.gemspec',
20
19
  'README.md']
@@ -22,7 +22,7 @@ class ERB
22
22
  out.cr
23
23
  when :cr
24
24
  out.cr
25
- when '<%', '<%==', '<%=', '<%#'
25
+ when '<%', '<%~', '<%=', '<%#'
26
26
  scanner.stag = token
27
27
  add_put_cmd(out, content) if content.size > 0
28
28
  content = ''
@@ -47,9 +47,9 @@ class ERB
47
47
  else
48
48
  out.push(content)
49
49
  end
50
- when '<%=='
51
- add_insert_cmd(out, content)
52
50
  when '<%='
51
+ add_insert_cmd(out, content)
52
+ when '<%~'
53
53
  add_insert_escapehtml_cmd(out, content)
54
54
  when '<%#'
55
55
  # out.push("# #{content_dump(content)}")
@@ -72,7 +72,7 @@ class ERB
72
72
  end
73
73
  class TrimScanner < Scanner
74
74
  def scan_line(line)
75
- line.scan(/(.*?)(<%%|%%>|<%==|<%=|<%#|<%|%>|\n|\z)/m) do |tokens|
75
+ line.scan(/(.*?)(<%%|%%>|<%~|<%=|<%#|<%|%>|\n|\z)/m) do |tokens|
76
76
  tokens.each do |token|
77
77
  next if token.empty?
78
78
  yield(token)
@@ -80,7 +80,7 @@ class ERB
80
80
  end
81
81
  end
82
82
  def trim_line1(line)
83
- line.scan(/(.*?)(<%%|%%>|<%==|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
83
+ line.scan(/(.*?)(<%%|%%>|<%~|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
84
84
  tokens.each do |token|
85
85
  next if token.empty?
86
86
  if token == "%>\n"
@@ -94,7 +94,7 @@ class ERB
94
94
  end
95
95
  def trim_line2(line)
96
96
  head = nil
97
- line.scan(/(.*?)(<%%|%%>|<%==|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
97
+ line.scan(/(.*?)(<%%|%%>|<%~|<%=|<%#|<%|%>\n|%>|\n|\z)/m) do |tokens|
98
98
  tokens.each do |token|
99
99
  next if token.empty?
100
100
  head = token unless head
@@ -114,7 +114,7 @@ class ERB
114
114
  end
115
115
  end
116
116
  def explicit_trim_line(line)
117
- line.scan(/(.*?)(^[ \t]*<%\-|<%\-|<%%|%%>|<%==|<%=|<%#|<%|-%>\n|-%>|%>|\z)/m) do |tokens|
117
+ line.scan(/(.*?)(^[ \t]*<%\-|<%\-|<%%|%%>|<%~|<%=|<%#|<%|-%>\n|-%>|%>|\z)/m) do |tokens|
118
118
  tokens.each do |token|
119
119
  next if token.empty?
120
120
  if @stag.nil? && /[ \t]*<%-/ =~ token
@@ -130,7 +130,7 @@ class ERB
130
130
  end
131
131
  end
132
132
  end
133
- ERB_STAG << '<%=='
133
+ ERB_STAG << '<%~'
134
134
  def is_erb_stag?(s)
135
135
  ERB_STAG.member?(s)
136
136
  end
@@ -138,7 +138,7 @@ class ERB
138
138
  Scanner.default_scanner = TrimScanner
139
139
  class SimpleScanner < Scanner # :nodoc:
140
140
  def scan
141
- @src.scan(/(.*?)(<%%|%%>|<%==|<%=|<%#|<%|%>|\n|\z)/m) do |tokens|
141
+ @src.scan(/(.*?)(<%%|%%>|<%~|<%=|<%#|<%|%>|\n|\z)/m) do |tokens|
142
142
  tokens.each do |token|
143
143
  next if token.empty?
144
144
  yield(token)
@@ -151,7 +151,7 @@ class ERB
151
151
  require 'strscan'
152
152
  class SimpleScanner2 < Scanner # :nodoc:
153
153
  def scan
154
- stag_reg = /(.*?)(<%%|<%==|<%=|<%#|<%|\z)/m
154
+ stag_reg = /(.*?)(<%%|<%~|<%=|<%#|<%|\z)/m
155
155
  etag_reg = /(.*?)(%%>|%>|\z)/m
156
156
  scanner = StringScanner.new(@src)
157
157
  while ! scanner.eos?
@@ -164,7 +164,7 @@ class ERB
164
164
  Scanner.regist_scanner(SimpleScanner2, nil, false)
165
165
  class ExplicitScanner < Scanner # :nodoc:
166
166
  def scan
167
- stag_reg = /(.*?)(^[ \t]*<%-|<%%|<%==|<%=|<%#|<%-|<%|\z)/m
167
+ stag_reg = /(.*?)(^[ \t]*<%-|<%%|<%~|<%=|<%#|<%-|<%|\z)/m
168
168
  etag_reg = /(.*?)(%%>|-%>|%>|\z)/m
169
169
  scanner = StringScanner.new(@src)
170
170
  while ! scanner.eos?
@@ -5,8 +5,8 @@ require 'erb_safe_ext'
5
5
 
6
6
  template = ERB.new <<-EOF
7
7
  <%= "hello, #{'world'}." %>
8
- <%= "<script>alert('safety:)');</script>" %>
9
- <%== "<script>alert('danger!');</script>" %>
8
+ <%~ "<script>alert('safety:)');</script>" %>
9
+ <%= "<script>alert('danger!');</script>" %>
10
10
  this is the end.
11
11
  EOF
12
12
 
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: erb_safe_ext
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeffrey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-22 00:00:00.000000000 Z
11
+ date: 2014-06-30 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: make ERB default html safe.protect from XSS attack.
13
+ description: add method to erb, protect from XSS attack.
14
14
  email:
15
15
  - jeffrey6052@163.com
16
16
  executables: []
@@ -18,7 +18,6 @@ extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
20
  - lib/erb_safe_ext.rb
21
- - lib/erb_safe_ext/sinatra/exception_template.rb
22
21
  - test/erb_safe_test.rb
23
22
  - erb_safe_ext.gemspec
24
23
  - README.md
@@ -1,295 +0,0 @@
1
-
2
- #modify sinatra original exception template,fixed to erb_safe_ext.
3
-
4
- module Sinatra
5
-
6
- class ShowExceptions < Rack::ShowExceptions
7
-
8
- defined?(TEMPLATE) and remove_const(:TEMPLATE)
9
-
10
- TEMPLATE = <<-HTML # :nodoc:
11
- <!DOCTYPE html>
12
- <html>
13
- <head>
14
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
15
- <title><%= exception.class %> at <%= path %></title>
16
-
17
- <script type="text/javascript">
18
- //<!--
19
- function toggle(id) {
20
- var pre = document.getElementById("pre-" + id);
21
- var post = document.getElementById("post-" + id);
22
- var context = document.getElementById("context-" + id);
23
-
24
- if (pre.style.display == 'block') {
25
- pre.style.display = 'none';
26
- post.style.display = 'none';
27
- context.style.background = "none";
28
- } else {
29
- pre.style.display = 'block';
30
- post.style.display = 'block';
31
- context.style.background = "#fffed9";
32
- }
33
- }
34
-
35
- function toggleBacktrace(){
36
- var bt = document.getElementById("backtrace");
37
- var toggler = document.getElementById("expando");
38
-
39
- if (bt.className == 'condensed') {
40
- bt.className = 'expanded';
41
- toggler.innerHTML = "(condense)";
42
- } else {
43
- bt.className = 'condensed';
44
- toggler.innerHTML = "(expand)";
45
- }
46
- }
47
- //-->
48
- </script>
49
-
50
- <style type="text/css" media="screen">
51
- * {margin: 0; padding: 0; border: 0; outline: 0;}
52
- div.clear {clear: both;}
53
- body {background: #EEEEEE; margin: 0; padding: 0;
54
- font-family: 'Lucida Grande', 'Lucida Sans Unicode',
55
- 'Garuda';}
56
- code {font-family: 'Lucida Console', monospace;
57
- font-size: 12px;}
58
- li {height: 18px;}
59
- ul {list-style: none; margin: 0; padding: 0;}
60
- ol:hover {cursor: pointer;}
61
- ol li {white-space: pre;}
62
- #explanation {font-size: 12px; color: #666666;
63
- margin: 20px 0 0 100px;}
64
- /* WRAP */
65
- #wrap {width: 1000px; background: #FFFFFF; margin: 0 auto;
66
- padding: 30px 50px 20px 50px;
67
- border-left: 1px solid #DDDDDD;
68
- border-right: 1px solid #DDDDDD;}
69
- /* HEADER */
70
- #header {margin: 0 auto 25px auto;}
71
- #header img {float: left;}
72
- #header #summary {float: left; margin: 12px 0 0 20px; width:660px;
73
- font-family: 'Lucida Grande', 'Lucida Sans Unicode';}
74
- h1 {margin: 0; font-size: 36px; color: #981919;}
75
- h2 {margin: 0; font-size: 22px; color: #333333;}
76
- #header ul {margin: 0; font-size: 12px; color: #666666;}
77
- #header ul li strong{color: #444444;}
78
- #header ul li {display: inline; padding: 0 10px;}
79
- #header ul li.first {padding-left: 0;}
80
- #header ul li.last {border: 0; padding-right: 0;}
81
- /* BODY */
82
- #backtrace,
83
- #get,
84
- #post,
85
- #cookies,
86
- #rack {width: 980px; margin: 0 auto 10px auto;}
87
- p#nav {float: right; font-size: 14px;}
88
- /* BACKTRACE */
89
- a#expando {float: left; padding-left: 5px; color: #666666;
90
- font-size: 14px; text-decoration: none; cursor: pointer;}
91
- a#expando:hover {text-decoration: underline;}
92
- h3 {float: left; width: 100px; margin-bottom: 10px;
93
- color: #981919; font-size: 14px; font-weight: bold;}
94
- #nav a {color: #666666; text-decoration: none; padding: 0 5px;}
95
- #backtrace li.frame-info {background: #f7f7f7; padding-left: 10px;
96
- font-size: 12px; color: #333333;}
97
- #backtrace ul {list-style-position: outside; border: 1px solid #E9E9E9;
98
- border-bottom: 0;}
99
- #backtrace ol {width: 920px; margin-left: 50px;
100
- font: 10px 'Lucida Console', monospace; color: #666666;}
101
- #backtrace ol li {border: 0; border-left: 1px solid #E9E9E9;
102
- padding: 2px 0;}
103
- #backtrace ol code {font-size: 10px; color: #555555; padding-left: 5px;}
104
- #backtrace-ul li {border-bottom: 1px solid #E9E9E9; height: auto;
105
- padding: 3px 0;}
106
- #backtrace-ul .code {padding: 6px 0 4px 0;}
107
- #backtrace.condensed .system,
108
- #backtrace.condensed .framework {display:none;}
109
- /* REQUEST DATA */
110
- p.no-data {padding-top: 2px; font-size: 12px; color: #666666;}
111
- table.req {width: 980px; text-align: left; font-size: 12px;
112
- color: #666666; padding: 0; border-spacing: 0;
113
- border: 1px solid #EEEEEE; border-bottom: 0;
114
- border-left: 0;
115
- clear:both}
116
- table.req tr th {padding: 2px 10px; font-weight: bold;
117
- background: #F7F7F7; border-bottom: 1px solid #EEEEEE;
118
- border-left: 1px solid #EEEEEE;}
119
- table.req tr td {padding: 2px 20px 2px 10px;
120
- border-bottom: 1px solid #EEEEEE;
121
- border-left: 1px solid #EEEEEE;}
122
- /* HIDE PRE/POST CODE AT START */
123
- .pre-context,
124
- .post-context {display: none;}
125
-
126
- table td.code {width:750px}
127
- table td.code div {width:750px;overflow:hidden}
128
- </style>
129
- </head>
130
- <body>
131
- <div id="wrap">
132
- <div id="header">
133
- <img src="<%== env['SCRIPT_NAME'] %>/__sinatra__/500.png" alt="application error" height="161" width="313" />
134
- <div id="summary">
135
- <h1><strong><%= exception.class %></strong> at <strong><%= path %>
136
- </strong></h1>
137
- <h2><%= exception.message %></h2>
138
- <ul>
139
- <li class="first"><strong>file:</strong> <code>
140
- <%= frames.first.filename.split("/").last %></code></li>
141
- <li><strong>location:</strong> <code><%= frames.first.function %>
142
- </code></li>
143
- <li class="last"><strong>line:
144
- </strong> <%= frames.first.lineno %></li>
145
- </ul>
146
- </div>
147
- <div class="clear"></div>
148
- </div>
149
-
150
- <div id="backtrace" class='condensed'>
151
- <h3>BACKTRACE</h3>
152
- <p><a href="#" id="expando"
153
- onclick="toggleBacktrace(); return false">(expand)</a></p>
154
- <p id="nav"><strong>JUMP TO:</strong>
155
- <a href="#get-info">GET</a>
156
- <a href="#post-info">POST</a>
157
- <a href="#cookie-info">COOKIES</a>
158
- <a href="#env-info">ENV</a>
159
- </p>
160
- <div class="clear"></div>
161
-
162
- <ul id="backtrace-ul">
163
-
164
- <% id = 1 %>
165
- <% frames.each do |frame| %>
166
- <% if frame.context_line && frame.context_line != "#" %>
167
-
168
- <li class="frame-info <%== frame_class(frame) %>">
169
- <code><%= frame.filename %></code> in
170
- <code><strong><%= frame.function %></strong></code>
171
- </li>
172
-
173
- <li class="code <%== frame_class(frame) %>">
174
- <% if frame.pre_context %>
175
- <ol start="<%= frame.pre_context_lineno + 1 %>"
176
- class="pre-context" id="pre-<%== id %>"
177
- onclick="toggle(<%== id %>);">
178
- <% frame.pre_context.each do |line| %>
179
- <li class="pre-context-line"><code><%= line %></code></li>
180
- <% end %>
181
- </ol>
182
- <% end %>
183
-
184
- <ol start="<%== frame.lineno %>" class="context" id="<%== id %>"
185
- onclick="toggle(<%== id %>);">
186
- <li class="context-line" id="context-<%== id %>"><code><%= frame.context_line %></code></li>
187
- </ol>
188
-
189
- <% if frame.post_context %>
190
- <ol start="<%= frame.lineno + 1 %>" class="post-context"
191
- id="post-<%== id %>" onclick="toggle(<%== id %>);">
192
- <% frame.post_context.each do |line| %>
193
- <li class="post-context-line"><code><%= line %></code></li>
194
- <% end %>
195
- </ol>
196
- <% end %>
197
- <div class="clear"></div>
198
- </li>
199
-
200
- <% end %>
201
-
202
- <% id += 1 %>
203
- <% end %>
204
-
205
- </ul>
206
- </div> <!-- /BACKTRACE -->
207
-
208
- <div id="get">
209
- <h3 id="get-info">GET</h3>
210
- <% if req.GET and not req.GET.empty? %>
211
- <table class="req">
212
- <tr>
213
- <th>Variable</th>
214
- <th>Value</th>
215
- </tr>
216
- <% req.GET.sort_by { |k, v| k.to_s }.each { |key, val| %>
217
- <tr>
218
- <td><%= key %></td>
219
- <td class="code"><div><%= val.inspect %></div></td>
220
- </tr>
221
- <% } %>
222
- </table>
223
- <% else %>
224
- <p class="no-data">No GET data.</p>
225
- <% end %>
226
- <div class="clear"></div>
227
- </div> <!-- /GET -->
228
-
229
- <div id="post">
230
- <h3 id="post-info">POST</h3>
231
- <% if req.POST and not req.POST.empty? %>
232
- <table class="req">
233
- <tr>
234
- <th>Variable</th>
235
- <th>Value</th>
236
- </tr>
237
- <% req.POST.sort_by { |k, v| k.to_s }.each { |key, val| %>
238
- <tr>
239
- <td><%= key %></td>
240
- <td class="code"><div><%= val.inspect %></div></td>
241
- </tr>
242
- <% } %>
243
- </table>
244
- <% else %>
245
- <p class="no-data">No POST data.</p>
246
- <% end %>
247
- <div class="clear"></div>
248
- </div> <!-- /POST -->
249
-
250
- <div id="cookies">
251
- <h3 id="cookie-info">COOKIES</h3>
252
- <% unless req.cookies.empty? %>
253
- <table class="req">
254
- <tr>
255
- <th>Variable</th>
256
- <th>Value</th>
257
- </tr>
258
- <% req.cookies.each { |key, val| %>
259
- <tr>
260
- <td><%= key %></td>
261
- <td class="code"><div><%= val.inspect %></div></td>
262
- </tr>
263
- <% } %>
264
- </table>
265
- <% else %>
266
- <p class="no-data">No cookie data.</p>
267
- <% end %>
268
- <div class="clear"></div>
269
- </div> <!-- /COOKIES -->
270
-
271
- <div id="rack">
272
- <h3 id="env-info">Rack ENV</h3>
273
- <table class="req">
274
- <tr>
275
- <th>Variable</th>
276
- <th>Value</th>
277
- </tr>
278
- <% env.sort_by { |k, v| k.to_s }.each { |key, val| %>
279
- <tr>
280
- <td><%= key %></td>
281
- <td class="code"><div><%= val %></div></td>
282
- </tr>
283
- <% } %>
284
- </table>
285
- <div class="clear"></div>
286
- </div> <!-- /RACK ENV -->
287
-
288
- <p id="explanation">You're seeing this error because you have
289
- enabled the <code>show_exceptions</code> setting.</p>
290
- </div> <!-- /WRAP -->
291
- </body>
292
- </html>
293
- HTML
294
- end
295
- end