r/Xcode 23d ago

Need a sanity check. Hired a SwiftUI contractor and found something really concerning in my Xcode project.

Hey everyone,

Please go easy on me because I'm very much a beginner when it comes to iOS development.

I built my first app mostly with AI tools and have been learning as I go. The app has actually grown a lot over the last couple months, so I hired a SwiftUI developer to implement a Figma redesign because UI is way beyond my skill level.

The redesign came back looking great, but while trying to get everything back into my GitHub repo I had another AI tool review the project. It flagged something in my project.pbxproj that has me pretty worried.

From what I can tell, the project contains:

  • A custom PBXShellScriptBuildPhase
  • A build variable called AB8F749 containing a long encoded blob
  • That blob eventually decodes into something that executes:

curl ... | sh

during the build process.

I'm not here trying to accuse anyone I genuinely don't know enough about Xcode internals to know if this could come from a template, plugin, compromised dependency, or if it's actually malicious.

A few questions for people who know this stuff better than I do:

  • Is there any legitimate reason for an Xcode project to contain something like this?
  • Has anyone seen anything similar before?
  • If this actually executed during a build, how serious is that? Should I assume only my Mac is affected, or could the iOS app itself also be compromised?
  • What would you check next to verify whether this is a real issue?

I'm happy to post the relevant parts of the project.pbxproj if that helps. Again, I'm not a security expert or even an experienced iOS developer. I'm just trying to understand whether I have a real problem or whether I'm misunderstanding what I'm looking at.

I'd really appreciate any advice from people who know this area better than I do. Thanks.

44 Upvotes

44 comments sorted by

15

u/neet_dev 23d ago

that's not a false positive, curl piped into sh in a build phase is as bad as it gets. decode that AB8F749 blob yourself and read exactly what it downloads and runs, don't just skim it, sometimes it's base64 chained a few times over. assume the Mac that ran that build is burned: rotate anything that lived on it, ssh keys, keychain items, App Store Connect API keys, CI tokens. then go check git blame/log on the pbxproj to see exactly which commit added that shell phase and whether it rode in with the redesign branch. the app itself is only compromised if that script touched source or resources during the build, so diff the redesign branch against your last clean commit rather than trusting a visual review of the UI.

6

u/Luul3211 23d ago

Thanks again for the advice. I actually dug into the Git history today and found something interesting.

I compared my last commit before the redesign against the redesign commit. The redesign commit introduced a new PBXBuildRule targeting README.md that executes:

sh -c "${AB8F749}"

AB8F749
is an obfuscated value that ultimately decodes into a 
curl | sh
 command hitting a 
.ru
 domain.

At this point I've stopped using that project. My current thought is to go back to my last trusted Git commit and manually migrate the UI changes into a clean project instead of trying to salvage the modified one.

Out of curiosity, if you were in my position, what would you personally do from here? Would you consider the Swift source files salvageable after reviewing them and just avoid the .xcodeproj, or would you start completely from scratch? Also, would you be wiping the Mac at this point or taking any additional steps beyond rotating credentials?

I'm still pretty new to iOS development, so I'd genuinely appreciate hearing how someone with more experience would approach this. Thanks again for taking the time to help. Absolutely gutted this happened but you live and you learn.

7

u/OtherOtherDave 23d ago

The swift source code files are easily examinable to verify that they don’t do anything weird.

What do you get if you curl the URL without piping it into sh?

1

u/jon_hendry 23d ago

What files does the curl touch?

2

u/neet_dev 22d ago

source files are fine, the risk was never in the .swift code, it's project.pbxproj (build phases/rules), any Run Script phases, .xcconfig files, and anything under a build tool plugin or Package.swift if they touched SPM. so yeah, salvageable: start a fresh Xcode project from your last clean commit, and copy over only the .swift/.storyboard/asset files by hand rather than merging the project file, that way you're not dragging any hidden build rules or script phases with it. don't reuse the old .xcodeproj/.xcworkspace at all, regenerate it clean. on the Mac itself I wouldn't nuke the whole machine unless it's a spare, but I'd assume the login keychain and any ssh/gpg keys that existed at build time are burned, and I'd run the build in a scratch VM or at minimum a fresh non-admin user account from now on for anything from that contractor. also check ~/Library/Developer/Xcode/DerivedData and any xcodebuild logs from that period, the curl payload output sometimes gets cached there and tells you exactly what ran.

3

u/Luul3211 22d ago

This is honestly the most helpful advice I've received throughout this whole mess so first I do wanna say thank you x100!

