security: CORS preflight, session invalidation, CSRF on preview, symlink containment, and hardening
- Add OPTIONS /api/volumen/* for CORS preflight (S-22). - Invalidate session in require_login! when user no longer exists (S-8). - Add check_csrf! to POST /admin/preview (S-1). - Use File.realpath for symlink-safe containment in media_file (S-2). - Memoize Users#all with mtime-based invalidation (S-12). - Document that empty permitted_hosts means allow-all (S-5). - Warn and fall back to random when session_key is too short (S-20).
This commit is contained in:
@@ -263,6 +263,25 @@ class AdminTest < Minitest::Test
|
||||
assert_includes last_response.body, "Username unchanged"
|
||||
end
|
||||
|
||||
def test_preview_requires_csrf
|
||||
login
|
||||
get "/admin/posts/new"
|
||||
post "/admin/preview", "body" => "**hi**"
|
||||
assert_equal 403, last_response.status
|
||||
end
|
||||
|
||||
def test_orphaned_session_is_rejected
|
||||
login
|
||||
session_for = -> { rack_mock_session.cookie_jar["rack.session"].to_s }
|
||||
refute_empty session_for.call, "expected a session cookie after login"
|
||||
|
||||
# Simulate a deleted user by clearing users.toml while keeping the cookie.
|
||||
File.write(@users_path, "")
|
||||
get "/admin/"
|
||||
assert_equal 302, last_response.status
|
||||
assert_equal "http://example.org/admin/login", last_response.location
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def csrf(body)
|
||||
|
||||
Reference in New Issue
Block a user