Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: security #57

Merged
merged 2 commits into from
Oct 10, 2024
Merged

docs: security #57

merged 2 commits into from
Oct 10, 2024

Conversation

fhur
Copy link
Collaborator

@fhur fhur commented Oct 10, 2024

SynthQL pull request template

Why

Motivation an context for the change.

What changed

Brief summary of the changes.

Important

Mention important points that require special attention or that might surprise
reviewers.

Summary by CodeRabbit

  • New Features

    • Enhanced security measures against SQL injection in query execution.
    • Introduced query middlewares for improved functionality, including logging and authentication.
    • Added detailed guidance on registered queries and query permissions.
  • Documentation

    • Updated security documentation with new sections on query handling, middleware, and access control.
    • Expanded explanations on restricting access to tables and columns, including practical examples.

Copy link

vercel bot commented Oct 10, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 10, 2024 10:42pm

Copy link
Contributor

coderabbitai bot commented Oct 10, 2024

Walkthrough

The changes introduced in this pull request include enhancements to the PgExecutor test suite with new test cases for SQL injection vulnerabilities, improvements to type safety in the SqlBuilder class, and comprehensive updates to the documentation regarding security practices in SynthQL. The documentation now includes sections on query middlewares, query permissions, and registered queries, providing clarity on access control and security measures.

Changes

File Path Change Summary
packages/backend/src/execution/executors/PgExecutor/PgExecutor.test.ts Added two new test cases for SQL injection vulnerabilities in limit and offset methods.
packages/backend/src/execution/executors/PgExecutor/queryBuilder/exp.ts Enhanced type safety in limit and offset methods to ensure parameters are numbers; minor formatting adjustments to error messages.
packages/docs/docs/200-security/index.md Updated security section with details on registered queries, whitelisting, and row-level access control for the orders table.
packages/docs/docs/200-security/query-middleware.md Introduced query middlewares, explained their usage, and provided an example of restrictOrdersByUser.
packages/docs/docs/200-security/query-permissions.md Overview of query permissions management, including the .requires() method and role inheritance.
packages/docs/docs/200-security/registered-queries.md Guide on registered queries, emphasizing security features and the mechanics of query registration.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Middleware
    participant QueryHandler
    participant Database

    User->>Middleware: Request to access orders
    Middleware->>QueryHandler: Check user permissions
    QueryHandler->>Database: Execute query for user orders
    Database-->>QueryHandler: Return user-specific orders
    QueryHandler-->>Middleware: Return filtered orders
    Middleware-->>User: Provide access to orders
Loading

🐇 "In the garden of code, we play,
With tests and docs, we pave the way.
Type safety blooms, vulnerabilities flee,
Security strong, as it should be!
Hop along, let queries flow,
In SynthQL's realm, we proudly grow!" 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (16)
packages/docs/docs/200-security/query-middleware.md (2)

7-37: LGTM: Well-structured example of adding a middleware

The code example effectively demonstrates how to create and use a query middleware for enhancing security. It shows a practical use case of restricting order queries based on user context.

Consider adding a brief comment explaining the purpose of the middleware<DB>() function for readers who might be unfamiliar with the API. For example:

// Create a new middleware for the database type DB
const restrictOrdersByUser = middleware<DB>()
    .from('orders')
    // ... rest of the code

39-43: LGTM: Clear explanation of middleware execution order

This section effectively explains the sequence of operations during query execution, which is crucial for understanding the security context in which middlewares operate.

There's a minor grammatical issue in the last sentence. Consider revising it for clarity:

- This ensures that the middleware can inject additional parameters to the query as it's now happening in a safe context.
+ This ensures that the middleware can inject additional parameters into the query, as it's now operating in a safe context.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~43-~43: Possible missing comma found.
Context: ...can inject additional parameters to the query as it's now happening in a safe context...

(AI_HYDRA_LEO_MISSING_COMMA)

packages/docs/docs/200-security/query-permissions.md (5)

