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 _ - .