SHA256
fix(ios): restrict authentication capabilities and validate bootstrap types
Require iOS 18.4 for explicit upload denial in the isolated authentication window. Add origin-bound generated download policy, app-switcher privacy, typed metadata regressions and original community icon assets. Seven portable tests and Swift formatting checks pass; Apple SDK validation remains external.
This commit is contained in:
1 parent
74c2c9e6e8
commit
69c48169e2
15 files changed
+341
-112
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import XCTest
|
||||
|
||||
@testable import Yuvomi
|
||||
|
||||
final class ServerAddressTests: XCTestCase {
|
||||
@@ -8,21 +9,32 @@ final class ServerAddressTests: XCTestCase {
|
||||
XCTAssertEqual(try ServerAddress("https://[::1]:8443").url.port, 8443)
|
||||
}
|
||||
func testUnsafeConfigurations() {
|
||||
for value in ["http://family.example", "javascript:alert(1)", "https://u:p@family.example",
|
||||
"https://family.example/subpath", "https://family.example?token=secret",
|
||||
"https://family.example/#token", "https://family.example:0",
|
||||
"https://family.example:65536", "https://family.example/%2f",
|
||||
"https://family.example\\@evil.test", "https:///", ""] {
|
||||
for value in [
|
||||
"http://family.example", "javascript:alert(1)", "https://u:p@family.example",
|
||||
"https://family.example/subpath", "https://family.example?token=secret",
|
||||
"https://family.example/#token", "https://family.example:0",
|
||||
"https://family.example:65536", "https://family.example/%2f",
|
||||
"https://family.example\\@evil.test", "https:///", "",
|
||||
] {
|
||||
XCTAssertThrowsError(try ServerAddress(value), value)
|
||||
}
|
||||
}
|
||||
func testOriginIsolation() throws {
|
||||
let server = try ServerAddress("https://family.example")
|
||||
XCTAssertTrue(server.owns(URL(string: "https://FAMILY.example:443/tasks?id=1")!))
|
||||
for value in ["https://family.example.evil.test", "https://family.example@evil.test",
|
||||
"https://user@family.example", "http://family.example", "https://family.example:8443",
|
||||
"file:///etc/passwd", "data:text/html,hi"] {
|
||||
for value in [
|
||||
"https://family.example.evil.test", "https://family.example@evil.test",
|
||||
"https://user@family.example", "http://family.example", "https://family.example:8443",
|
||||
"file:///etc/passwd", "data:text/html,hi",
|
||||
] {
|
||||
XCTAssertFalse(server.owns(URL(string: value)!), value)
|
||||
}
|
||||
}
|
||||
func testBlobExportsAreOriginBound() throws {
|
||||
let server = try ServerAddress("https://family.example")
|
||||
XCTAssertTrue(server.ownsDownload(URL(string: "blob:https://family.example/unique-id")!))
|
||||
XCTAssertFalse(server.ownsDownload(URL(string: "blob:https://evil.example/unique-id")!))
|
||||
XCTAssertFalse(server.ownsDownload(URL(string: "blob:http://family.example/unique-id")!))
|
||||
XCTAssertFalse(server.ownsDownload(URL(string: "file:///tmp/export")!))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import XCTest
|
||||
|
||||
@testable import Yuvomi
|
||||
|
||||
final class ServerMetadataTests: XCTestCase {
|
||||
private let bootstrap = Data(#"{"app_name":"Yuvomi","setup_required":false,"password_reset_enabled":true}"#.utf8)
|
||||
private let authentication = Data(#"{"enabled":false,"password_login_enabled":true}"#.utf8)
|
||||
func testAcceptsActualAnonymousMetadataWithoutVersion() throws {
|
||||
try ServerMetadata.validate(bootstrap: bootstrap, authentication: authentication)
|
||||
}
|
||||
func testRejectsNumericBooleanAndMissingAuthenticationMetadata() {
|
||||
let numeric = Data(#"{"enabled":1,"password_login_enabled":true}"#.utf8)
|
||||
XCTAssertThrowsError(try ServerMetadata.validate(bootstrap: bootstrap, authentication: numeric))
|
||||
XCTAssertThrowsError(try ServerMetadata.validate(bootstrap: bootstrap, authentication: Data("{}".utf8)))
|
||||
}
|
||||
func testRejectsProxyHtmlAndInvalidJson() {
|
||||
XCTAssertThrowsError(
|
||||
try ServerMetadata.validate(bootstrap: Data("<html>SSO proxy</html>".utf8), authentication: authentication))
|
||||
XCTAssertThrowsError(try ServerMetadata.validate(bootstrap: Data("null".utf8), authentication: authentication))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user