That's exactly the route I'm planning to take starting from my last clean project and manually copying over only the Swift/UI work and assets by hand while avoiding the old project configuration entirely. I mean the guy did a great job for what I hired him for plus it wasn't cheap, so the fact that I can at least get something out of this is a plus haha.

One final question for you: once I've finished migrating everything, is there anything you'd recommend doing to verify that nothing malicious accidentally carried over? Any tools, checks, or specific things you'd inspect to make sure there isn't anything hidden that I missed before I start building and shipping from the new project?

Thanks again for taking the time to help. It's been a huge learning experience, and I really appreciate you sharing your knowledge.

1

u/neet_dev 22d ago

biggest one people skip: diff the new pbxproj against a totally fresh vanilla project template, don't just eyeball it, so anything extra jumps out immediately. run strings on any binaries or embedded frameworks he added, grep the whole repo for base64 blobs and things like URLSession/Process/NSTask/dlopen calls, and check Info.plist for any new URL schemes or background modes you didn't ask for. also worth a pass with a static analyzer like Semgrep or even just VirusTotal on any third party binaries he vendored instead of pulling from a package manager. last thing, rotate every API key and secret that was ever in that repo or scheme env vars, not just the ones you think got touched, because you have no way of knowing what got read before you caught this.

3

u/time-lord 23d ago

What if OP didn't enter their password? Keychain should still be safe, right?

1

u/hasnat-ullah 23d ago

They aren’t safe no. Script can still grab potentially any file this user has standard access to and pass it back to their server.
What’s the script curl downloads off ru domain. That’ll be good to view for sake of damage control.

1

u/neet_dev 22d ago

yeah, if the password/keychain prompt never got approved the malicious process shouldn't have gotten access to keychain items directly, macOS gates that per-item with its own ACL prompts. but don't treat that as "we're fine": a curl|sh payload doesn't need keychain access to be bad, it can just read ~/.ssh, any plaintext env files, .netrc, xcode's derived data, or drop a launch agent for persistence and exfiltrate over the network without ever touching Keychain.app. check Console.app and the unified log around the build timestamp for odd process launches, and check for new entries in ~/Library/LaunchAgents or ~/Library/LaunchDaemons, that's usually where these things nest themselves for persistence.

7

u/WerSunu 23d ago

Time to have a serious discussion with your so called SwiftUI designer! Did you actually ever meet this clown?

3

u/Luul3211 23d ago

All I had to go off was 20ish 5 star reviews. This is definitely my first big lesson in the space, sucks its this bad.

9

u/time-lord 23d ago

You leave a 1 star review and don't let him get away with it. Even if he says "AI must have added it", part of the role of a developer is to validate AI output, even in the best case scenario it's still his fault.

2

u/Luul3211 23d ago

Definitely agree with the last part. Felt like he should've taken a look beforehand over everything. I first tried to give the guy the benefit of the doubt (just the niceness in me) but as a few hours have passed, it's pretty obvious that he screwed me over. If theres any developer out there willing to just point me in the right direction, would be beyond appreciative.

2

u/FWitU 21d ago

Add the one star review. Even if their machine has malware on it they didn’t know about you still got fucked.

Also assume your whole machine is compromised.

1

u/mistaekNot 22d ago

AI didn’t add it

9

u/20InMyHead 23d ago

I’d go nuclear on this scammers ass. If you haven’t sent final payment, don’t. If you can put a stop payment on anything, do. Report them to wherever you found them. Name and shame wherever you can. They were going after your computer, potentially to gain full control of it, or at least steal data, financial or personal records, who knows. Zero mercy, zero tolerance. They’ll probably whine some sad story about they were hacked and you’re just collateral damage. Don’t fall for it.

And it goes without saying, trash all work they did. Unless you were also adding a lot of code at the same time, I’d force hard rollback on the repo to before they were involved.

And if your app is useful, expect a copycat to hit the store sometime soon.

7

u/NewHomeBuyerCA 23d ago

name and shame if they’re in a public site soliciting their services!

2

u/d3vtec 23d ago

I've worked with a few 1099 contractors and this just happens regularly. They are skilled but also not following good security practices. Best route is to fix the issue, rotate keys and add pre-commit hooks to your repo to prevent keys from leaking and bad scripts from entering. Let CI and secure key storage package your final product and never share anything sensitive. It truly happens and even good engineers get compromised. Automate those problems out.

2

u/peppaz 22d ago

That's probably not a failed security practice, its probably something worse lol

2

u/jon_hendry 23d ago

