langgenius / langgenius/dify

Tool file URLs generated without signature parameters causing 400 validation errors

Open Beginner friendly
#39,222 2 comments 1 reaction 0 assignees View on GitHub
🐞 bug 1.16.0 project#dify
Dominant language
TypeScript
Stars
156k
Forks
24.6k
Avg merge
22h 9m
Merged PRs (30d)
610

Description

### Self Checks

- [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542).
- [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general).
- [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones.
- [x] I confirm that I am using English to submit this report, otherwise it will be closed.
- [x] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
- [x] Please do not modify this template :) and fill in all the required fields.

### Dify version

1.16.0

### Cloud or Self Hosted

Self Hosted (Docker)

### Steps to reproduce

**Bug**: Tool file URLs are being generated without required security parameters (timestamp,
nonce, sign), causing 400 validation errors when users try to access tool-generated files
(images, documents, etc.)
1. Use an agent or tool that generates files (e.g., image generation)
2. Let the tool complete and generate a file
3. Try to access/download the generated file
4. Observe 400 validation error

## Error Message

pydantic_core._pydantic_core.ValidationError: 3 validation errors for ToolFileQuery
timestamp
Field required [type=missing, input_value={}, input_type=dict]
nonce
Field required [type=missing, input_value={}, input_type=dict]
sign
Field required [type=missing, input_value={}, input_type=dict]

## Root Cause

The error occurs because tool file URLs are being generated **without using the
`sign_tool_file()` function**, which is responsible for adding required security parameters.

## Affected Code Locations

### 1. `/api/core/app/apps/base_app_runner.py` (Line ~447)

```python
# CURRENT (BUGGY):
url=f"/files/tools/{tool_file.id}",

# SHOULD BE:
url=sign_tool_file(tool_file_id=tool_file.id, extension=extension),

2. /api/core/tools/utils/message_transformer.py (Line ~204)

# CURRENT (BUGGY):
@classmethod
def get_tool_file_url(cls, tool_file_id: str, extension: str | None) -> str:
return f"/files/tools/{tool_file_id}{extension or '.bin'}"

# SHOULD BE:
@classmethod
def get_tool_file_url(cls, tool_file_id: str, extension: str | None) -> str:
return sign_tool_file(tool_file_id=tool_file_id, extension=extension or '.bin')

Evidence from Logs

Nginx Access Log:
GET /files/tools/44111312-4099-465c-ae7b-1e661dce50c4.png HTTP/1.1" 400 559

Note: URL is missing query parameters ?timestamp=...&nonce=...&sign=...

API Error Log:
File "/app/api/controllers/files/tool_files.py", line 52, in get
args = ToolFileQuery.model_validate(request.args.to_dict())
pydantic_core._pydantic_core.ValidationError: 3 validation errors for ToolFileQuery

Investigation Results

✅ Environment Variables: All correctly configured
- SECRET_KEY: Properly set and loaded
- FILES_URL: https://gpt.epuber.cn
- FILES_ACCESS_TIMEOUT: 300 seconds
- Aliyun OSS: Fully configured

❌ Code Issue: Two locations generate URLs without signing

Expected Behavior

According to /api/core/tools/signature.py, tool file URLs should be generated using
sign_tool_file() which adds cryptographic signature, timestamp, and nonce parameters for
security.

Impact

- User Impact: Tool-generated files (images, documents) cannot be accessed/downloaded
- Security: The validation is working correctly - preventing unauthorized access
- Functionality: Files are generated successfully but URLs are invalid
- #29620 (https://github.com/langgenius/dify/issues/29620) - Signature Verification Failure
- #14713 (https://github.com/langgenius/dify/issues/14713) - Plugin Signature Verification
Failed

Additional Context

This issue was discovered when investigating why tool-generated images were returning 400
errors. The investigation confirmed that:
- Environment configuration is correct
- SECRET_KEY is properly loaded across all services
- The issue is purely in the URL generation code

### ✔️ Expected Behavior

✔️ Expected Behavior

Tool-generated files should be accessible via signed URLs with proper security parameters:
- URL should include ?timestamp=...&nonce=...&sign=...
- Files should download/display correctly
- No validation errors should occur

### ❌ Actual Behavior

Tool-generated files return 400 validation errors:
pydantic_core._pydantic_core.ValidationError: 3 validation errors for ToolFileQuery
timestamp - Field required
nonce - Field required
sign - Field required

Nginx access log shows requests without query parameters:
GET /files/tools/44111312-4099-465c-ae7b-1e661dce50c4.png HTTP/1.1" 400 559

Root Cause Analysis

Two code locations generate tool file URLs without using the sign_tool_file() function:

1. /api/core/app/apps/base_app_runner.py (Line ~447):
url=f"/files/tools/{tool_file.id}", # Missing signature parameters
2. /api/core/tools/utils/message_transformer.py (Line ~204):
def get_tool_file_url(cls, tool_file_id: str, extension: str | None) -> str:
return f"/files/tools/{tool_file_id}{extension or '.bin'}" # Missing signature

Environment Configuration Verified ✅

- SECRET_KEY: Properly configured and loaded
- FILES_URL: https://gpt.epuber.cn
- FILES_ACCESS_TIMEOUT: 300 seconds
- Aliyun OSS: Fully configured
- All services running healthy

Impact

- Tool-generated images/files cannot be accessed
- Affects agents that generate visual content
- Security validation working correctly (preventing unauthorized access)

Related Issues

- #21068 - File expired in historical conversations
- #29620 - Signature Verification Failure and Plugins Not Appearing

Contributor guide

Open the contributing guide

Research direction

Start with the two affected locations: api/core/app/apps/base_app_runner.py and api/core/tools/utils/message_transformer.py. Read api/core/tools/signature.py and trace how tool file URLs are consumed by api/controllers/files/tool_files.py. Confirm generated URLs include timestamp, nonce, and sign parameters, then verify tool-generated files no longer return the reported 400 validation errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, security
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.