Live data from Hacker News

WordPress security plugin Hide My WP addresses SQL injection, deactivation flaws

portswigger.net

41–50 of 54 posts

Re: WordPress security plugin Hide My WP addresses SQL injection, deactivation flaws

#41

This is one of those types of things that shouldn’t happen anymore, but does. 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.

>I’m pretty sure that WordPress now has their own low-level version of PDO Prepared Statements.

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.

Re: WordPress security plugin Hide My WP addresses SQL injection, deactivation flaws

#42
post #11

Earlier quoted context omitted.

There isn't, at least not really, since webapps are designed as full-service kiosks: all of the data management, user management and access control are supposed to be handled from the same console. If you want the database to enforce access controls, then every user must exist as a separate entity in the database, which is good, but then the webapp also needs the permissions to manage user accounts in the database, w…

I have experimented with a design that only allows the application to access a set of stored procedures via it's SQL user. 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 st…

My current project is maintenance for a large system built of shared procedures.

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.

Re: WordPress security plugin Hide My WP addresses SQL injection, deactivation flaws

#43

SQL injection draws attention to the fact that almost all web applications run as root, in regards to the most important asset: the data. 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?

SQL injections for me are solved problem.

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.

Re: WordPress security plugin Hide My WP addresses SQL injection, deactivation flaws

#44

Earlier quoted context omitted.

I have experimented with a design that only allows the application to access a set of stored procedures via it's SQL user. 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 st…

My current project is maintenance for a large system built of shared procedures. 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…

I agree it would require a great deal more discipline to implement then the alternatives. I can do it by myself, just takes about twice as long to do over the normal way, but with a team it would be a nightmare.

Re: WordPress security plugin Hide My WP addresses SQL injection, deactivation flaws

#45
post #41

This is one of those types of things that shouldn’t happen anymore, but does. 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.

>I’m pretty sure that WordPress now has their own low-level version of PDO Prepared Statements. 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.

Ah ... well, it's better than nothing.

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.

Re: WordPress security plugin Hide My WP addresses SQL injection, deactivation flaws

#46

Earlier quoted context omitted.

I have experimented with a design that only allows the application to access a set of stored procedures via it's SQL user. 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 st…

My current project is maintenance for a large system built of shared procedures. 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…

I'm unfamiliar with T/SQL but of those issues seem like fundamental limitations of stored procedures, just implementation details that need updating. Why is there no way to do it?

Re: WordPress security plugin Hide My WP addresses SQL injection, deactivation flaws

#47

Earlier quoted context omitted.

My current project is maintenance for a large system built of shared procedures. 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…

I'm unfamiliar with T/SQL but of those issues seem like fundamental limitations of stored procedures, just implementation details that need updating. Why is there no way to do it?

Of course, everything is possible, but resources are limited and so it matters that it's harder and requires ongoing effort to keep this right.

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

Re: WordPress security plugin Hide My WP addresses SQL injection, deactivation flaws

#48
post #11

SQL injection draws attention to the fact that almost all web applications run as root, in regards to the most important asset: the data. 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?

There isn't, at least not really, since webapps are designed as full-service kiosks: all of the data management, user management and access control are supposed to be handled from the same console. If you want the database to enforce access controls, then every user must exist as a separate entity in the database, which is good, but then the webapp also needs the permissions to manage user accounts in the database, w…

Even in a monolith, scope can be managed. I've worked on an application where a specific subset of endpoints used a different data source that was configured with different credentials, attached to a read-only user. Without code execution, these systems were reasonably fool-proof.

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.

Re: WordPress security plugin Hide My WP addresses SQL injection, deactivation flaws

#49
post #36
post #23

Earlier quoted context omitted.

If you're able to inject SQL, and the return value of the SQL query is not directly displayed to the user, you may use a timing-based side channel to exfiltrate data. 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 measure…

We're there any actual timings attacks executed like this? I'm talking about stack "attacker => internet => reverse-proxy => app => database", not extracting data over LAN from exposed app.

Yes, that's one way to extract data by (ab)using a blind sql injection vulnerability.

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...

Re: WordPress security plugin Hide My WP addresses SQL injection, deactivation flaws

#50
post #37

This is ridiculous. SQLi is a dumb problem and any development environment worth using should make it trivial to avoid. All you have to do is never allow SQL queries to be formed using string concatenation. Or if you do, make sure you're excruciatingly strict about it. 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 conc…

In WordPress the string concatenation in SQL is normal, even on the very first example: $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.wor…

Or even better if they didn't treat tables like confetti. I haven't analysed the wordpress schema closely but on first blush it looks like a hacky premature optimisation to solve a problem, either one of performance, or data isolation, or to avoid unravelling use of magic numbers.

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"
Post reply on HN