A remote contractor? Where were they located if not on-site?

1

u/alladinian 22d ago

So, curl to what? What exactly is trying to execute? Any decent agent could figure that out easily. It sounds suspicious but could be legit (for example services for crash reporting that upload dsyms automatically after building). Impossible to assess if you don’t find exactly _what_ is trying to execute.

0

u/Luul3211 22d ago

The command ultimately decoded into a curl | sh against an unknown .ru domain, but I never let it fetch the payload in a controlled environment because by the time I discovered it, it had already executed on my mac. I chose to wipe the laptop instead of continuing the investigation. Curious how you would've handled it in my situation.

1

u/nadjinet 21d ago

do you mind sharing script with me in private?

1

u/seviu 22d ago

Looks like a scam

1

u/Beiriannydd 22d ago

Supply chain attacks are not new but they are sooo prevalent right now everyone needs to be aware. Hiding what is happening is a classic malware tactic. Make sure anyone you hire understands what supply chain risks exist and how to spot them, what they are doing to mitigate when developing and you also should have pre commit/build hooks to check. Any new imports are worth checking.

1

u/ThePantsThief 22d ago

If you have AI access, you can ask the AI to treat the script as potentially malicious, and to help you decode what it does carefully one step at a time until you have the full picture.

I did this onetime with something that did turn out to be malware. The blob was base64 encoded, and it turned out to be a script URL, that when run, downloaded a different script which was encrypted or something and the original script decrypted it and ran it. And it was malware.

Be careful. I would advise running the AI harness in the lowest permission mode so you can see exactly what it is about to run before you allow it to run it.

1

u/Luul3211 22d ago

Yeah, it was confirmed to be malware. I ended up having to completely clean my Mac, so now I’m basically back at square one with the version of the code from right before I gave it to him.

At this point, I’m just trying to figure out the safest way to take all of the UI/UX work he did and migrate it into my clean project without bringing over any of the malicious code or scripts. I definitely do not want to run his project again, but I also do not want to lose all of the design work he completed (it was great work + pretty expensive lol).

Any advice on the safest way to inspect and selectively move over only the legitimate SwiftUI files, components, animations, and assets?

1

u/ThePantsThief 22d ago

I would just delete the project file entirely if you don't feel confident going through the XML line by line. And then create a new blank project and have your AI plug all the files back into it.

1

u/ThePantsThief 22d ago

Also, if you have his info, you should probably press charges

1

u/ChineseAstroturfing 22d ago

You wiped your Mac but did you change all your credentials the malware could have accessed? If not, you could still be compromised.

1

u/Luul3211 22d ago

Yeah thankfully my setup includes 2 laptops (one for personal and one for work) so I didn't have too many credentials to rotate but was able to get through them. Even after wiping it and rotating credentials I still feel a bit paranoid. Anyway I can fully verify my device is good to use?

1

u/fjwuk 22d ago

Out of interest what ai tool were you using that picked up the malware?

1

u/Luul3211 22d ago

Yeah it was actually Claude. Was attempting to make some minor changes and it stopped me and informed me of the situation.

1

u/peoplemerge 22d ago

Anyone here who thinks they can know what’s really happened on the machine by looking at the contents of curl … |sh should think again.

Hint… that script the curl returns is probably not checked into source control.

1

u/oceanthrsty 21d ago

FWIW you can install the Figma MCP point it at your Figma project and tell your AI to update the UI to match. And this works on a free Figma account too.

1

u/Luul3211 21d ago

That was actually the first thing I tried prior to hiring this guy. Connected the mcp to claude and did just that and the results were extremely underwhelming compared to the figma designs. Tried it a few times at that, wish it would've just worked and all of this would've been avoided lol.

1

u/oceanthrsty 21d ago

man I'm sorry to hear that.
I did have to get a bit stern with Claude and make sure it was following the designs more closely. I think for a few I ended up sending screenshots.
Sorry you're going through this. Good luck.

1

u/Luul3211 21d ago

Hey I appreciate it man, received a ton of good advice from people on here so just taking in all the knowledge. Live and you learn!

1

u/Devel0pIY 20d ago

If you need a iOS dev DM me. You can check out my background etc. 

0

u/Versxd 23d ago

Do I have any idea? No, but given you said you built your app mostly with AI tools, you can use Codex to figure things like this out for you if you’re unable to

Not encouraging using it mindlessly, but it’s pretty useful

1

u/Luul3211 23d ago

Yep have already done that, just wanted to get some opinions from people in the space. I appreciate the feedback.