1-36: Great introduction and explanation of defining permissions

The content in this section is clear, informative, and well-structured. The progression from simple string-based permissions to using TypeScript enums is logical and helps users understand the flexibility of the system.

There's a minor typo in the enum example:

- .requires(Roles.usersRead, Roles.usersWrite)
+ .requires(Permissions.usersRead, Permissions.usersWrite)

Also, consider adding a brief explanation of why using an enum for permissions is beneficial (e.g., type safety, autocomplete support, easier refactoring).

🧰 Tools
🪛 Markdownlint

5-5: Expected: 250; Actual: 257
Line length

(MD013, line-length)


38-54: Clear explanation of role inheritance

The section effectively explains how permissions accumulate when using sub-queries. The code example with users and pets is particularly illustrative.

To further enhance clarity:

Consider explicitly stating the total permissions required after the code example. For instance:

In this example, the user needs to have both the `users:read` and `pets:read` permissions to execute the query. The query engine will ensure that all required permissions are present before allowing execution.

This reinforces the concept of permission accumulation and sets up the next section about query context.


56-65: Good introduction to query context, with room for enhancement

The section effectively introduces the concept of passing a context object with permissions. To improve clarity and flow:

  1. Consider expanding on how the query engine uses the context. For example:

    The query engine uses this context to verify that the user has all the required permissions before executing the query.
  2. To smooth the transition to the next point, you could add:

    To ensure comprehensive permission checking:
  3. Then, the existing line about recursive traversal would follow naturally.

These additions would provide a more complete picture of how the query context is used in the permission checking process.


67-69: Expand on query registration for better clarity

The "Query registration" section touches on an important security aspect but could benefit from more detail and emphasis. Consider expanding this section as follows:

## Query registration

When a query is registered, it is registered along with its permissions. This is a crucial security feature that ensures:

1. The integrity of permission requirements: A malicious client cannot modify the ACL requirements of a query after registration.
2. Centralized permission management: Permissions are defined at the query level, making it easier to audit and maintain security policies.

This approach significantly enhances the overall security posture of your application by preventing unauthorized access and potential permission escalation attacks.

This expansion provides more context on why query registration is important and how it contributes to the security of the system.

🧰 Tools
🪛 Markdownlint

69-69: null
Files should end with a single newline character

(MD047, single-trailing-newline)


1-69: Minor formatting improvements

To adhere to common Markdown best practices:

  1. Consider breaking the long line (line 5) into shorter segments for improved readability, although the current length doesn't significantly impact comprehension.

  2. Add a newline character at the end of the file. This is a common best practice for text files and can prevent issues with some text processing tools.

These minor adjustments will improve the overall quality and consistency of the documentation.

🧰 Tools
🪛 Markdownlint

5-5: Expected: 250; Actual: 257
Line length

(MD013, line-length)


69-69: null
Files should end with a single newline character

(MD047, single-trailing-newline)

packages/docs/docs/200-security/index.md (1)

32-33: Excellent addition for improved documentation structure.

The new sentence provides a valuable link to more detailed information about registered queries, enhancing the document's overall structure and user navigation. This addition is well-placed and contributes to a more comprehensive understanding of SynthQL's security features.

Consider adding a brief description of what readers can expect to find in the linked document. For example:

You can read more about registered queries, including advanced usage and best practices, [here](/docs/security/registered-queries).

This would give readers a clearer idea of the content they'll find, potentially increasing the likelihood of them exploring the additional documentation.

packages/backend/src/execution/executors/PgExecutor/PgExecutor.test.ts (2)

55-62: Approve the 'limit sql injection' test with a minor suggestion.

The test case effectively checks for SQL injection vulnerability in the limit method. It correctly expects an error when a malicious string is passed as the limit.

Consider adding a test that actually executes the query to ensure that the SQL injection is prevented at runtime as well. This would provide an additional layer of security validation.


64-71: Approve the 'offset sql injection' test with suggestions for improvement.

