Class: TDiary::TDiaryAuthorOnlyBase

Inherits:
TDiaryBase show all
Defined in:
lib/tdiary/author_only_base.rb

Overview

class TDiaryAuthorOnlyBase base class for author-only access pages

Direct Known Subclasses

TDiaryAdmin, TDiaryConf, TDiaryFormPlugin

Constant Summary

Constants inherited from TDiaryBase

TDiary::TDiaryBase::DIRTY_COMMENT, TDiary::TDiaryBase::DIRTY_DIARY, TDiary::TDiaryBase::DIRTY_NONE, TDiary::TDiaryBase::DIRTY_REFERER

Instance Attribute Summary

Attributes inherited from TDiaryBase

#cgi, #conf, #cookies, #date, #diaries, #ignore_parser_cache, #request, #rhtml

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from TDiaryBase

#[], #calendar, #eval_rhtml, #last_modified

Methods included from ViewHelper

#base_url, #bot?

Constructor Details

#initialize(cgi, rhtml, conf) ⇒ TDiaryAuthorOnlyBase

Returns a new instance of TDiaryAuthorOnlyBase.



71
72
73
74
# File 'lib/tdiary/author_only_base.rb', line 71

def initialize( cgi, rhtml, conf )
  super
  csrf_check( @request, conf )
end

Class Method Details

.csrf_fetch_verdict(origin, sec_fetch_site, allowed_origins) ⇒ Object

classify the request provenance from browser fetch metadata: :same_origin / :cross_site / :unknown (no usable signal, e.g. non-browser clients or a user-initiated navigation)



35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/tdiary/author_only_base.rb', line 35

def self.csrf_fetch_verdict( origin, sec_fetch_site, allowed_origins )
  if origin and !origin.empty?
    # 'null' (sandboxed or opaque initiators) never matches
    return allowed_origins.include?( origin.downcase ) ? :same_origin : :cross_site
  end
  case sec_fetch_site
  when 'same-origin'
    :same_origin
  when 'same-site', 'cross-site'
    :cross_site
  else
    :unknown
  end
end

.csrf_origin_of(url) ⇒ Object

normalize an absolute http(s) URL to its origin serialization (lowercase scheme://host, default port omitted); nil when the input has no usable origin



23
24
25
26
27
28
29
30
# File 'lib/tdiary/author_only_base.rb', line 23

def self.csrf_origin_of( url )
  uri = URI.parse( url.to_s )
  return nil unless uri.kind_of?( URI::HTTP ) and uri.host
  port = uri.port == uri.default_port ? '' : ":#{uri.port}"
  "#{uri.scheme.downcase}://#{uri.host.downcase}#{port}"
rescue URI::InvalidURIError
  nil
end

.csrf_provenance_ok?(origin, sec_fetch_site, referer, allowed_origins, config_uri, allowed_referer_regexp, check_referer) ⇒ Boolean

main csrf decision: Origin / Sec-Fetch-Site first, the legacy Referer check only as a fallback when neither header gives a usable signal. A cross-site verdict can still be allowed by an explicit Referer allowance (the update page itself or the admin-configured regexp), but not by the empty-referer tolerance of check_referer=false.

Returns:

  • (Boolean)


56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/tdiary/author_only_base.rb', line 56

def self.csrf_provenance_ok?( origin, sec_fetch_site, referer, allowed_origins, config_uri, allowed_referer_regexp, check_referer )
  case csrf_fetch_verdict( origin, sec_fetch_site, allowed_origins )
  when :same_origin
    true
  when :cross_site
    referer != '' && csrf_referer_allowed?( referer, config_uri, allowed_referer_regexp )
  else
    if referer == ''
      !check_referer
    else
      csrf_referer_allowed?( referer, config_uri, allowed_referer_regexp )
    end
  end
end

.csrf_referer_allowed?(referer, config_uri, allowed_referer_regexp) ⇒ Boolean

referer must be non-empty with its query string stripped; it is allowed when it names the update page itself or matches the admin-configured regexp

Returns:

  • (Boolean)


15
16
17
18
# File 'lib/tdiary/author_only_base.rb', line 15

def self.csrf_referer_allowed?( referer, config_uri, allowed_referer_regexp )
  return true if config_uri == URI.parse( referer )
  allowed_referer_regexp != '' && Regexp.new( allowed_referer_regexp ).match?( referer )
end

Instance Method Details

#csrf_protection_get_is_okayObject



7
# File 'lib/tdiary/author_only_base.rb', line 7

def csrf_protection_get_is_okay; false; end