Mitigation Strategy: Leverage Liquid's strict_variables
and strict_filters
Modes
-
Description:
- Enable Modes: When initializing the
Liquid::Template
object in your server-side code (e.g., Ruby), set thestrict_variables
andstrict_filters
options totrue
. This is done at the point of Liquid instantiation, making it a Liquid-specific configuration.template = Liquid::Template.parse(template_string, strict_variables: true, strict_filters: true)
- Error Handling: Wrap the template rendering process in a
begin...rescue
block (or your language's equivalent) to catchLiquid::UndefinedVariable
andLiquid::UndefinedFilter
exceptions. This error handling is directly related to the Liquid engine's behavior. - Log Errors: Log any exceptions caught, including the context (template name, input data, etc.). This logging is triggered by Liquid's error handling.
- User-Friendly Error (Optional): Optionally, display a generic error message to the user (do not reveal the specific error details). This is a consequence of Liquid's error.
- Enable Modes: When initializing the
-
List of Threats Mitigated:
- Logic Errors (Severity: Low): Helps catch unintentional use of undefined variables or filters, which could lead to unexpected behavior or data leakage. Primarily a debugging aid.
- Limited Template Injection (Severity: Low): Provides a very limited defense against certain types of template injection attempts that rely on undefined variables or filters. This is not a reliable defense against template injection, but it is a direct consequence of Liquid's configuration.
-
Impact:
- Logic Errors: Risk reduced from Low to Very Low.
- Limited Template Injection: Minimal impact; risk remains High without other mitigations (like input validation).
-
Currently Implemented:
- Development Environment: Enabled in the development environment configuration (
config/environments/development.rb
). - Test Environment: Enabled in the test environment configuration (
config/environments/test.rb
).
- Development Environment: Enabled in the development environment configuration (
-
Missing Implementation:
- Production Environment: Not currently enabled in production (
config/environments/production.rb
). We need to evaluate whether our application logic is robust enough to guarantee that all variables and filters will always be defined.
- Production Environment: Not currently enabled in production (
Mitigation Strategy: Avoid render
, include
with Dynamic Paths (Within Liquid)
-
Description:
- Identify Dynamic Paths: Within your Liquid templates, search for any instances of
{% render ... %}
or{% include ... %}
where the template path is determined, even partially, by a Liquid variable that could be influenced by user input. - Replace with Hardcoded Paths: If possible, replace these dynamic paths with hardcoded, known-safe paths within the Liquid template itself. This is a direct modification of the Liquid code.
<!-- BAD: Potentially dynamic --> {% render some_variable %} <!-- GOOD: Hardcoded --> {% render 'partials/my_safe_partial' %}
- Implement Whitelist (Server-Side, but Affects Liquid): If dynamic template selection is absolutely required, the decision of which template to use must happen on the server-side, and a safe, pre-approved value should be passed to Liquid. The Liquid template then uses this safe value. This is a combination of server-side logic and Liquid usage. The key is that the Liquid template itself never directly handles potentially unsafe input for the path.
- Conditional Rendering (Alternative): Consider refactoring your Liquid templates to use conditional logic (
{% if ... %}{% elsif ... %}{% else %}{% endif %}
) within a single template, rather than dynamically including different templates. This is a direct change to the Liquid code to avoid therender
/include
issue.
- Identify Dynamic Paths: Within your Liquid templates, search for any instances of
-
List of Threats Mitigated:
- Path Traversal (Severity: High): Prevents attackers from accessing arbitrary files on the server by manipulating the template path through Liquid.
- Template Injection (Severity: High): By controlling which templates are included via Liquid, reduces the risk of attackers injecting malicious Liquid code.
-
Impact:
- Path Traversal: Risk reduced from High to Very Low.
- Template Injection: Risk reduced from High to Low.
-
Currently Implemented:
- Main Layout Templates: The main layout templates (
app/views/layouts/
) use hardcoded paths within the Liquid files. - Partial Views: Most partial views are included using hardcoded paths within the Liquid files.
- Main Layout Templates: The main layout templates (
-
Missing Implementation:
- User-Generated Content Sections: The Liquid template in the user profile section needs to be refactored to use either hardcoded paths or server-side whitelisting, ensuring the Liquid code itself doesn't handle potentially unsafe paths.
Mitigation Strategy: Be Extremely Cautious with Custom Filters and Tags (Within Liquid's Implementation)
-
Description: This strategy focuses on the implementation of the custom filters and tags themselves, which are part of how Liquid functions in your application.
- Identify Custom Components: List all custom Liquid filters and tags defined in your application.
- Input Validation (Within Components): Within the Ruby (or other language) code that defines the custom filter or tag, validate and sanitize all input received. This code is directly extending Liquid's functionality.
- Avoid System Calls: Ensure the code defining the custom filter or tag never executes system commands or accesses sensitive resources directly. This is a restriction on the implementation of the Liquid extension.
- Least Privilege: Ensure that the code for your custom filters and tags has only the minimum necessary permissions. This applies to the environment in which the Liquid extensions are executed.
- Thorough Testing: Create unit tests and integration tests for each custom filter and tag, specifically testing with various inputs. This testing focuses on the behavior of the Liquid extensions.
-
List of Threats Mitigated:
- Code Injection (Severity: High): Prevents attackers from injecting malicious code into your custom filters and tags, which are executed as part of Liquid's processing.
- Data Leakage (Severity: Medium-High): By controlling what data is accessed and processed within the filter/tag (part of Liquid's extended functionality), reduces the risk of exposing sensitive information.
- System Compromise (Severity: Critical): By avoiding system calls within the Liquid extension code, prevents attackers from gaining control of the server.
-
Impact:
- Code Injection: Risk reduced from High to Low (depending on the complexity of the filter/tag).
- Data Leakage: Risk reduced from Medium-High to Low.
- System Compromise: Risk reduced from Critical to Very Low.
-
Currently Implemented:
format_date
Filter: This custom filter (part of our Liquid implementation) formats dates. It includes basic validation.
-
Missing Implementation:
generate_widget
Tag: This custom tag (part of our Liquid implementation) lacks input validation and needs a complete rewrite.- Review of all custom filters and tags: A complete security review of all custom filters and tags (all part of our extended Liquid functionality) is needed.
Mitigation Strategy: Avoid Dynamic Variable/Filter Names from User Input (Within Liquid):
-
Description:
- Identify Dynamic Access: Within your Liquid templates, search for any instances where a Liquid variable is used to construct the name of another variable or filter being accessed (e.g.,
{{ object[variable_name] }}
). Thevariable_name
here could be influenced by user input. - Replace with Static Access: Refactor the Liquid template code to use static variable and filter names whenever possible.
<!-- BAD: Potentially dynamic --> {{ object[some_variable] }} <!-- GOOD: Static --> {{ object.my_safe_field }}
- Whitelist (Server-Side, but Affects Liquid): If dynamic access is unavoidable, the decision of which variable/filter to access must happen on the server-side. A safe, pre-approved value should be passed to Liquid. The Liquid template then uses this safe value. The key is that the Liquid template itself never directly handles potentially unsafe input for the variable/filter name.
- Identify Dynamic Access: Within your Liquid templates, search for any instances where a Liquid variable is used to construct the name of another variable or filter being accessed (e.g.,
-
List of Threats Mitigated:
- Template Injection (Severity: High): Prevents attackers from accessing arbitrary variables or filters through Liquid, potentially exposing sensitive data or manipulating the application's behavior.
-
Impact:
- Template Injection: Risk reduced from High to Low.
-
Currently Implemented:
- Generally Avoided: We generally avoid this pattern in our Liquid templates.
-
Missing Implementation:
- Code Review: A thorough review of all Liquid templates is needed to confirm that there are no instances of this vulnerability. We need to add a specific check for this pattern to our Liquid template review checklist.