The test case effectively checks for SQL injection vulnerability in the offset method, similar to the previous test for the limit method.

Consider the following improvements for both the 'limit' and 'offset' SQL injection tests:

  1. Combine the tests into a single parameterized test to reduce code duplication. This will make it easier to maintain and extend these tests in the future.

  2. Add tests that actually execute the queries to ensure runtime protection against SQL injection.

  3. Test with various malicious input patterns to cover a wider range of potential SQL injection attempts.

Here's an example of how you could refactor these tests:

import { describe, it, expect } from 'vitest';

describe('SQL injection prevention', () => {
  const maliciousInputs = [
    "1; DROP TABLE users; --",
    "1 OR 1=1",
    "(SELECT * FROM users)",
    "1' UNION SELECT username, password FROM users--"
  ];

  const methods = ['limit', 'offset'] as const;

  methods.forEach(method => {
    describe(`${method} method`, () => {
      maliciousInputs.forEach(input => {
        it(`prevents SQL injection: ${input}`, () => {
          expect(() => {
            const query = from('actor')
              [method](input as unknown as number)
              .all();
            executor.compile(query);
          }).toThrow(`Expected ${method} to be a number`);
        });

        it(`prevents SQL injection at runtime: ${input}`, async () => {
          await expect(async () => {
            const query = from('actor')
              [method](input as unknown as number)
              .all();
            await executor.execute(query, executeProps);
          }).rejects.toThrow();
        });
      });
    });
  });
});

This refactored version provides more comprehensive testing while reducing code duplication.

packages/docs/docs/200-security/registered-queries.md (4)

27-51: LGTM: Clear instructions with well-commented code example

This section provides clear instructions on how to register queries, including a helpful code example demonstrating query registration with parameters. The explanation of placeholder values is particularly useful.

Consider adding a brief note about the importance of using appropriate placeholder values that don't expose sensitive information, as these values might be visible in logs or error messages.


53-85: LGTM: Comprehensive explanation of conditional queries

This section effectively explains how to handle queries with conditional logic, providing a clear code example and demonstrating how to register multiple variants of a conditional query. The content addresses an important use case for complex queries.

Consider adding a brief note about the performance implications of registering multiple variants of a query, and whether there are any limits or best practices regarding the number of variants that should be registered.

🧰 Tools
🪛 LanguageTool

[style] ~76-~76: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...se types of queries correctly, you will need to register each variant of the query indi...

(REP_NEED_TO_VB)


87-123: LGTM: Comprehensive explanation of registered queries security

This section provides a thorough explanation of how registered queries work, covering query identification, checking, and parameter substitution. The included code example effectively illustrates the concept of parameter substitution.

Consider adding a brief note about any potential security implications of parameter substitution, such as how SynthQL prevents SQL injection attacks when substituting parameter values.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~93-~93: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...rtant to understand how they work. The high level idea is simple: 1. Identifying querie...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

🪛 Markdownlint

93-93: Expected: 0 or 2; Actual: 1
Trailing spaces

(MD009, no-trailing-spaces)


95-95: Expected: 2; Actual: 1
Spaces after list markers

(MD030, list-marker-space)


96-96: Expected: 2; Actual: 1
Spaces after list markers

(MD030, list-marker-space)


97-97: Expected: 2; Actual: 1
Spaces after list markers

(MD030, list-marker-space)


130-149: LGTM: Clear explanation of hash calculation with helpful examples

This section effectively explains the hash calculation process, providing useful examples of queries with the same and different hashes. The link to the hashQuery function implementation is valuable for developers who want to explore further.

Please address the following minor formatting issues:

  1. Add a hyphen to "high-level" on line 93 to form a compound adjective.
  2. Add "the" before "case" on line 124 for better readability.
  3. Add a comma after "So" on line 133.
  4. Consider rephrasing "very large" on line 132 to avoid the overused intensifier.
  5. Remove trailing spaces on lines 93, 126, and 148.

