In order to help webmasters better protect their websites and users, Mozilla has built an online scanner Mozilla Observatory that can check if web servers have the best security settings in place.
Steps to score an A+ security rating from Mozilla Observatory:
REACT/ANGULAR
-
As the first step, Enfore HTTPS! Always make sure to add a redirection rule from HTTP to HTTPS. If your application is running on AWS-load balancer, enfore HTTPS on load balancer or if it’s hosted elsewhere, add the following code in your app server.
app.use(function (req, res, next) { if (!req.secure && (process.env.NODE_ENV === `production`) { res.redirect("https://" + req.headers.host + req.url) } else return next(); });
-
Next, we are going to use HELMET for increasing the rating. Go to your project, and do
npm i helmet
. -
For React, In the
server.js
file, importhelmet
and use it with your app. Make sure to use helmet before handling any custom routes.const express = require('express') const helmet = require('helmet') const app = express() const port = process.env.PORT || 3000 app.use(helmet()) ...other configuration app.listen(port, () => { console.log(`Running on port : ${port}`) })
For Angular, In
server/app.ts
file, importhelmet
before handling any custom routes.import * as helmet from 'helmet'; app.use(helmet());
-
Helmet with default configuration will increase the security rating from F to B. We need to do one more thing to score an A+ which is to implement CSP (Content Security Policy).
-
For React, Just below the
app.use(helmet())
line in theserver.js
file, add the following:app.use( helmet({ contentSecurityPolicy: { directives: { scriptSrc: ["'self'"] baseUri: ["'self'"], objectSrc: ["'self'"], styleSrc: ["'self'"], fontSrc: ["'self'"], frameAncestors: ["'self'"], defaultSrc: ["'self'"], connectSrc: ["'self'"], imgSrc: ["'self'"], formAction: ["'self'"] } } }) )
Make the above changes for Angular in
server/app.ts
file. -
The above configuration will block all external sources except resources from the same origin. Whitelist the sources you want to load as follows:
An example of production configuration for
styleSrc
andconnectSrc
would be://allow styles to load from same origin, google and cloudfront. styleSrc: ["'self'",'https://fonts.googleapis.com','https://*.cloudfront.net'] //allow content to load from same origin and c66. connectSrc: ["'self'", 'http://*.c66.me/graphql']
-
Re-run the mozilla observatory test and you should now see an A+
RAILS
- Content Security Policy
- For RAILS 5.2 and higher go to
config/content_security_policy.rb
file and addRails.application.config.content_security_policy do |policy| policy.default_src :none policy.font_src :self policy.img_src :self policy.object_src :none policy.script_src :self policy.style_src :self policy.report_uri "/csp-violation-report-endpoint" end
If you want data from a specific url as well as self :-
Rails.application.config.content_security_policy do |p| .... p.img_src :self, 'url', :https ... end
- For RAILS version lower than 5.2 use gem Secure_Headers.
- For RAILS 5.2 and higher go to
- Cookies
- For securing cookies in your rails application go to
config/environments/production.rb
file and addconfig.force_ssl = true
.
- For securing cookies in your rails application go to
- Cross-origin Resource Sharing
- add
gem 'rack-cors'
into your gemfile - if you are using Rails 3/4 add below code to
config/application.rb
fileconfig.middleware.insert_before 0, "Rack::Cors" do allow do origins '*' resource '*', headers: :any, methods: [:get, :post, :options] end end
- if you are using Rails 5 add below code to
config/application.rb
file if you are using Rails 5config.middleware.insert_before 0, Rack::Cors do allow do origins '*' resource '*', headers: :any, methods: [:get, :post, :options] end end
- On production site we should only add the UI domain as the origin whereas in staging it can be “*”.
config.middleware.insert_before 0, Rack::Cors do allow do origins 'www.xyz.com', '127.0.0.1:3000', /\Ahttp:\/\/192\.168\.0\.\d{1,3}(:\d+)?\z/ # regular expressions can be used here resource '*', headers: :any, methods: [:get, :post, :options] end end
- add
-
HTTP Strict Transport Security - For HSTS in your rails application
config/environments/production.rb
file addconfig.force_ssl = true
. -
Redirection - For redirecting from bad urls in your application
config/environments/production.rb
file addconfig.force_ssl = true
. - Referrer Policy - In Rails applications, security headers can be set in either
config/application.rb
or in specificconfig/environments/
files. - Inconfig/environments/production.rb
file addRails.application.configure do config.action_dispatch.default_headers = { 'Referrer-Policy' => 'strict-origin-when-cross-origin' } end
-
X-Content-Type-Options - In Rails applications, security headers can be set in either
config/application.rb
or in specificconfig/environments/
files. - Inconfig/environments/production.rb
file addruby Rails.application.configure do config.action_dispatch.default_headers = { 'X-Content-Type-Options' => 'nosniff' } end
-
X-Frame-Options - In Rails applications, security headers can be set in either
config/application.rb
or in specificconfig/environments/
files. - Inconfig/environments/production.rb
file addruby Rails.application.configure do config.action_dispatch.default_headers = { 'X-Frame-Options' => 'SAMEORIGIN' } end
- X-XSS-Protection - In Rails applications, security headers can be set in either
config/application.rb
or in specificconfig/environments/
files. - Inconfig/environments/production.rb
file addruby Rails.application.configure do config.action_dispatch.default_headers = { 'X-XSS-Protection' => '1; mode=block' } end
Supplementary resources: