Enhancing Security and Developer Productivity: LinkedIn’s Journey with Implementing Content Security Policy


Figure 2. Decentralized system

In our effort to decentralize Content Security Policy headers, we created a CSP Filter, which is an intercepting filter. This filter lives as part of our frontend frameworks.

Developers can define Content Security Policies as part of their app’s configurations. When a request comes in, the WebApp processes the request and produces a response. As the response is leaving the WebApp, the response is intercepted by our new CSP Filter. If the WebApp owner has defined CSPs as part of their configurations, then the CSP Filter will decorate the response with Content Security Policy response headers. If the WebApp owners have not defined CSPs as part of their configurations, then the CSP Filter will take no action.

After a response leaves the WebApp layer and returns to the traffic layer, our existing Traffic Headers Plugin looks at the response. If there are no Content Security Policy headers in the response, the plugin will decorate the response with the appropriate headers. This fallback mechanism ensures setting a CSP header for every response.

Overall with the decentralized system, we saw a reduced impact in CSP changes, ensuring that changes have a limited and well-contained scope within the application thus minimizing the potential errors and disruptions. We were able to equip developers with the necessary tools, resources and knowledge to efficiently implement by themselves thereby empowering developer productivity. Additionally, developers could leverage their own testing environment for testing CSP changes.

One primary disadvantage in adopting a decentralized architecture for Content Security Policy customizations is that the security governance for CSP rules became challenging due to the following reasons:

  1. Lack of centralized location to easily inspect CSP rules. 

  2. While developers are empowered to make their own changes, the Application Security  team is not directly involved in setting CSP rules leading to lack of visibility into any potentially unsafe CSP changes. 

  3. ​​Modification of CSP can be tricky for developers and sometimes requires deep knowledge of frontend security. 

We addressed these issues by adopting a shift-left approach to implement security validators that analyze code at the time of code commit. To ensure developers always commit safe CSP policies, we implemented risk-based validation rules. We leveraged GitHub validation checks to enforce the rules and appropriate actions for the developer to take using GitHub annotations. 

As an example, one critical risk rule we defined is that we support only static JavaScript using hashes or loaded from trusted sources. This means that we block a developer’s pull request (PR) when they set script-src directive to a wildcard or a domain that is not approved.  The following is a screenshot of the developer experience for critical rules.



Source link