Skip to content

Commit aaba26e

Browse files
committed
Merge branch 'hidden_dotfiles'
2 parents e87a005 + ca0ec0e commit aaba26e

File tree

5 files changed

+29
-1
lines changed

5 files changed

+29
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
- New `unsafe_contents_md` property in the text component to allow rendering markdown with embedded HTML tags.
2525
- New `_sqlpage_footer` property for table rows. When applied, that row will be rendered as the table footer. It is recommended to use this on the last data row.
2626
- New `freeze_footers` property in table component. If the footer is enabled, this will make it always visible. Works similarly to `freeze_headers`.
27+
- Hidden files and folders (those with a name starting with a `.`) are now inaccessible. This allows you to easily create internal files to use with `sqlpage.run_sql(...)` that will not be directly accessible.
2728

2829
## 0.33.1 (2025-02-25)
2930

examples/official-site/sqlpage/migrations/38_run_sql.sql

+6-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@ select ''dynamic'' as component, sqlpage.run_sql(''common_header.sql'') as prope
2727
#### Notes
2828
2929
- **recursion**: you can use `run_sql` to include a file that itself includes another file, and so on. However, be careful to avoid infinite loops. SQLPage will throw an error if the inclusion depth is superior to `max_recursion_depth` (10 by default).
30-
- **security**: be careful when using `run_sql` to include files. Never use `run_sql` with a user-provided parameter. Never run a file uploaded by a user, or a file that is not under your control.
30+
- **security**: be careful when using `run_sql` to include files.
31+
- Never use `run_sql` with a user-provided parameter.
32+
- Never run a file uploaded by a user, or a file that is not under your control.
33+
- Remember that users can also run the files you include with `sqlpage.run_sql(...)` directly just by loading the file in the browser.
34+
- Make sure this does not allow users to bypass security measures you put in place such as [access control](/component.sql?component=authentication).
35+
- If you need to include a file, but make it inaccessible to users, you can use hidden files and folders (starting with a `.`), or put files in the special `sqlpage/` folder that is not accessible to users.
3136
- **variables**: the included file will have access to the same variables (URL parameters, POST variables, etc.)
3237
as the calling file.
3338
If the included file changes the value of a variable or creates a new variable, the change will not be visible in the calling file.

src/filesystem.rs

+5
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ impl FileSystem {
122122
status: actix_web::http::StatusCode::FORBIDDEN,
123123
});
124124
}
125+
if c.as_encoded_bytes().starts_with(b".") {
126+
anyhow::bail!(ErrorWithStatus {
127+
status: actix_web::http::StatusCode::FORBIDDEN,
128+
});
129+
}
125130
} else {
126131
anyhow::bail!(
127132
"Unsupported path: {path:?}. Path component '{component:?}' is not allowed."

tests/.hidden.sql

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
select 'text' as component, 'This is a hidden file that should not be accessible' as contents;

tests/index.rs

+16
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,22 @@ async fn test_request_body_base64() -> actix_web::Result<()> {
880880
Ok(())
881881
}
882882

883+
#[actix_web::test]
884+
async fn test_hidden_files() {
885+
let resp_result = req_path("/tests/.hidden.sql").await;
886+
assert!(
887+
resp_result.is_err(),
888+
"Accessing a hidden file should be forbidden, but received success: {resp_result:?}"
889+
);
890+
let resp = resp_result.unwrap_err().error_response();
891+
assert_eq!(resp.status(), http::StatusCode::FORBIDDEN);
892+
assert!(
893+
String::from_utf8_lossy(&resp.into_body().try_into_bytes().unwrap())
894+
.to_lowercase()
895+
.contains("forbidden"),
896+
);
897+
}
898+
883899
async fn get_request_to_with_data(
884900
path: &str,
885901
data: actix_web::web::Data<AppState>,

0 commit comments

Comments
 (0)