Mitigation Strategy: Strict Input Validation and Sanitization for Server Functions
Mitigation Strategy: Strict Input Validation and Sanitization for Server Functions.
-
Description:
- Define Data Structures: Create Rust structs or enums that precisely define the expected data types and constraints for each server function input. Use descriptive field names and appropriate types (e.g.,
String
,u32
,Option<String>
). This leverages Rust's type system, which is fundamental to how Leptos server functions operate. - Validation Library (Recommended): Integrate a validation library like
validator
to add declarative validation rules to your data structures. This is a common pattern used withserde
in Leptos. Example:#[derive(Validate, Serialize, Deserialize)] struct UserInput { #[validate(length(min = 3, max = 20))] username: String, #[validate(email)] email: String, }
- Server Function Validation: At the very beginning of each server function, deserialize the input into your defined data structure using
serde
. Immediately after deserialization, call the validation function (e.g.,input.validate()?
). If validation fails, return an appropriate error. Do not proceed if validation fails. This is a direct interaction with Leptos's server function mechanism. - Sanitization (Context-Specific): After validation, perform context-specific sanitization.
- HTML Sanitization: If the input will be rendered as HTML within a Leptos component, use
ammonia
to sanitize it. Example:let sanitized_html = ammonia::clean(&input.comment);
. This is relevant because the output will be used within Leptos's rendering system. - SQL Sanitization: If interacting with a database from a Leptos server function, use the database driver's escaping or parameterized queries.
- HTML Sanitization: If the input will be rendered as HTML within a Leptos component, use
- Error Handling: Handle validation and sanitization errors gracefully, returning informative errors (without sensitive details) and logging detailed errors on the server. This uses Leptos's
Result
handling within server functions.
- Define Data Structures: Create Rust structs or enums that precisely define the expected data types and constraints for each server function input. Use descriptive field names and appropriate types (e.g.,
-
Threats Mitigated:
- Remote Code Execution (RCE): (Severity: Critical)
- Cross-Site Scripting (XSS): (Severity: High) - Specifically within Leptos-rendered content.
- SQL Injection: (Severity: Critical) - When database interaction is within a Leptos server function.
- Denial of Service (DoS): (Severity: High)
- Other Injection Attacks: (Severity: Variable)
-
Impact:
- RCE: Risk reduced from Critical to Negligible.
- XSS: Risk reduced from High to Low (within Leptos components).
- SQL Injection: Risk reduced from Critical to Negligible.
- DoS: Risk significantly reduced.
- Other Injection Attacks: Risk significantly reduced.
-
Currently Implemented:
- Example:
src/api/user.rs
-create_user
usesUserInput
andvalidator
. - Example:
src/api/comments.rs
-add_comment
usesammonia
.
- Example:
-
Missing Implementation:
- Example:
src/api/search.rs
-search_products
lacks a struct andvalidator
. - Example:
src/api/admin.rs
- Server functions lack consistent validation.
- Example:
Mitigation Strategy: Comprehensive XSS Protection within Leptos Components
Mitigation Strategy: Comprehensive XSS Protection in Leptos Components.
-
Description:
- Prefer Leptos Templating: Use Leptos's built-in templating features (e.g.,
view!
, component properties) for rendering data. This is the core of how Leptos handles safe rendering. - Avoid
inner_html
(Generally): Minimizeinner_html
. If unavoidable, go to step 3. inner_html
Sanitization: Ifinner_html
is absolutely necessary, always sanitize the input usingammonia
before inserting it. This is crucial becauseinner_html
bypasses Leptos's built-in escaping. Example:let unsafe_html = "<script>alert('XSS')</script><p>Some content</p>"; let safe_html = ammonia::clean(unsafe_html); view! { <div inner_html=safe_html></div> }
- Contextual Escaping: When manually constructing HTML attributes or inline JavaScript within a Leptos component, use appropriate escaping.
- Component Review: Before using third-party Leptos components, review their source for
inner_html
usage and ensure proper escaping. This is specific to the Leptos component ecosystem. web-sys
Caution: When usingweb-sys
within a Leptos component to interact with JavaScript, be extremely careful about passing data to JavaScript functions that might modify the DOM. Sanitize or escape data, treating it as untrusted. This is relevant because it's within the context of Leptos's frontend.
- Prefer Leptos Templating: Use Leptos's built-in templating features (e.g.,
-
Threats Mitigated:
- Cross-Site Scripting (XSS): (Severity: High) - Specifically within Leptos-rendered content.
-
Impact:
- XSS: Risk reduced from High to Low.
-
Currently Implemented:
- Example: Most components in
src/components/
use Leptos templating.
- Example: Most components in
-
Missing Implementation:
- Example:
src/components/markdown_viewer.rs
usesinner_html
withoutammonia
.
- Example:
Mitigation Strategy: Safe Reactivity Practices
Mitigation Strategy: Debouncing, Throttling, and Careful Signal Graph Design within Leptos.
-
Description:
- Identify High-Frequency Signals: Analyze your Leptos application's reactive graph and identify signals updated frequently, especially those from user input or network events within Leptos components.
- Debouncing: For signals triggered by user input that don't need immediate processing, use Leptos's
create_debounce
. Example:let (input, set_input) = create_signal(String::new()); let debounced_input = create_debounce( move || input.get(), Duration::from_millis(300), ); // Use debounced_input in your effects or views
- Throttling: For signals needing regular but not too frequent updates, use Leptos's
create_throttle
. Example:let (scroll_position, set_scroll_position) = create_signal(0); let throttled_scroll = create_throttle( move || scroll_position.get(), Duration::from_millis(100), ); // Use throttled_scroll to update UI elements
- Signal Graph Design:
- Minimize Signal Dependencies: Avoid unnecessary dependencies between Leptos signals.
- Avoid Cycles: Ensure your Leptos reactive graph doesn't contain cycles.
- Use Derived Signals: Use Leptos's
create_memo
for derived values. - Consider
create_resource
: For asynchronous operations within Leptos, usecreate_resource
.
- Testing: Thoroughly test your Leptos application's reactive logic.
-
Threats Mitigated:
- Denial of Service (DoS) (Client-Side): (Severity: Medium) - Within the Leptos frontend.
- Performance Issues: (Severity: Low) - Within the Leptos frontend.
-
Impact:
- DoS (Client-Side): Risk reduced from Medium to Low.
- Performance Issues: Significantly improves performance.
-
Currently Implemented:
- Example:
src/components/search_bar.rs
uses debouncing.
- Example:
-
Missing Implementation:
- Example:
src/components/live_chat.rs
needs throttling. - Example: General review of the reactive graph is needed.
- Example:
Mitigation Strategy: Secure web-sys
Usage within Leptos Components
Mitigation Strategy: Careful handling of untrusted data when using web-sys
within Leptos components.
-
Description:
- Identify
web-sys
Interactions: Locate all instances where your Leptos components useweb-sys
to interact with JavaScript APIs, especially those that involve:- Manipulating the DOM (e.g., setting
innerHTML
, adding event listeners). - Accessing browser APIs that could be security-sensitive (e.g.,
fetch
,localStorage
,WebSockets
).
- Manipulating the DOM (e.g., setting
- Treat Data as Untrusted: Assume that any data passed from Rust to JavaScript (via
web-sys
) could be manipulated by an attacker. - Sanitize/Escape: Before passing data to JavaScript functions that modify the DOM, sanitize or escape the data appropriately for the context. Use
ammonia
for HTML sanitization if the data will be rendered as HTML. - Validate Input to Callbacks: If you're using
web-sys
to set up JavaScript callbacks that pass data back to Rust, validate the data received in the callback before using it. Treat this data as untrusted, just like input to server functions. - Avoid Sensitive Operations: Be extremely cautious about using
web-sys
to perform security-sensitive operations directly from the client-side. If possible, move these operations to server functions.
- Identify
-
Threats Mitigated:
- Cross-Site Scripting (XSS): (Severity: High) - If
web-sys
is used to manipulate the DOM with untrusted data. - Other JavaScript-Related Vulnerabilities: (Severity: Variable) - Depending on the specific
web-sys
calls used.
- Cross-Site Scripting (XSS): (Severity: High) - If
-
Impact:
- XSS: Risk significantly reduced when combined with other XSS mitigations.
- Other Vulnerabilities: Risk reduced depending on the specific vulnerability.
-
Currently Implemented:
- (This section needs a review of the codebase to identify specific
web-sys
usage and assess the current implementation.)
- (This section needs a review of the codebase to identify specific
-
Missing Implementation:
- (This section needs a review of the codebase to identify specific
web-sys
usage and determine where mitigation is missing.)
- (This section needs a review of the codebase to identify specific
Mitigation Strategy: Server Function Error Handling (Leptos-Specific Aspects)
Mitigation Strategy: Use Leptos's Result
and error handling mechanisms within server functions to prevent data leakage.
-
Description:
- Use
Result
: Structure all server functions to return aResult<T, E>
, whereT
is the success type andE
is a custom error type (often an enum). This is fundamental to Leptos server function design. - Custom Error Types: Define custom error enums that represent the different types of errors that can occur within your server functions. These enums should not contain sensitive data.
- Map Errors to HTTP Status Codes: Use Leptos's mechanisms (or your own logic) to map your custom error types to appropriate HTTP status codes (e.g., 400 Bad Request, 403 Forbidden, 500 Internal Server Error).
- Generic Error Messages (Client-Facing): When returning an error to the client, provide a generic, user-friendly error message that does not reveal any internal details. This message should be derived from your custom error type, but should not include any sensitive information.
- Detailed Logging (Server-Side): Log detailed error information on the server, including the specific error type, stack trace (if available), and relevant context. This is separate from the message sent to the client.
- Use
-
Threats Mitigated:
- Information Disclosure: (Severity: Medium) - Prevents leaking sensitive information through detailed error messages returned by server functions.
-
Impact:
- Information Disclosure: Risk reduced from Medium to Low.
-
Currently Implemented:
- Example: Server functions in
src/api/
useResult
and return custom error types.
- Example: Server functions in
-
Missing Implementation:
- Example: A consistent approach to error handling and mapping to HTTP status codes needs to be enforced across all server functions.