diff --git a/app.rb b/app.rb index 33751c52..34368163 100644 --- a/app.rb +++ b/app.rb @@ -201,7 +201,7 @@ get '/site_files/text_editor/:filename' do |filename| end post '/site_files/save/:filename' do |filename| - halt 'You are not logged in!' if current_site.nil? + require_login_ajax tmpfile = Tempfile.new 'neocities_saving_file' @@ -235,6 +235,10 @@ get '/privacy' do slim :'privacy' end +before do + redirect '/' if request.post? && !csrf_safe? +end + def sites_name_redirect path = request.path.gsub "/sites/#{params[:name]}", '' # path += "/#{params[:file]}" unless params[:file].nil? @@ -246,6 +250,18 @@ def dashboard_if_signed_in redirect '/dashboard' if signed_in? end +def require_login_ajax + halt 'You are not logged in!' unless signed_in? +end + +def csrf_safe? + csrf_token == params[:csrf_token] || csrf_token == request.env['HTTP_X_CSRF_TOKEN'] +end + +def csrf_token + session[:_csrf_token] ||= SecureRandom.base64(32) +end + def require_login redirect '/' unless signed_in? end diff --git a/views/dashboard.slim b/views/dashboard.slim index 6a59a2df..d30ab1ed 100644 --- a/views/dashboard.slim +++ b/views/dashboard.slim @@ -66,6 +66,7 @@ javascript: h4: a href="/site_files/#{current_site.username}.zip" Download Entire Site form method="POST" action="/site_files/delete" id="deleteFilenameForm" + input name="csrf_token" type="hidden" value="#{csrf_token}" input type="hidden" id="deleteFilenameInput" name="filename" .modal.hide.fade id="deleteConfirmModal" tabindex="-1" role="dialog" aria-labelledby="deleteConfirmModalLabel" aria-hidden="true" diff --git a/views/layout.slim b/views/layout.slim index 7149126d..5c33cdb2 100644 --- a/views/layout.slim +++ b/views/layout.slim @@ -9,6 +9,7 @@ html link href="/css/styles.css" rel="stylesheet" meta property="og:title" content="NeoCities" meta property="og:description" content="NeoCities is the new Geocities. Create your own free home page, and do whatever you want with it." + meta name="csrf-token" content="#{csrf_token}" script src="/js/jquery.min.js" body @@ -40,6 +41,16 @@ html script src="/js/bootstrap.min.js" + javascript: + !function(){ + var csrf_token = $('meta[name="csrf-token"]').attr('content'); + + $(document).ajaxSend(function(ev, jqxhr){ + jqxhr.setRequestHeader('X-CSRF-Token', csrf_token); + }); + }(); + + javascript: (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), @@ -47,4 +58,4 @@ html })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-41925541-1', 'neocities.org'); - ga('send', 'pageview'); \ No newline at end of file + ga('send', 'pageview'); diff --git a/views/new.slim b/views/new.slim index 7355fa9b..f94b8a69 100644 --- a/views/new.slim +++ b/views/new.slim @@ -14,9 +14,10 @@ javascript: .row .span8.offset3 - form method="POST" action="/create" + form method="POST" action="/create" + input name="csrf_token" type="hidden" value="#{csrf_token}" h2 Create a new Home Page - + .row .span6 p First, enter a username. This will also be used as your site path.
Do not forget this, it will be used to sign in to and manage your home page.
It cannot contain spaces, and can only use the following characters: a-z A-Z 0-9 _ - @@ -71,4 +72,4 @@ javascript: .row style="margin-top: 10px" .span3.offset1 - input.btn.btn-success.btn-large type="submit" value="Create Home Page" \ No newline at end of file + input.btn.btn-success.btn-large type="submit" value="Create Home Page" diff --git a/views/signin.slim b/views/signin.slim index 11e8720e..0248d542 100644 --- a/views/signin.slim +++ b/views/signin.slim @@ -5,10 +5,12 @@ .row .span12 form method="POST" action="/signin" + input name="csrf_token" type="hidden" value="#{csrf_token}" + fieldset div: input name="username" type="text" placeholder="Your username" div: input name="password" type="password" placeholder="Your password" div: button class="btn btn-large btn-success" href="#" style="margin-top: 10px" Sign in .row .span12 - a href="/new" I don't have an account yet. \ No newline at end of file + a href="/new" I don't have an account yet. diff --git a/views/site_files/new.slim b/views/site_files/new.slim index f53d9447..36ac46f9 100644 --- a/views/site_files/new.slim +++ b/views/site_files/new.slim @@ -13,6 +13,7 @@ .row .span12.text-center form method="POST" action="/site_files/upload" enctype="multipart/form-data" + input name="csrf_token" type="hidden" value="#{csrf_token}" h4 Select a file from your computer: h4: input type="file" name="newfile" p: input.btn.btn-success.btn-large type="submit" value="Upload File" @@ -31,4 +32,4 @@ h4 If the file already exists, it will be overwritten without warning. h4 It has to be legal to share this content in the United States. h4 It must fit into your home page space (5MB). - h4 The file uploader will automatically scrub any characters not matching: a-z A-Z 0-9 _ - . \ No newline at end of file + h4 The file uploader will automatically scrub any characters not matching: a-z A-Z 0-9 _ - .