These small changes will improve the overall readability and consistency of the document.

🧰 Tools
🪛 LanguageTool

[style] ~132-~132: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...ngified query to avoid sending possibly very large JSON strings over the wire. Special car...

(EN_WEAK_ADJECTIVE)


[uncategorized] ~133-~133: A comma might be missing here.
Context: ...rizable are not hardcoded in the hash. So for example, the following two queries ...

(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)

🪛 Markdownlint

148-148: Expected: 0 or 2; Actual: 1
Trailing spaces

(MD009, no-trailing-spaces)


132-132: Expected: 250; Actual: 296
Line length

(MD013, line-length)

packages/backend/src/execution/executors/PgExecutor/queryBuilder/exp.ts (2)

355-358: LGTM: Enhanced type safety for limit parameter

The added type check ensures that the limit parameter is a number, which improves type safety and prevents potential runtime errors. This is a good practice.

Consider removing the Number() conversion in the SQL string since you've already ensured limit is a number:

- return this.add(`limit ${Number(limit)} `);
+ return this.add(`limit ${limit} `);

This minor change would slightly improve performance while maintaining type safety.


407-410: LGTM: Enhanced type safety for offset parameter

The added type check ensures that the offset parameter is a number, which improves type safety and prevents potential runtime errors. This change is consistent with the improvements made to the limit method and is a good practice.

Consider removing the Number() conversion in the SQL string since you've already ensured offset is a number:

- return this.add(`offset ${Number(offset)} `);
+ return this.add(`offset ${offset} `);

This minor change would slightly improve performance while maintaining type safety.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 5df8937 and ab4d25f.

📒 Files selected for processing (6)
  • packages/backend/src/execution/executors/PgExecutor/PgExecutor.test.ts (1 hunks)
  • packages/backend/src/execution/executors/PgExecutor/queryBuilder/exp.ts (3 hunks)
  • packages/docs/docs/200-security/index.md (1 hunks)
  • packages/docs/docs/200-security/query-middleware.md (1 hunks)
  • packages/docs/docs/200-security/query-permissions.md (1 hunks)
  • packages/docs/docs/200-security/registered-queries.md (1 hunks)
🧰 Additional context used
🪛 LanguageTool
packages/docs/docs/200-security/query-middleware.md

[uncategorized] ~43-~43: Possible missing comma found.
Context: ...can inject additional parameters to the query as it's now happening in a safe context...

(AI_HYDRA_LEO_MISSING_COMMA)

packages/docs/docs/200-security/registered-queries.md

[style] ~76-~76: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...se types of queries correctly, you will need to register each variant of the query indi...

(REP_NEED_TO_VB)


