WordPress security plugin Hide My WP addresses SQL injection, deactivation flaws
portswigger.net
portswigger.net
It’s odd that this hasn’t got more attention. It should be easier to write backends that tie data access more closely to user credentials without the backend trying to enforce that itself. Is there anything out there that makes this easy to do?
That‘s largely a configuration problem. They don‘t have to run as root, most of the time.
Disadvantage with the Windows behavior is that a webservice running on said port has elevated permissions and if you surf the web with the same machine, a script inserted into a site could launch attacks against it. Of course the site itself could be malicious, in that case the CORS rule wouldn't do much.
Of course you are correct, running directly on port 80 might just be a bad idea, but for development purposes I might do that.
What usually happens is that the process only has the necessary capability for a brief period to open the port and drops it immediately before processing any requests.
https://www.postgresql.org/docs/current/ddl-rowsecurity.html
There are tricks you can use, such as implementing row-level security and tying it to some concept of end user identity, but even ignoring that ORM's don't understand or support RLS and developers therefore won't use it: it's still the same problem of letting the fox guard the henhouse. The webapp is the single control point for both user access and user administration (including self-service account creation and password reset), so whatever solution you come up with, the webapp will need to have super-user access to do that, and therefore if the webapp is compromised, your data-level access controls can be compromised too.
So, in order to even begin thinking about securing your data, the webapp should probably be split into multiple reduced-access microservices that handle different aspects of the webapp function. As long as we're talking about a single monolithic backend, any attempt at scope mitigation can (and likely will) be defeated.
- We have deadlines but they are not strict and very rarely somebody is going to even ping you outside work hours. People there want some discipline but they don't micromanage.
- The atmosphere is 95% of the time super chill.
- There are no egos flying around (not more than usual anyway; I scheduled a meeting to explain some coding style practices that should be painfully obvious but hey, trying not to judge here).
- Technical excellence is appreciated by a very technical and careful CTO -- but is indeed often sidelined in favor of deadlines and business-enabling work. However, I have already successfully fought him and the CEO off on 2-3 technical excellence tasks by demonstrating they'll reduce future slowdowns. Doable but requires some brawling in meetings.
- Pay is one of the biggest in EU (although it's like 1.5x - 2.0x less the than the US one).
---
> and the market signal of enough people doing it will improve conditions for everyone.
I keep hearing this and I want it to be true but for 20 years of career I've never seen it, not once. Nowadays I no longer believe it. Everywhere I worked (I am mostly a contractor so it has been a very colorful career) the business will stick to their idea of "we can always hire somebody else" with persistence that you'd be jealous of -- I don't know if it's an illusion or not but trust me, it's VERY persistent. That alone weakens the point you brought up because employers simply don't believe it and often times go out of their way to look for those other mythical people -- and I've been told in several occasions that the business closed doors before they managed to repair their clusterf_ck of an app. That's how persistent they are in their thinking process that everyone is expendable.
It seems to work, if you write complicated enough stored procedures you can enforce things like each entry must be created by a logged in user or whatever. Then the application is limited to interactions it's supposed to have, so it can't drop a audit table or something. I even did login via a stored procedure, confirming the hashed password matched and generating a bearer token that future stored procedures require to function.
In principle this feels like a reasonable strategy but chances are your stored procedures do not enjoy the same creature comforts as your "real" software. In my case they've got commented out code blocks, procedures with names ending V3.bak.tmpMar14.old, randomly different styles and formats from one to the next, and inconsistent naming (AllGroups allGroups or ag?). All of which would be quickly and easily prevented or retrospectively corrected in say C# or Java but there's no easy way to do it with the archaic T/SQL setup here.
Edited to add: I retrospectively realised the above comment had an auto-correct mistake where "easy way" had been misscorrected to "way way" and so it wasn't clear I meant only that it's needlessly harder
A plugin system where an plugin would be exposed to a different set of credentials shouldn't be too hard to set up with some middleware preparations. Such a system would require granting the main account complete database control (which is iffy) or would require a lot of manual configuration for user permissions (which sucks) but it's definitely something you can do in a monolith like WordPress.
Permissions wouldn't be as well-contained as in a proper, fragmented, micro-service-oriented permissions model, but it would be a good step forward and one that wouldn't necessarily break too much when done as a software update.
If your database supports writable views (e.g. via triggers) you can build parametric views.
Both are not plug-and-play modules in your framework and requires actual DBA, though.
E.g. in order to exfiltrate the string "Test123" you would go character-by-character, starting with the first character "T". For each ASCII character you would wait 10ms, as "T" is ASCII #84 [1] you'd sleep() for 84*10=840ms. This sleep() can be measured from the attacker side because the SQL query will block the HTTP response.
This way, without "seeing" a result, the attacker is able to return data.
[1] https://en.m.wikipedia.org/wiki/File:ASCII-Table-wide.svg
If you look at sqlmap [1], they offer two techniques for blind sql injection: boolean-based and time-based. Boolean-based should be used when the app just returns an error page (or not) based on your sql injection. The time-based approach should be used when no error page appears but the SQL is still executed.
But when I look at sqlmap docs for the time-based approach [2] I think I got the initial explanation wrong. It will do a 5 second delay if a certain condition is met, e.g. "Is the first character of the value an 'T'? If yes, wait 5 seconds; if not, return immediately". And then send hundreds of requests in parallel to iterate over all positions & possible characters.
[1] https://github.com/sqlmapproject/sqlmap/wiki/Usage#sql-injec... [2] https://github.com/sqlmapproject/sqlmap/wiki/Usage#seconds-t...
Frameworks and ORMs are making it easier on back-ends to tie data access to user credentials. The same with multi-tenancy if you use good framework with ORM you have all the tools to do filtering on higher level of abstraction. The same with referential consistency on database if it is there - ORM will help you to load data that is tied to that account. Making user like web app users on database level would make all development/ops really costly.
If someone is writing SQL queries directly, he has to have a good reason for it. Like if it is plugin for Wordpress it probably is not that easy to use ORM.
Most of the plugins that WP researchers look at are in the official repo with higher install counts, so it’s nice to see stuff like this get some code coverage among researchers.
Envato should really invest in their own automated and human vulnerability research. I think there’s probably a lot of badness out there among the commercial plugins but in many cases researchers have to buy the plugin to take a look.
I’m pretty sure that WordPress now has their own low-level version of PDO Prepared Statements. Also, they have a lot of even higher-level DB abstractions. I can’t think of any reason to directly access the DB from a plugin or theme.
Because it's PHP and it's easy.
We keep developing “nerf-world” languages, designed to protect ourselves from ourselves, and most fall down before they get a chance to even get going; mostly because they constrain, without empowering. I remember moving to Pascal, after using Assembly and Machine Code. It was very frustrating for me. Pascal was one of the earliest “safe” languages.
The problem is that we can’t build houses, using PlaySkool “Li’l Builder” toolsets.
Also, the WP Codex is really disorganized. It’s difficult to find anything in it, and that is deadly.
Geeks like to design clever architectures, but we hate to document them.
I imagine it's well tested, but it's a bunch of PHP escaping and regexes inside of wp-db.php. It is not at all real placeholders and prepared statements, though the functions are named that way. I suppose because there's too much tech debt to use normal placeholders.
For me, I always use PDO, and prepared statements and transactions. I get a lot of power, for free. I'm not a particularly good DB programmer, so I need all the help I can get.
There's a saying here that the shoemaker's children walk barefoot. I think this might not be an isolated phenomenon
I run a large-ish web application written in ColdFusion (more precisely, CFML running on the open source Lucee) which is a language where string concatenation is happening all the time. This is a very old language which will look embarrassingly janky compared to any of the new hotness in vogue on Hacker News. But even in CFML I can trivially guarantee zero SQLi by parameterising all variables.
Query parameters. They're a thing. If you don't know how your favourite programming language has implemented them, learn it. Use them.
In the rare instances where I do this, I'm analysing the full scope of potential valid variables. I then make local copies of the variables which have been pummelled with the narrowest possible regular expression, e.g.
slightly_safer = unsafe.replace(/[^0-9A-Za-z]/gi, '')
Stripping away all punctuation eliminates most forms of SQLi.When you're bringing in strings from outside, there's no such thing as being too paranoid. White-listing of permitted characters is the only safe approach. (And if you think your whitelist might ever need contain any kind of quote-mark, backtick or backslash, then you're wrong. Your table/identifier names are stupid and must change.)
$results = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}options WHERE option_id = 1", OBJECT );
This is because the database tables aren't static, so one must add prefix to each table from a variable. It's horrible, it would have been far better if there was magic string like %PREFIX% to avoid that.[1]: https://developer.wordpress.org/reference/classes/wpdb/#usin...
Realistically, content within the same "universe" should co-mingle in the same table. Multiple "universes" of content should be isolated into their own database/schema, which $wpdb should pre-select upon connection.
"SELECT * FROM options WHERE prefix = ? AND option_id = 241"> wpWave [adressed] both flaws in Hide My WP version 6.2.4, released on October 26.