Created
Apr 8, 2022 8:17 AM
Department
Engineering
Category
Security
Technology
Ruby on RailsReactAngular
Tags
Date
URL
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:
‣
- 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.
- 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. - 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: - The above configuration will block all external sources except resources from the same origin. Whitelist the sources you want to load as follows:
- Re-run the Mozilla observatory test and you should now see an A+
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();
});
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, import helmet
before handling any custom routes.
import * as helmet from 'helmet';
app.use(helmet());
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.
An example of production configuration for styleSrc
and connectSrc
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']
‣
- Content Security Policy
- For RAILS 5.2 and higher go to
config/content_security_policy.rb
file and add - For RAILS version lower than 5.2 use gem Secure_Headers.
- Cookies
- For securing cookies in your rails application go to
config/environments/production.rb
file and addconfig.force_ssl = true
. - 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
file - if you are using Rails 5 add below code to
config/application.rb
file if you are using Rails 5 - On production site we should only add the UI domain as the origin whereas in staging it can be "*".
- 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 add - 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
Rails.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
config.middleware.insert_before 0, "Rack::Cors" do
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :options]
end
end
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :options]
end
end
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
Rails.application.configure do
config.action_dispatch.default_headers = {
'Referrer-Policy' => 'strict-origin-when-cross-origin'
}
end
Supplementary resources: