Skip to content

Repository files navigation

SecureQueryItem

🔐 SecureQueryItem makes it easy to secure sensitive API parameters.

SwiftPM compatibleSwiftPlatformLicense: MIT

Purpose

When working with APIs that require partial (field-level) encryption — where some parameters must be encrypted while others stay in plain text — developers often end up managing two separate dictionaries:

  • values (e.g, ["username": "Alice", "password": "Hello, Bob!"])
  • encryption flags (e.g., ["username": "N", "password": "Y"])

This leads to repetitive, error-prone, and messy code.

Let’s say you’re building a login request between 🤷 Alice (the user) and 🧑‍💻 Bob (the server).
Meanwhile, 🕵️ Trudy, an attacker lurking on the network, is eager to intercept anything she can.

letparams:[String:String]=["username":"Alice","password":"Hello, Bob!"]letencryptionFlags:[String:String]=["username":"N","passwod":"Y"]

What happens?

  • 🕵️ Trudy, the attacker on the network, can now see Alice’s password in plaintext. Since "password" wasn’t marked for encryption (due to the "passwod" typo), it gets sent over the wire unprotected.
  • 🧑‍💻 Bob, the server, expects "password" to be encrypted. But he receives a plaintext field instead — or worse, never sees it at all because it’s named "passwod". He shrugs and returns an error, or maybe just logs something silently.
  • 🤷 Alice, the user, is left wondering why her login doesn’t work — unaware that her password was just exposed.

⚠️ The real danger?

This kind of bug doesn’t crash.
It compiles. It runs. It leaks data.
And unless you’re looking for it, you’ll never know.

SecureQueryItem solves this by:

  • Representing both plaintext and encrypted fields in a single dictionary
  • Automatically encrypting only the necessary fields before sending

Let the code guide you — just follow me.


Usage

Define parameters:

letparams:SecureQueryItem=["username":"Alice","password":.secure("Hello, Bob!")]

Define your crypto module:

finalclassMyCryptoModule:CryptoProvider{staticletshared=MyCryptoModule()privateinit(){}privatevar_text:String?func encrypt(_ plaintext:String){
// encrypt and store internally
}func getSecureText()->String{
// return the encrypted result
}func clear(){
// clear internal encrypted memory if needed
}func decrypt(_ ciphertext:String)->String{
// decrypt and return plain text
}}

Convert to encrypted [String: String]:

letbodyData=try?JSONEncoder().encode(
params.encrypted(using:MyCryptoModule.shared))

Now you're ready to pass bodyData to your URLSession request —
then just decrypt the response and you're done.

Task{varrequest=URLRequest(url:URL(string:"https://example.com/api")!)
request.httpMethod ="POST"
request.setValue("application/json", forHTTPHeaderField:"Content-Type")
request.httpBody = bodyData
do{let(data, response)=tryawaitURLSession.shared.data(for: request)
// handling HTTPURLResponse starts
// ...
// handling HTTPURLResponse ends
letenvelope=tryJSONDecoder().decode(SecureResponse.self, from: data)letdecryptedJson=MyCryptoModule.shared.decrypt(envelope.data)letpayload=tryJSONDecoder().decode(Payload.self, from:.init(decryptedJson.utf8))
// result handling
}catch{
// error handling
}}

Installation

SecureQueryItem is available via Swift Package Manager.

Using Xcode:

  1. Open your project in Xcode
  2. Go to File > Add Packages…
  3. Enter the URL:
https://github.com/dsunny90/SecureQueryItem
  1. Select the version and finish

Using Package.swift:

dependencies:[.package(url:"https://github.com/dsunny90/SecureQueryItem", from:"1.0.0")]

About

secure sensitive API parameters in Swift

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages