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

Enable setting the port and allowPrivateAddress through environment vars #53

Merged
merged 2 commits into from
Nov 1, 2024

Conversation

HelgeKrueger
Copy link
Contributor

@HelgeKrueger HelgeKrueger commented Oct 27, 2024

By setting

  BEHIND_PROXY: "true"
  HOLLO_PORT: 80
  ALLOW_PRIVATE_ADDRESS: "true"

one allows private addresses and runs on port 80.

Summary by CodeRabbit

  • New Features

    • Introduced a new configuration option for handling private addresses in the federation.
    • Added a port configuration option to enhance server functionality.
  • Documentation

    • Updated .env.sample to include the new LISTEN_PORT and ALLOW_PRIVATE_ADDRESS variables for server configuration.
    • Enhanced documentation across multiple languages to clarify new environment variables and their implications.

Copy link
Contributor

coderabbitai bot commented Oct 27, 2024

Warning

Rate limit exceeded

@dahlia has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 23 minutes and 18 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 06da44d and 4fd03b9.

Walkthrough

The changes introduce a new property allowPrivateAddress in src/federation/index.ts, determined by the environment variable ALLOW_PRIVATE_ADDRESS. In src/index.tsx, a constant LISTEN_PORT is added, retrieving its value from the environment variable LISTEN_PORT, defaulting to 3000. This constant is incorporated into the export statement, modifying the exported object to include both the fetch method and the new port property when BEHIND_PROXY is true. The .env.sample file is also updated to include these new environment variables.

Changes

File Change Summary
src/federation/index.ts Added allowPrivateAddress to createFederation based on ALLOW_PRIVATE_ADDRESS environment variable.
src/index.tsx Introduced LISTEN_PORT constant from LISTEN_PORT environment variable, defaulting to 3000. Modified export to include fetch and port properties.
.env.sample Added new environment variables LISTEN_PORT=3000 and ALLOW_PRIVATE_ADDRESS=false with comments.
CHANGES.md Documented the addition of LISTEN_PORT and ALLOW_PRIVATE_ADDRESS environment variables.
docs/src/content/docs/install/env.mdx Updated documentation to include LISTEN_PORT and ALLOW_PRIVATE_ADDRESS with descriptions and defaults.
docs/src/content/docs/ja/install/env.mdx Updated Japanese documentation to include LISTEN_PORT and ALLOW_PRIVATE_ADDRESS with descriptions.
docs/src/content/docs/ko/install/env.mdx Updated Korean documentation to include LISTEN_PORT and ALLOW_PRIVATE_ADDRESS with descriptions.
docs/src/content/docs/zh-cn/install/env.mdx Updated Chinese documentation to include LISTEN_PORT and ALLOW_PRIVATE_ADDRESS with descriptions.

Possibly related PRs

  • docs: Simplified Chinese translation #31: The changes in the main PR introduce the ALLOW_PRIVATE_ADDRESS environment variable, which is also documented in the retrieved PR that adds a Simplified Chinese translation for the documentation, ensuring that users can understand the new configuration options in their language.

Poem

In the code where rabbits play,
New properties hop in today!
A port to fetch, a flag to see,
Private addresses, oh so free!
With each change, we leap and cheer,
For better code is finally here! 🐇✨


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 (1)
src/index.tsx (1)

25-25: Document the conditional export behavior and consider type safety.

The export behavior changes based on BEHIND_PROXY, which could lead to type-related issues in consuming code.

Consider adding JSDoc documentation and type definitions:

/** 
 * @returns When BEHIND_PROXY is true, returns an object with:
 *          - fetch: Proxy-aware fetch function
 *          - port: Configured server port
 * @returns When BEHIND_PROXY is false, returns the Hono app instance
 */
export default BEHIND_PROXY 
  ? { fetch: behindProxy(app.fetch.bind(app)), port: HOLLO_PORT } 
  : app;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 876c624 and fd41cc1.

📒 Files selected for processing (2)
  • src/federation/index.ts (1 hunks)
  • src/index.tsx (1 hunks)
🧰 Additional context used
🪛 Biome
src/federation/index.ts

[error] 112-112: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

src/index.tsx

[error] 23-23: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

🔇 Additional comments (2)
src/index.tsx (2)

25-25: Verify the impact of conditional exports on TypeScript consumers.

The conditional export pattern might affect type inference in consuming TypeScript code.

Let's check for potential type-related issues:

✅ Verification successful

