Project

General

Profile

Defect #44228 ยป 0001-Sanitize-NUL-bytes-in-filenames-when-uploading-attac.patch

Go MAEDA, 2026-07-03 04:26

View differences:

app/controllers/wiki_controller.rb
441 441
    extension = '.txt'
442 442
    # Keep this character set aligned with Attachment#sanitize_filename.
443 443
    # Unlike attachments, do not drop path-like components from wiki titles.
444
    sanitized_title = page.title.tr('\\', '_').gsub(/[\/?%*:|"'<>\n\r]+/, '_')
444
    sanitized_title = page.title.tr('\\', '_').gsub(/[\/?%*:|"'<>\n\r\x00]+/, '_')
445 445
    filename = "#{sanitized_title}#{extension}"
446 446
    dup_count = 0
447 447

  
app/models/attachment.rb
581 581
    just_filename = value.gsub(/\A.*(\\|\/)/m, '')
582 582

  
583 583
    # Finally, replace invalid characters with underscore
584
    just_filename.gsub(/[\/?%*:|"'<>\n\r]+/, '_')
584
    just_filename.gsub(/[\/?%*:|"'<>\n\r\x00]+/, '_')
585 585
  end
586 586

  
587 587
  # Returns the subdirectory in which the attachment will be saved
test/integration/api_test/attachments_test.rb
190 190
    assert_match /_test\.txt$/, attachment.diskfile
191 191
  end
192 192

  
193
  test "POST /uploads.json should sanitize NUL in :filename param" do
194
    set_tmp_attachments_directory
195
    assert_difference 'Attachment.count' do
196
      post(
197
        '/uploads.json?filename=hello%00world.txt',
198
        :headers => {
199
          "RAW_POST_DATA" => 'File content',
200
          "CONTENT_TYPE" => 'application/octet-stream'
201
        }.merge(credentials('jsmith'))
202
      )
203
      assert_response :created
204
    end
205

  
206
    attachment = Attachment.order(id: :desc).first
207
    assert_equal 'hello_world.txt', attachment.filename
208
  end
209

  
193 210
  test "POST /uploads.xml should not accept other content types" do
194 211
    set_tmp_attachments_directory
195 212
    assert_no_difference 'Attachment.count' do
test/unit/attachment_test.rb
509 509
    assert(
510 510
      Attachment.update_attachments(
511 511
        attachments,
512
        {2 => {:filename => 'newname?.txt'}}
512
        {2 => {:filename => "new\x00name?.txt"}}
513 513
      )
514 514
    )
515 515
    attachment = Attachment.find(2)
516
    assert_equal 'newname_.txt', attachment.filename
516
    assert_equal 'new_name_.txt', attachment.filename
517 517
  end
518 518

  
519 519
  def test_latest_attach
    (1-1/1)