[uncategorized] ~93-~93: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...rtant to understand how they work. The high level idea is simple: 1. Identifying querie...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[uncategorized] ~124-~124: You might be missing the article “the” here.
Context: ...UserById(0)) ``` ### What happens in case of a hash collision? If you try to reg...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[style] ~128-~128: You have already used ‘trying to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ...ery B, it would be equivalent to simply trying to execute query B. ### How is the hash c...

(REP_TRY)


[style] ~132-~132: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...ngified query to avoid sending possibly very large JSON strings over the wire. Special car...

(EN_WEAK_ADJECTIVE)


[uncategorized] ~133-~133: A comma might be missing here.
Context: ...rizable are not hardcoded in the hash. So for example, the following two queries ...

(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)

🪛 Markdownlint
packages/docs/docs/200-security/query-permissions.md

5-5: Expected: 250; Actual: 257
Line length

(MD013, line-length)


69-69: null
Files should end with a single newline character

(MD047, single-trailing-newline)

packages/docs/docs/200-security/registered-queries.md

93-93: Expected: 0 or 2; Actual: 1
Trailing spaces

(MD009, no-trailing-spaces)


126-126: Expected: 0 or 2; Actual: 1
Trailing spaces

(MD009, no-trailing-spaces)


148-148: Expected: 0 or 2; Actual: 1
Trailing spaces

(MD009, no-trailing-spaces)


132-132: Expected: 250; Actual: 296
Line length

(MD013, line-length)


95-95: Expected: 2; Actual: 1
Spaces after list markers

(MD030, list-marker-space)


96-96: Expected: 2; Actual: 1
Spaces after list markers

(MD030, list-marker-space)


97-97: Expected: 2; Actual: 1
Spaces after list markers

(MD030, list-marker-space)

🔇 Additional comments (9)
packages/docs/docs/200-security/query-middleware.md (1)

1-5: LGTM: Clear and concise introduction to query middlewares

The introduction effectively explains the concept of query middlewares and their relevance to security. It provides a good foundation for the rest of the document.

packages/docs/docs/200-security/query-permissions.md (1)

1-69: Excellent documentation on query permissions

This documentation provides a comprehensive and well-structured overview of query permissions in SynthQL. The content effectively communicates key concepts, with a logical progression from basic to more advanced topics. The inclusion of relevant code examples enhances understanding.

The minor suggestions provided in the review comments will further improve clarity, completeness, and adherence to documentation best practices. Overall, this is a high-quality addition to the SynthQL documentation that will greatly assist users in implementing and understanding the query permission system.

🧰 Tools
🪛 Markdownlint

5-5: Expected: 250; Actual: 257
Line length

(MD013, line-length)


69-69: null
Files should end with a single newline character

(MD047, single-trailing-newline)

packages/docs/docs/200-security/index.md (1)

Line range hint 1-33: Well-structured and comprehensive security documentation.

The document provides a clear and thorough overview of SynthQL's security features. The logical structure, combined with relevant examples and explanations, makes it easy for users to understand and implement security measures in their projects.

Key strengths:

  1. Clear explanations of whitelisting queries, access restrictions, and row-level security.
  2. Practical code examples that demonstrate real-world usage.
  3. Logical flow from basic concepts to more advanced security implementations.

The document successfully achieves its goal of explaining SynthQL's security mechanisms and guiding users in implementing robust authorization logic.

packages/backend/src/execution/executors/PgExecutor/PgExecutor.test.ts (1)

Line range hint 1-72: Overall assessment of the test file.

The test file for PgExecutor is well-structured and covers a good range of scenarios, including:

  1. Query compilation
  2. Query execution
  3. Different table queries (film, actor)
  4. Included columns and nested queries
  5. SQL injection prevention (newly added)

The addition of SQL injection tests enhances the security coverage of the test suite. Consider implementing the suggested improvements to make these tests even more robust and maintainable.

packages/docs/docs/200-security/registered-queries.md (3)

1-18: LGTM: Clear introduction and illustrative example

The introduction effectively communicates the core security principle of SynthQL, and the code example provides a clear demonstration of how to register and execute a query. The use of TypeScript is consistent with the project's language.


20-25: LGTM: Clear explanation of registered queries concept

This section effectively explains the rationale behind registered queries and draws a helpful parallel with traditional REST APIs. The explanation is concise and easy to understand.


1-149: Overall: Excellent documentation on registered queries

This document provides a comprehensive and well-structured explanation of registered queries in SynthQL. It effectively covers the concept, implementation details, and security considerations. The use of code examples and clear explanations makes it accessible to developers of various skill levels.

The minor issues identified in the review (such as typos and formatting) do not detract significantly from the overall quality of the document. Once these are addressed, this will serve as an excellent resource for developers working with SynthQL.

Great job on creating this thorough and informative documentation!

🧰 Tools
🪛 LanguageTool

[style] ~76-~76: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...se types of queries correctly, you will need to register each variant of the query indi...

(REP_NEED_TO_VB)


[uncategorized] ~93-~93: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...rtant to understand how they work. The high level idea is simple: 1. Identifying querie...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[uncategorized] ~124-~124: You might be missing the article “the” here.
Context: ...UserById(0)) ``` ### What happens in case of a hash collision? If you try to reg...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)