No type-related issues found with conditional exports

The conditional export in src/index.tsx is safe from a TypeScript perspective because:

  1. The TypeScript configuration is properly set up with strict type checking
  2. Both branches of the conditional return compatible types (either the full app or an object with a subset of app's properties)
  3. No direct type imports or dependencies on this module were found in the codebase
  4. The exported types are properly handled by TypeScript's type system which can deal with conditional types and unions
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for type-related imports of this module
# Expected: Find places where the exported type might need to be handled conditionally

# Search for imports of this module
rg -l "from ['\"].*src/index['\"]"

# Search for type definitions related to this module
fd -e d.ts -x cat {} \; 

Length of output: 425


Script:

#!/bin/bash
# Let's check for type definitions and usage patterns more thoroughly

# Check for type declarations or interfaces in the index file
ast-grep --pattern 'type $_ = $_'
ast-grep --pattern 'interface $_ $_'

# Look for direct imports of the index file
rg "from ['\"]\.\.?/index['\"]" -A 2

# Check if there are any TypeScript configuration files that might affect type inference
fd tsconfig.json -x cat {}

Length of output: 6459


Line range hint 1-25: Verify ALLOW_PRIVATE_ADDRESS implementation.

The PR objectives mention ALLOW_PRIVATE_ADDRESS configuration, but it's not visible in this file.

Let's verify the implementation:

✅ Verification successful

ALLOW_PRIVATE_ADDRESS is properly implemented

The environment variable is correctly implemented in the federation configuration at src/federation/index.ts. It's used to configure the allowPrivateAddress option when creating the federation instance:

export const federation = createFederation<void>({
  kv,
  queue,
  allowPrivateAddress: process.env["ALLOW_PRIVATE_ADDRESS"] === "true"
});
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify ALLOW_PRIVATE_ADDRESS implementation
# Expected: Find where ALLOW_PRIVATE_ADDRESS is used

# Search for ALLOW_PRIVATE_ADDRESS usage
rg "ALLOW_PRIVATE_ADDRESS"

# Search for federation configuration
ast-grep --pattern 'federation($_, $_)'

Length of output: 425


Script:

#!/bin/bash
# Let's check the federation configuration in src/federation/index.ts
cat src/federation/index.ts

# Also check if there are any other files that might be using allowPrivateAddress
rg "allowPrivateAddress"

Length of output: 30932

🧰 Tools
🪛 Biome

[error] 23-23: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

src/index.tsx Outdated
@@ -20,5 +20,6 @@ app.get("/nodeinfo/2.0", (c) => c.redirect("/nodeinfo/2.1"));

// biome-ignore lint/complexity/useLiteralKeys: tsc complains about this (TS4111)
const BEHIND_PROXY = process.env["BEHIND_PROXY"] === "true";
const HOLLO_PORT = process.env["HOLLO_PORT"] ?? 3000;
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 27, 2024

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add type safety and validation for HOLLO_PORT.

The port value should be properly typed and validated to ensure it's a valid port number.

Apply this diff to add proper type conversion and validation:

-const HOLLO_PORT = process.env["HOLLO_PORT"] ?? 3000;
+const HOLLO_PORT = (() => {
+  const port = parseInt(process.env["HOLLO_PORT"] ?? "3000", 10);
+  if (isNaN(port) || port < 0 || port > 65535) {
+    throw new Error("HOLLO_PORT must be a valid port number between 0 and 65535");
+  }
+  return port;
+})();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const HOLLO_PORT = process.env["HOLLO_PORT"] ?? 3000;
const HOLLO_PORT = (() => {
const port = parseInt(process.env["HOLLO_PORT"] ?? "3000", 10);
if (isNaN(port) || port < 0 || port > 65535) {
throw new Error("HOLLO_PORT must be a valid port number between 0 and 65535");
}
return port;
})();
🧰 Tools
🪛 Biome

[error] 23-23: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

Copy link
Owner

Choose a reason for hiding this comment

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

Environment variables are untyped and all strings. It should be parsed into a number using Number.parseInt() function.

Suggested change
const HOLLO_PORT = process.env["HOLLO_PORT"] ?? 3000;
const HOLLO_PORT = Number.parseInt(process.env["HOLLO_PORT"] ?? "3000");

Copy link
Owner

Choose a reason for hiding this comment

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

By the way, as the existing configurations do not have HOLLO_ prefix, it should be just PORT or LISTEN_PORT for consistency.

Copy link
Contributor

Choose a reason for hiding this comment

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

@dahlia, understood. I'll update the environment variable to PORT or LISTEN_PORT for consistency with the existing configurations.

(^・ω・^ )
Thanks for the clarification!


✏️ Learnings added
Learnt from: dahlia
PR: dahlia/hollo#53
File: src/index.tsx:23-23
Timestamp: 2024-10-27T15:51:16.533Z
Learning: In this codebase, environment variables do not have the `HOLLO_` prefix. Future environment variables should be named consistently without the `HOLLO_` prefix, e.g., use `PORT` or `LISTEN_PORT` instead of `HOLLO_PORT`.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Copy link
Contributor

Choose a reason for hiding this comment

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

@dahlia, thank you for the clarification. You're absolutely right that environment variables are untyped strings and should be parsed using Number.parseInt() when expecting a number. I've noted this information for future reviews.

(_/)
(•_•)💡
/ \


✏️ Learnings added
Learnt from: dahlia
PR: dahlia/hollo#53
File: src/index.tsx:23-23
Timestamp: 2024-10-27T15:51:24.473Z
Learning: In JavaScript, environment variables are untyped strings and should be parsed using `Number.parseInt()` when expecting numeric values.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@@ -109,6 +109,7 @@ if (getRedisUrl() == null) {
export const federation = createFederation<void>({
kv,
queue,
allowPrivateAddress: process.env["ALLOW_PRIVATE_ADDRESS"] === "true"
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 27, 2024

Choose a reason for hiding this comment

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

💡 Codebase verification

Document security implications and add environment variable configuration

The environment variable ALLOW_PRIVATE_ADDRESS is currently undocumented. Please:

  1. Add documentation for ALLOW_PRIVATE_ADDRESS in appropriate configuration files (e.g., .env.example, README.md).
  2. Add the following security notice above the configuration:
    // SECURITY: Enabling private addresses allows federation with internal network endpoints.
    // Only enable this in trusted environments where internal federation is required.
  3. Consider simplifying the computed expression to process.env.ALLOW_PRIVATE_ADDRESS === "true".
🔗 Analysis chain

Consider security implications and improve code style.

While the implementation aligns with the PR objectives, consider the following improvements:

  1. The computed expression can be simplified.
  2. Adding private address support has security implications that should be documented.

Apply this diff to simplify the computed expression:

-  allowPrivateAddress: process.env["ALLOW_PRIVATE_ADDRESS"] === "true"
+  allowPrivateAddress: process.env.ALLOW_PRIVATE_ADDRESS === "true"

Consider adding a comment documenting the security implications of enabling private addresses, such as:

// SECURITY: Enabling private addresses allows federation with internal network endpoints.
// Only enable this in trusted environments where internal federation is required.

Let's verify if this environment variable is documented:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if ALLOW_PRIVATE_ADDRESS is documented in README or similar files
fd -e md -e txt -e env.example | xargs rg "ALLOW_PRIVATE_ADDRESS"

Length of output: 65


Script:

#!/bin/bash
# Let's try a broader search for any documentation or configuration files
fd -t f | rg -l ".(md|txt|env|config|json|ya?ml)$" | xargs rg -i "private.*address|allow.*private"

# Also search for environment variable usage in the codebase
rg "ALLOW_PRIVATE_ADDRESS" -A 2 -B 2

Length of output: 396

🧰 Tools
🪛 Biome

[error] 112-112: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

Copy link
Owner

Choose a reason for hiding this comment

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

It's turned off to prevent SSRF attacks. Why do you need this option?

Copy link
Contributor

Choose a reason for hiding this comment

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

@dahlia, thank you for clarifying that ALLOW_PRIVATE_ADDRESS is turned off by default to prevent SSRF attacks. I've noted this information for future reviews.

(•̀o•́)ง


✏️ Learnings added
Learnt from: dahlia
PR: dahlia/hollo#53
File: src/federation/index.ts:112-112
Timestamp: 2024-10-27T15:51:25.648Z
Learning: In the Hollo application, `ALLOW_PRIVATE_ADDRESS` is turned off by default to prevent SSRF attacks.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's turned off to prevent SSRF attacks. Why do you need this option?

To build https://data.funfedi.dev/, I run all the Fediverse applications in a local docker network. It uses ips starting with 178.3.x.x by default, I think. These fall into the private addresses. So I need a way to disable this.

I'm not sure if I know how to check for an IP range here. Is it fine if I just add the variable to .env.sample?

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Owner

Choose a reason for hiding this comment

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

Okay, fair enough. Please add it to the .env.sample.

Copy link
Owner

@dahlia dahlia left a comment

Choose a reason for hiding this comment

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

When a new environment variable is introduced, it should be added to the .env.sample file as well.

@@ -109,6 +109,7 @@ if (getRedisUrl() == null) {
export const federation = createFederation<void>({
kv,
queue,
allowPrivateAddress: process.env["ALLOW_PRIVATE_ADDRESS"] === "true"
Copy link
Owner

Choose a reason for hiding this comment

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

It's turned off to prevent SSRF attacks. Why do you need this option?

src/index.tsx Outdated
@@ -20,5 +20,6 @@ app.get("/nodeinfo/2.0", (c) => c.redirect("/nodeinfo/2.1"));

// biome-ignore lint/complexity/useLiteralKeys: tsc complains about this (TS4111)
const BEHIND_PROXY = process.env["BEHIND_PROXY"] === "true";
const HOLLO_PORT = process.env["HOLLO_PORT"] ?? 3000;
Copy link
Owner

Choose a reason for hiding this comment

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

Environment variables are untyped and all strings. It should be parsed into a number using Number.parseInt() function.

Suggested change
const HOLLO_PORT = process.env["HOLLO_PORT"] ?? 3000;
const HOLLO_PORT = Number.parseInt(process.env["HOLLO_PORT"] ?? "3000");

src/index.tsx Outdated
@@ -20,5 +20,6 @@ app.get("/nodeinfo/2.0", (c) => c.redirect("/nodeinfo/2.1"));

// biome-ignore lint/complexity/useLiteralKeys: tsc complains about this (TS4111)
const BEHIND_PROXY = process.env["BEHIND_PROXY"] === "true";
const HOLLO_PORT = process.env["HOLLO_PORT"] ?? 3000;
Copy link
Owner

Choose a reason for hiding this comment

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

By the way, as the existing configurations do not have HOLLO_ prefix, it should be just PORT or LISTEN_PORT for consistency.

@ThisIsMissEm
Copy link
Contributor

An option like this does make sense, however, it should be a comma separated string of private IP addresses or ranges not to enforce checking on, not a simple Boolean value.

e.g., https://docs.joinmastodon.org/admin/config/#allowed_private_addresses

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: 4

🧹 Outside diff range and nitpick comments (1)
src/federation/index.ts (1)

112-112: Simplify the computed expression

The computed expression can be simplified by using dot notation instead of string literal notation for accessing environment variables.

-  allowPrivateAddress: process.env["ALLOW_PRIVATE_ADDRESS"] === "true"
+  allowPrivateAddress: process.env.ALLOW_PRIVATE_ADDRESS === "true"
🧰 Tools
🪛 Biome

[error] 112-112: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between fd41cc1 and 246b66f.

📒 Files selected for processing (3)
  • .env.sample (1 hunks)
  • src/federation/index.ts (1 hunks)
  • src/index.tsx (1 hunks)
🧰 Additional context used
📓 Learnings (2)
src/federation/index.ts (1)
Learnt from: dahlia
PR: dahlia/hollo#53
File: src/federation/index.ts:112-112
Timestamp: 2024-10-27T15:51:25.872Z
Learning: In the Hollo application, `ALLOW_PRIVATE_ADDRESS` is turned off by default to prevent SSRF attacks.
src/index.tsx (1)
Learnt from: dahlia
PR: dahlia/hollo#53
File: src/index.tsx:23-23
Timestamp: 2024-10-27T15:51:16.761Z
Learning: In this codebase, environment variables do not have the `HOLLO_` prefix. Future environment variables should be named consistently without the `HOLLO_` prefix, e.g., use `PORT` or `LISTEN_PORT` instead of `HOLLO_PORT`.
🪛 Biome
src/federation/index.ts

[error] 112-112: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

src/index.tsx

[error] 23-23: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

🔇 Additional comments (1)
src/federation/index.ts (1)

112-112: Verify the security implications of enabling private addresses

The code allows federation with private addresses when ALLOW_PRIVATE_ADDRESS is set to "true". This configuration should be used with caution as it could potentially lead to Server-Side Request Forgery (SSRF) attacks.

Let's check if there are any security-related comments or documentation:

✅ Verification successful

Security measures are in place for private address handling

The codebase has proper security measures in place:

  • Uses @fedify/fedify library (v1.1.2) for federation implementation
  • Includes ssrfcheck (v1.1.1) as a dependency, which is a dedicated SSRF prevention library
  • The allowPrivateAddress flag is part of the createFederation configuration, indicating it's a controlled feature of the federation library

The security concern is adequately addressed through these built-in protections, making this a safe and intentional configuration option.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for security documentation related to private addresses
echo "Searching for security documentation..."
rg -i "private.*address|ssrf|security" -g "*.{md,txt}"

# Check if the environment variable is documented
echo "Checking environment variable documentation..."
fd -e md -e env.example | xargs rg "ALLOW_PRIVATE_ADDRESS"

Length of output: 307


Script:

#!/bin/bash
# Let's check the context around the usage of ALLOW_PRIVATE_ADDRESS
echo "Checking usage context of ALLOW_PRIVATE_ADDRESS..."
rg -B 5 -A 5 "ALLOW_PRIVATE_ADDRESS"

# Let's also check for any validation or security checks around private addresses
echo "Checking for private address validation..."
ast-grep --pattern 'isPrivateAddress($$$)'

# Look for any network or URL validation related code
echo "Checking for URL/network validation..."
rg -B 3 -A 3 "isPrivate|privateAddress|validateUrl|checkUrl"

Length of output: 985


Script:

#!/bin/bash
# Let's examine the federation module implementation to understand how this flag is used
echo "Checking federation module implementation..."
rg -B 10 -A 10 "createFederation" 

# Let's also check if there are any tests related to private address handling
echo "Checking related tests..."
fd -e test.ts -e spec.ts | xargs rg -l "ALLOW_PRIVATE_ADDRESS|privateAddress"

# Check the dependencies to see if there's a federation library being used
echo "Checking package.json for federation-related dependencies..."
fd package.json | xargs cat

Length of output: 4814

🧰 Tools
🪛 Biome

[error] 112-112: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

src/index.tsx Outdated
@@ -20,5 +20,6 @@ app.get("/nodeinfo/2.0", (c) => c.redirect("/nodeinfo/2.1"));

// biome-ignore lint/complexity/useLiteralKeys: tsc complains about this (TS4111)
const BEHIND_PROXY = process.env["BEHIND_PROXY"] === "true";
const HOLLO_PORT = Number.parseInt(process.env["LISTEN_PORT"] ?? 3000, 10);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Enhance port configuration robustness and naming.

  1. The environment variable name should be consistent with existing conventions (avoid HOLLO_ prefix).
  2. Add validation for port number range and proper error handling.

Apply this diff to address these concerns:

-const HOLLO_PORT = Number.parseInt(process.env["LISTEN_PORT"] ?? 3000, 10);
+const port = (() => {
+  const rawPort = Number.parseInt(process.env["LISTEN_PORT"] ?? "3000", 10);
+  if (isNaN(rawPort) || rawPort < 0 || rawPort > 65535) {
+    throw new Error("LISTEN_PORT must be a valid port number between 0 and 65535");
+  }
+  return rawPort;
+})();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const HOLLO_PORT = Number.parseInt(process.env["LISTEN_PORT"] ?? 3000, 10);
const port = (() => {
const rawPort = Number.parseInt(process.env["LISTEN_PORT"] ?? "3000", 10);
if (isNaN(rawPort) || rawPort < 0 || rawPort > 65535) {
throw new Error("LISTEN_PORT must be a valid port number between 0 and 65535");
}
return rawPort;
})();
🧰 Tools
🪛 Biome

[error] 23-23: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

@@ -109,6 +109,7 @@ if (getRedisUrl() == null) {
export const federation = createFederation<void>({
kv,
queue,
allowPrivateAddress: process.env["ALLOW_PRIVATE_ADDRESS"] === "true"
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 27, 2024

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider implementing IP range configuration for private addresses

Based on the PR feedback, instead of a simple boolean flag, consider implementing a more flexible configuration that accepts comma-separated IP ranges. This approach:

  • Provides granular control over allowed private addresses
  • Aligns with Mastodon's implementation
  • Reduces security risks by limiting the scope of allowed private addresses

Here's a suggested implementation:

-  allowPrivateAddress: process.env["ALLOW_PRIVATE_ADDRESS"] === "true"
+  allowPrivateAddresses: process.env.ALLOW_PRIVATE_ADDRESSES?.split(",").map(range => range.trim()).filter(Boolean) ?? []

Usage example in .env:

ALLOW_PRIVATE_ADDRESSES=192.168.1.0/24,10.0.0.0/8

Committable suggestion was skipped due to low confidence.

🧰 Tools
🪛 Biome

[error] 112-112: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

Copy link
Contributor

Choose a reason for hiding this comment

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

@HelgeKrueger this above would be the better implementation ^, but it may be required to make changes in Fedify first.

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@HelgeKrueger
Copy link
Contributor Author

Added change to .env.sample

I also created dahlia/fedify#157

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: 4

🧹 Outside diff range and nitpick comments (1)
src/federation/index.ts (1)

112-112: Simplify environment variable access.

The environment variable access can be simplified by using dot notation.

-  allowPrivateAddress: process.env["ALLOW_PRIVATE_ADDRESS"] === "true"
+  allowPrivateAddress: process.env.ALLOW_PRIVATE_ADDRESS === "true"
🧰 Tools
🪛 Biome

[error] 112-112: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 246b66f and 74f0911.

📒 Files selected for processing (3)
  • .env.sample (1 hunks)
  • src/federation/index.ts (1 hunks)
  • src/index.tsx (1 hunks)
🧰 Additional context used
📓 Learnings (2)
src/federation/index.ts (1)
Learnt from: dahlia
PR: dahlia/hollo#53
File: src/federation/index.ts:112-112
Timestamp: 2024-10-27T15:51:25.872Z
Learning: In the Hollo application, `ALLOW_PRIVATE_ADDRESS` is turned off by default to prevent SSRF attacks.
src/index.tsx (1)
Learnt from: dahlia
PR: dahlia/hollo#53
File: src/index.tsx:23-23
Timestamp: 2024-10-27T15:51:16.761Z
Learning: In this codebase, environment variables do not have the `HOLLO_` prefix. Future environment variables should be named consistently without the `HOLLO_` prefix, e.g., use `PORT` or `LISTEN_PORT` instead of `HOLLO_PORT`.
🪛 Biome
src/federation/index.ts

[error] 112-112: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

src/index.tsx

[error] 23-23: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

🔇 Additional comments (3)
src/index.tsx (3)

25-25: LGTM with previous suggestions.

The export logic is correct, implementing the proxy configuration as intended. Please refer to the previous review comment about adding type declarations for improved type safety.


23-25: Verify environment variable documentation.

Let's ensure the new environment variable is properly documented.

✅ Verification successful

Let me check the content of .env.sample to verify if LISTEN_PORT is properly documented there.


Environment variable is properly documented

The LISTEN_PORT environment variable is well documented in .env.sample with a clear description indicating it's used as the server port when BEHIND_PROXY=true. The default value of 3000 matches the code implementation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if LISTEN_PORT is documented in relevant files
echo "Checking documentation for LISTEN_PORT configuration:"
rg -l "LISTEN_PORT" --type md
rg -l "LISTEN_PORT" -g ".env*"

Length of output: 189


Script:

#!/bin/bash
# Check the documentation of LISTEN_PORT in .env.sample
echo "Content of .env.sample related to LISTEN_PORT:"
rg "LISTEN_PORT" .env.sample -C 2

Length of output: 373

🧰 Tools
🪛 Biome

[error] 23-23: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)


23-23: ⚠️ Potential issue

Improve port configuration implementation.

The current implementation has a few issues:

  1. The variable name uses HOLLO_ prefix which is inconsistent with codebase conventions
  2. The default value should be a string when using with ?? operator since environment variables are strings

Apply this diff to address these concerns:

-const HOLLO_PORT = Number.parseInt(process.env["LISTEN_PORT"] ?? 3000, 10);
+const port = Number.parseInt(process.env["LISTEN_PORT"] ?? "3000", 10);

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome

[error] 23-23: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

.env.sample Show resolved Hide resolved
.env.sample Outdated Show resolved Hide resolved
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: 5

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 74f0911 and 2a2249c.

📒 Files selected for processing (3)
  • .env.sample (1 hunks)
  • src/federation/index.ts (1 hunks)
  • src/index.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .env.sample
🧰 Additional context used
📓 Learnings (1)
src/federation/index.ts (1)
Learnt from: dahlia
PR: dahlia/hollo#53
File: src/federation/index.ts:112-112
Timestamp: 2024-10-27T15:51:25.872Z
Learning: In the Hollo application, `ALLOW_PRIVATE_ADDRESS` is turned off by default to prevent SSRF attacks.
🪛 Biome
src/federation/index.ts

[error] 112-112: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

src/index.tsx

[error] 23-23: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

src/index.tsx Outdated

export default BEHIND_PROXY ? { fetch: behindProxy(app.fetch.bind(app)) } : app;
export default BEHIND_PROXY ? { fetch: behindProxy(app.fetch.bind(app)), port: HOLLO_PORT } : app;
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

Add type declarations for improved type safety.

The conditional export logic correctly exposes the port configuration when behind a proxy. However, adding explicit type declarations would improve type safety and maintainability.

Consider adding type declarations:

type AppExport = {
  fetch: typeof app.fetch;
  port?: number;
};

export default BEHIND_PROXY 
  ? { fetch: behindProxy(app.fetch.bind(app)), port: listenPort } as AppExport 
  : app;

src/index.tsx Outdated Show resolved Hide resolved
@@ -109,6 +109,7 @@ if (getRedisUrl() == null) {
export const federation = createFederation<void>({
kv,
queue,
allowPrivateAddress: process.env["ALLOW_PRIVATE_ADDRESS"] === "true"
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

Consider implementing IP range configuration.

Based on the PR feedback from ThisIsMissEm, consider implementing a more granular approach that accepts comma-separated IP ranges instead of a boolean flag. This would provide better control over which private addresses are allowed.

Example configuration:

ALLOW_PRIVATE_ADDRESSES=192.168.1.0/24,10.0.0.0/8

This approach:

  • Provides granular control over allowed private addresses
  • Aligns with Mastodon's implementation
  • Reduces security risks by limiting the scope

Would you like assistance in implementing this feature?

🧰 Tools
🪛 Biome

[error] 112-112: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)


⚠️ Potential issue

Document security implications and simplify environment variable access.

The ALLOW_PRIVATE_ADDRESS environment variable controls SSRF protection. Consider:

  1. Adding a security notice in the code.
  2. Simplifying the environment variable access.

Apply this diff:

-  allowPrivateAddress: process.env["ALLOW_PRIVATE_ADDRESS"] === "true"
+  // SECURITY: Enabling private addresses allows federation with internal network endpoints.
+  // Only enable this in trusted environments where internal federation is required.
+  allowPrivateAddress: process.env.ALLOW_PRIVATE_ADDRESS === "true"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
allowPrivateAddress: process.env["ALLOW_PRIVATE_ADDRESS"] === "true"
// SECURITY: Enabling private addresses allows federation with internal network endpoints.
// Only enable this in trusted environments where internal federation is required.
allowPrivateAddress: process.env.ALLOW_PRIVATE_ADDRESS === "true"
🧰 Tools
🪛 Biome

[error] 112-112: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)


💡 Codebase verification

Environment variable ALLOW_PRIVATE_ADDRESS requires documentation

The ALLOW_PRIVATE_ADDRESS environment variable is used in federation configuration but lacks documentation about its security implications. This variable appears to control whether private addresses are allowed in federation, which could have significant security ramifications.

Required actions:

  • Add documentation for ALLOW_PRIVATE_ADDRESS in the environment variables documentation at docs.hollo.social/install/env/
  • Include security implications and recommended settings
  • Consider adding a warning if enabling private addresses in federation context
🔗 Analysis chain

Verify environment variable documentation.

Let's ensure the security implications and configuration options are properly documented.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if ALLOW_PRIVATE_ADDRESS is documented
echo "Checking documentation for ALLOW_PRIVATE_ADDRESS..."
fd -e md -e env.example -e env.sample | xargs rg -i "ALLOW_PRIVATE_ADDRESS"

# Check for any security documentation
echo -e "\nChecking for security documentation..."
fd -e md | xargs rg -i "security|ssrf|private.*address"

Length of output: 339


Script:

#!/bin/bash
# Let's check for any environment variable documentation in common locations
echo "Checking for env documentation in README and docs..."
fd "README|env|configuration" -e md | xargs cat

# Check for .env files or examples
echo -e "\nChecking for .env files or examples..."
fd -e env -e env.example -e env.sample -e env.template | xargs cat

# Check the actual usage context
echo -e "\nChecking usage context..."
rg -B 3 -A 3 "ALLOW_PRIVATE_ADDRESS"

Length of output: 2568

🧰 Tools
🪛 Biome

[error] 112-112: The computed expression can be simplified without the use of a string literal.

Unsafe fix: Use a literal key instead.

(lint/complexity/useLiteralKeys)

@HelgeKrueger
Copy link
Contributor Author

It is strange when I run biome, there is no erro rrmessage ...

docker compose run --rm hollo bunx biome check
WARN[0000] The "LOG_LEVEL" variable is not set. Defaulting to a blank string. 
WARN[0000] The "BEHIND_PROXY" variable is not set. Defaulting to a blank string. 
WARN[0000] The "SECRET_KEY" variable is not set. Defaulting to a blank string. 
[+] Creating 3/0
 ✔ Container hollo-minio-1          Running                                                                                                                         0.0s 
 ✔ Container hollo-postgres-1       Running                                                                                                                         0.0s 
 ✔ Container hollo-create-bucket-1  Created                                                                                                                         0.0s 
[+] Running 1/1
 ✔ Container hollo-create-bucket-1  Started                                                                                                                         0.2s 
Checked 77 files in 1322ms. No fixes applied.

@dahlia
Copy link
Owner

dahlia commented Oct 30, 2024

These errors came from TypeScript (bunx tsc):

src/federation/index.ts(112,36): error TS4111: Property 'ALLOW_PRIVATE_ADDRESS' comes from an index signature, so it must be accessed with ['ALLOW_PRIVATE_ADDRESS'].
src/index.tsx(34,48): error TS4111: Property 'LISTEN_PORT' comes from an index signature, so it must be accessed with ['LISTEN_PORT'].

@HelgeKrueger
Copy link
Contributor Author

HelgeKrueger commented Oct 30, 2024

Sorry, for needing so many tries to get everything working. I still cannot get biome working in the docker environment. But it works on the host. Not sure what is going on.

As far as tsc, I get the errors. Are they expected?

/app # bunx tsc
src/components/AccountForm.tsx:28:11 - error TS2322: Type 'string' is not assignable to type 'HTMLAttributeFormMethod | undefined'.

28     <form method={props.method ?? "post"} action={props.action}>
             ~~~~~~

  node_modules/hono/dist/types/jsx/intrinsic-elements.d.ts:272:9
    272         method?: HTMLAttributeFormMethod | undefined;
                ~~~~~~
    The expected type comes from property 'method' which is declared here on type 'FormHTMLAttributes'

src/components/LoginForm.tsx:16:11 - error TS2322: Type 'string' is not assignable to type 'HTMLAttributeFormMethod | undefined'.

16     <form method={props.method ?? "post"} action={props.action}>
             ~~~~~~

  node_modules/hono/dist/types/jsx/intrinsic-elements.d.ts:272:9
    272         method?: HTMLAttributeFormMethod | undefined;
                ~~~~~~
    The expected type comes from property 'method' which is declared here on type 'FormHTMLAttributes'

src/components/OtpForm.tsx:12:11 - error TS2322: Type 'string' is not assignable to type 'HTMLAttributeFormMethod | undefined'.

12     <form method={props.method ?? "post"} action={props.action}>
             ~~~~~~

  node_modules/hono/dist/types/jsx/intrinsic-elements.d.ts:272:9
    272         method?: HTMLAttributeFormMethod | undefined;
                ~~~~~~
    The expected type comes from property 'method' which is declared here on type 'FormHTMLAttributes'

src/components/SetupForm.tsx:16:11 - error TS2322: Type 'string' is not assignable to type 'HTMLAttributeFormMethod | undefined'.

16     <form method={props.method ?? "post"} action={props.action}>
             ~~~~~~

  node_modules/hono/dist/types/jsx/intrinsic-elements.d.ts:272:9
    272         method?: HTMLAttributeFormMethod | undefined;
                ~~~~~~
    The expected type comes from property 'method' which is declared here on type 'FormHTMLAttributes'


Found 4 errors in 4 files.

Errors  Files
     1  src/components/AccountForm.tsx:28
     1  src/components/LoginForm.tsx:16
     1  src/components/OtpForm.tsx:12
     1  src/components/SetupForm.tsx:16

@dahlia
Copy link
Owner

dahlia commented Oct 31, 2024

Did you run bun install?

HelgeKrueger and others added 2 commits November 2, 2024 00:39
By setting

      BEHIND_PROXY: "true"
      HOLLO_PORT: 80
      ALLOW_PRIVATE_ADDRESS: "true"

one allows private addresses and runs on port 80.
@dahlia dahlia merged commit 72eb953 into dahlia:main Nov 1, 2024
4 checks passed
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.

3 participants