This page outlines the security features implemented in the backend system, managing user authentication, protecting the system from unauthorized access, and taking care of common security vulnerabilities.
The security implementation is largely based on features from Spring Security 6, implementing various features provided by the framework. Using this framework provides us with strong security features that do not require much setup and configuration, and easily integrates these security features into the Spring BOOT framework that the backend system is built on.
Authentication
User authentication is handled using a Spring Security OAuth2.0 resource server. More specifically, a self-hosted resource server provides JWT bearer tokens to successfully authenticated users, through methods provided by the Nimbuds Jose JWT library included in the Spring Security OAuth2.0 framework. This bearer token is self-signed by the server using a programmatically created RSA keypair, instantiated when the server system launches. The keypair is created using the KeyGeneratorUtils utility class, initializing a 2048-bit RSA keypair using a Java Security KeyPairGenerator, and providing it as a Spring component. The Jwks utility class further uses the key generator utility class to fetch the generated keypair and prepares it for JSON Web Key Set (JWKS) support. The authentication methods are exposed as Spring Beans through the AuthenticationConfig class.
The authentication system is based on a tutorial by Dan Vega (https://www.youtube.com/watch?v=UaB-0e76LdQ).
Authorization
Authorization is handled by defining a Spring Security SecurityFilterChain, and exposing it as a Spring Bean. The SecurityFilterChain looks at HTTP-requests, and lets us define addresses through request matchers to specify required access levels. Specifically, we have whitelisted access to addresses for user creation and authentication, and the Swagger API documentation page, by specifying request matchers for these addresses and permitting all relevant request methods. The rest of our system is restricted by requiring any request to be authenticated, meaning all HTTP requests that are not specifically whitelisted need a valid authentication token to be permitted.
Encryption
The previously mentioned AuthenticationConfig class also exposes a PasswordEncoder Spring Bean. The PasswordEncoder class is a class provided by the Spring Security framework, and provides methods to hash passwords using common hashing algorithms. Our PasswordEncoder uses the default bcrypt hashing algorithm. We then use the PasswordEncoder bean to hash passwords in our user registration endpoint, making sure that all passwords are hashed when stored in our database.
Furthermore, our live hosted system uses SSL certificates for secure browsing, provided by the domain service GoDaddy, who also provides our "smartmat.app" domain.
Other security practices
The Spring Security framework provides further security features. These features are largely enabled and configured by default. The Spring Security reference documentation provides an overview of some of the security features that are provided by simply enabling Spring Security:
- Session Fixation protection
- Security Header integration
- HTTP Strict Transport Security for secure requests
- X-Content-Type-Options integration
- Cache Control (can be overridden later by your application to allow caching of your static resources)
- X-XSS-Protection integration
- X-Frame-Options integration to help prevent Clickjacking
(https://docs.spring.io/spring-security/reference/servlet/getting-started.html)
On top of this, we have configured a custom Cross-Origin Resource Sharing (CORS) policy implementation, exposed as a Spring Bean in our CorsConfig class. This lets us define trusted origins that are permitted to make requests to our API. Specifically, we allow requests from our frontend domain "https://smartmat.app", and during development we have also allowed the origin "https://localhost" to make it easier for frontend developers to implement API functionality.
HTTPS
The frontend is configured with a HTTPS-certificate. This originated from a feature issued by the development team. To fully integrate being able to scan products in the website, a requirement from the browser was that the website was HTTPS-certified to access the user's camera. This issue was solved by deploying the built application code for the frontend to Github Pages. Github Pages serves static pages with a valid SSL sertificate, which in turn enables Github to secure the client-server communication.
By having served the website as a HTTPS-website, the communication, such as login requests are sent by secured call to the backend API. This ensures that the packets are encrypted, blocking the information from sniffers.
Token-validation
The frontend is implemented using a Pinia-storage system. This stores information on the logged in user in the browser's session storage. Information such as the current JWT-token and username is stored here.
To ensure that the token is valid at any user action, the frontend issues calls to the backend. The Vue Router is implemented with a router guard that manually extracts the user token and calls on the API to ensure that the user is logged in on each redirection which requires authorization.
The security is increased by manual extraction of the user token from session storage. This ensures that if the token is manually edited by the user, the updated token is validated on the next redirection. This is superior to using the Pinia store to extract the token, as it takes longer time to update the variable. This ensures live-validation on changes. The validation is, in practice, done by utilizing an Axios interceptor that sends the current authorization-header with the request. The same procedure is implemented for all API-calls that requires authorization.
Javascript injections
Vue and Axios helps mitigate inputs from being sent as injectibles to the backend by default.
Dependency check
The CI-pipeline utilizes the OWASP dependency check to locate and report vulnerabilities i the dependencies used by the frontend application. This generates a report described in the wiki page: https://gitlab.stud.idi.ntnu.no/idatt2106-v23-03/backend/-/wikis/CI-CD-and-testing