[style] ~128-~128: You have already used ‘trying to’ in nearby sentences. Consider using one of the replacements to let your writing stand out.
Context: ...ery B, it would be equivalent to simply trying to execute query B. ### How is the hash c...

(REP_TRY)


[style] ~132-~132: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ...ngified query to avoid sending possibly very large JSON strings over the wire. Special car...

(EN_WEAK_ADJECTIVE)


[uncategorized] ~133-~133: A comma might be missing here.
Context: ...rizable are not hardcoded in the hash. So for example, the following two queries ...

(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)

🪛 Markdownlint

93-93: Expected: 0 or 2; Actual: 1
Trailing spaces

(MD009, no-trailing-spaces)


126-126: Expected: 0 or 2; Actual: 1
Trailing spaces

(MD009, no-trailing-spaces)


148-148: Expected: 0 or 2; Actual: 1
Trailing spaces

(MD009, no-trailing-spaces)


132-132: Expected: 250; Actual: 296
Line length

(MD013, line-length)


95-95: Expected: 2; Actual: 1
Spaces after list markers

(MD030, list-marker-space)


96-96: Expected: 2; Actual: 1
Spaces after list markers

(MD030, list-marker-space)


97-97: Expected: 2; Actual: 1
Spaces after list markers

(MD030, list-marker-space)

packages/backend/src/execution/executors/PgExecutor/queryBuilder/exp.ts (2)

35-35: LGTM: Improved error message formatting

The change enhances the readability of the error message by using template literals for better string interpolation. This is a good practice for creating more informative error messages.


Line range hint 1-510: Summary: Improved type safety in SqlBuilder class

The changes in this file focus on enhancing type safety for the limit and offset methods in the SqlBuilder class. These improvements help prevent potential runtime errors by ensuring that the parameters are of the correct type. The changes are consistent and align with good programming practices, contributing to the overall robustness of the code.

Comment on lines +1 to +44
# Query middlewares

Query middlewares are functions that are executed before a query is executed. They can be used to add additional functionality to the query, such as logging, caching, or authentication.

In the context of security, query middlewares can be used to add additional checks on every query, or add additional filters to the query to limit the result set.

## Adding a middleware

You can add a middleware to the query engine using the `.use()` method.

```ts
import { DB } from './db';
import { QueryEngine, mapQuery } from '@synthql/backend';
import { orders } from './queries';

const restrictOrdersByUser = middleware<DB>()
.from('orders')
.mapQuery((query, context) => {
const userId = context.user.id;
return {
context,
query: {
...query,
// transforms the `where` to ensure that only orders can be read from the
// current user.
where: {
...query.where,
user_id: userId,
},
},
};
});

const queryEngine = new QueryEngine<DB>({
middlewares: [restrictOrdersByUser],
});
```

## When are middlewares executed?

When a query is executed, the ID check is performed first, and then the parameters are substituted. Then the middleware is executed.

This ensures that the middleware can inject additional parameters to the query as it's now happening in a safe context.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Suggestion: Add a "Best Practices" section

The document provides an excellent introduction to query middlewares and their security implications. To further enhance its value, consider adding a "Best Practices" section at the end. This section could include:

  1. Guidelines for designing secure middlewares
  2. Common pitfalls to avoid
  3. Recommendations for testing middlewares
  4. Examples of how middlewares can be combined for comprehensive security measures

Would you like assistance in drafting this additional section?

🧰 Tools
🪛 LanguageTool

[uncategorized] ~43-~43: Possible missing comma found.
Context: ...can inject additional parameters to the query as it's now happening in a safe context...

(AI_HYDRA_LEO_MISSING_COMMA)

packages/docs/docs/200-security/registered-queries.md Outdated Show resolved Hide resolved
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@fhur fhur merged commit 10826ad into master Oct 10, 2024
4 checks passed
@fhur fhur deleted the blog/security branch October 10, 2024 22:43
This was referenced Oct 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant