I recently added a new project to our issue tracker, which is Redmine. When creating a project, you give it a name and an identifier (which are often the same). There is a note when creating the project that you cannot change the identifier once it has been set. For this reason I was very careful to choose a generic identifier. Unfortunately, I wasn't careful enough and I spelled it wrong! The misspelled identifier appears in the issue tracker URLs. These will be seen by other developers and another company we are working with, so it's a very embarrassing mistake.
So I'm looking for suggestions as to how to fix this. Either Redmine-specific, or something I can do at the database level (which is MySQL).
I've already found a solution that I will probably go with, but I thought it would be worth asking here anyway. I'm hoping someone can offer a simpler solution - maybe a magically SQL one-liner.
The solution I've found is this:
Dump the database to SQL (using mysqldump)
search and replace with sed or a text editor
recreate the database from this SQL.
Thanks for any suggestions.
Turns out it was as simple as:
update `projects` set `identifier` = '[NEWNAME]' where `indentifer` = '[OLDNAME]';
If the identifier is just confined to some column or set of columns, you can use:
update [table] set [field] = replace([field],'[find]','[replace]');
Replace the bracketed text with the identifiers in your case, as appropriate.
Related
I understand the basic process of SQL injection attack. My question is related to SQL injection prevention. I was told that one way to prevent such an attack is by frequently changing the table name! Is that possible?
If so, can someone provide me a link to read about it more because I couldn't find an explanation about it on the web.
No. That makes no sense. You'd either have to change every line of code that references the table or you'd have to leave in place something like a view with the old table name that acts exactly like the old table. No reasonable person would do that. Plus, it's not like there are a ton of reasonable names for tables so you'd be doing crazy things like saying table A stores customer data and AA stores employer data and AAA was the intersection between customers and employers.
SQL injection is almost comically simple to prevent. Use prepared statements with bind variables. Don't dynamically build SQL statements. Done. Of course, in reality, making sure that the new developer doesn't violate this dictum either because they don't know any better or because they can hack something out in a bit less time if they just do a bit of string concatenation makes it a bit more complex. But the basic approach is very simple.
Pffft. What? Frequently changing a table name?
That's bogus advice, as far as "preventing SQL Injection".
The only prevention for SQL Injection vulnerabilities is to write code that isn't vulnerable. And in the vast majority of cases, that is very easy to do.
Changing table names doesn't do anything to close a SQL Injection vulnerability. It might make a successful attack vector less repeatable, requiring an attacker to make some adjustments. But it does nothing prevent SQL Injection.
As a starting point for research on SQL Injection, I recommend OWASP (Open Web Application Security Project)
Start here: https://www.owasp.org/index.php/SQL_Injection
If you run across "changing a table name" as a mitigation, let me know. I've never run across that as a prevention or mitigation for SQL Injection vulnerability.
Here's things you can do to prevent SQL injection:
Use an ORM that encapsulates your SQL calls and provides a friendly layer to your database records. Most of these are very good at writing high quality queries and protecting you from injection bugs simply because of how you use them.
Use prepared statements with placeholder values whenever possible. Write queries like this:
INSERT INTO table_name (name, age) VALUES (:name, :age)
Be very careful to properly escape any and all values that are inserted into SQL though any other method. This is always a risky thing to do, so any code you do write like this should have any escaping you do made blindingly obvious so that a quick code review can verify it's working properly. Never hide escaping behind abstractions or methods with cute names like scrub or clean. Those methods might be subtly broken and you'd never notice.
Be absolutely certain any table name parameters, if dynamic, are tested versus a white list of known-good values. For example, if you can create records of more than one type, or put data into more than one table ensure that the parameter supplied is valid.
Trust nothing supplied by the user. Presume every single bit of data is tainted and hostile unless you've taken the trouble to clean it up. This goes doubly for anything that's in your database if you got your database from some other source, like inheriting a historical project. Paranoia is not unfounded, it's expected.
Write your code such that deleting a line does not introduce a security problem. That means never doing this:
$value = $db->escaped(value);
$db->query("INSERT INTO table (value) VALUES ('$value')");
You're one line away from failure here. If you must do this, write it like so:
$value_escaped = $db->escaped(value);
$db->query("INSERT INTO table (value) VALUES ('$value_escaped')");
That way deleting the line that does the escaping does not immediately cause an injection bug. The default here is to fail safely.
Make every effort to block direct access to your database server by aggressively firewalling it and restricting access to those that actually need access. In practice this means blocking port 3306 and using SSH for any external connections. If you can, eliminate SSH and use a secured VPN to connect to it.
Never generate errors which spew out stack traces that often contain information highly useful to attackers. For example, an error that includes a table name, a script path, or a server identifier is providing way too much information. Have these for development, and ensure these messages are suppressed on production servers.
Randomly changing table names is utterly pointless and will make your code a total nightmare. It will be very hard to keep all your code in sync with whatever random name the table is assuming at any particular moment. It will also make backing up and restoring your data almost impossible without some kind of decoder utility.
Anyone who recommends doing this is proposing a pointless and naïve solution to a an already solved problem.
Suggesting that randomly changing the table names fixes anything demonstrates a profound lack of understanding of the form SQL injection bugs take. Knowing the table name is a nice thing to have, it makes your life easier as an attacker, but many attacks need no knowledge of this. A common attack is to force a login as an administrator by injecting additional clauses in the WHERE condition, the table name is irrelevant.
I read that it is best practise to have table names in Pascal Case (ThisIsMyTableName).
Therefor I would like to change my tables in MySQL. But neither phpmyadmin, nore SQL Manager 2005 for MySQL will let me. The names stay to appear in lowercase, as if I didn't to a change at all.
Any suggestions to solve this problem?
The easiest way to take care of this is to add the following to your .ini file
lower_case_table_names=2
2 is the significance here for Windows. You can read more about it here Identifier Case Sensitivity
I advice against mixed case because of problems with case sensitivity. A fully tested solution on one platform where case doesn't matter may actually fail when deployed on a platform where case DOES matter. For that reason alone I suggest sticking with either all caps or all lower case.
I use lower case because it is easier on the eye and make spelling errors easier to spot in fixed width fonts used in most editors.
Use RENAME
example:
RENAME TABLE this_is_my_table_name TO ThisIsMyTableName;
details : http://dev.mysql.com/doc/refman/5.1/en/rename-table.html
In MySQL, you can quote the table names everywhere to make them case preserving and sensitive.
`MyTableName`
In MS Access (2003), a column can have both a "name" (required obviously) and a "caption" (optional). It can also have a "description" (optional) and an "input mask".
The main advantage is that the column name can be code friendy (eg lower case with underscores), while the caption can be user friendly (eg title case / proper case, with spaces, or with completely different words).
If a column has a caption, then it is used by default in forms.
[Q1] Can this be achieved in MySQL? I'm most interested in the captions, but would also welcome advise re column linked description and input mask. I haven't searched re input mask yet.
I'd prefer to use an approach which can be implemented in almost any SQL database. So, the less proprietary, less hacky, and more "standard SQL" (sic) the approach, the better.
I note that, in MySQL, a column can have a "comment". I could use these, and use code to extract them when required. But (1) this is inconvenient and hacky and (2) it seems to me that the comment should be used for another purpose (eg notes to self or other developers, or to advise re data entry).
I'm currently using phpMyAdmin (via XAMPP), but I used MySQL Workbench previously.
I can't find any information about this on either of those sites or on Stack Overflow.
These keywords and links are related to the topic, but don't answer the question:
COLUMN_NAME
COLUMN_COMMENT
MS Access: setting table column Caption or Description in DDL?
MySQL query to get column names?
MySQL 5.7 Reference Manual :: 19 INFORMATION_SCHEMA Tables
Commenting your MySQL database... (yada yada)
Thanks in advance.
#Jim Garrison
Thanks for replying. I didn't vote for that answer because it's not doing a lot of what Access does. Not your fault though - you're just the messenger! I'm not sure how one should thank someone for their effort in Stack Overflow, since the comment area says not to use it for that purpose. Cheers anyway for the information.
I had an idea, although it too is far from ideal.
I could create a separate table to hold supplemental metadata (captions/aliases, descriptions, input masks etc) about all other tables in the database.
Its structure would be:
id | table_name | column_name | friendly_alias | description | input_mask
Unfortunately, it would be a chore to maintain, unless there would be a way of automatically populating it with table names and column names, and updating these values automatically if they were renamed, inserted or deleted.
It really would be much better if it were an extension of the built in information schema table(s) though, with null values allowed for those optional fields.
Could it be a separate table, but with a 1:1 relationship with the built in information schema table(s)?
Bear in mind that I'm an amateur enthusiast by the way!
There's nothing builtin that is easily usable without metadata queries. However, you can use column aliases and name-quoting to get whatever name you want, as in
select column_1 as `Date of Birth`,
column_2 as `Home Address`,
etc.
MySQL does allow comments, as you've noted, but you can't use them directly for queries. phpMyAdmin does show them, so if you're using phpMyAdmin that is the best solution/workaround.
However, I think you're over complicating things. This isn't the same as Access in that forms and labels are not automatically created as part of MySQL when you create a database/table. You've got to then write code (in whatever programming language you wish) to interact with that database. When you're writing code, especially standard SQL, you don't want to refer to table names like "address of the buyer", you'll want "address" because, well, that's how programming works and we programmers don't want to have to type the same long variable name again and again. And many systems choke on spaces. So in your application, you can display to the user "Please enter here the permanent shipping address of the buyer using the standard address scheme of their home country so that it's accepted by the postal service with minimal hassle", but there's no way you'd use that as a variable name. I hope this makes sense and isn't insulting; I'm just trying to demonstrate that your table names don't really correspond to anything the user sees. Access is a bit different because the program tries to make it easy for you to create a database structure and then quickly edit the form a user will use to insert or modify data. Therefore it makes a bit more sense to be able to provide a comment that it uses whenever referring to that field.
Anyway, you asked about keeping most to standard SQL, and the concept of referring to a table by a comment is nonstandard, so in the interest of being able to implement it in any database, I'd suggest using the table name in your queries.
Hope this helps a bit.
I'm using Sphinx to search MySQL.
One of the results Sphinx returns for a search is M*A*S*H, as in the hit television show.
The problem I'm facing is that M*A*S*H is returned for nearly any query made with Sphinx. I'm guessing this is due to the asterisks. If not, then what could the problem be?
If the asterisks are causing my problem, how can I work around this to not have M*A*S*H returned for every query?
Make sure that asterisks are included in the charset_table.
charset_table = <blah blah blah>, U+002A
http://sphinxsearch.com/docs/current.html#conf-charset-table
Does this Sphinx function (EscapeString) do what you want
This problem no longer seems to exist, though I don't know why. I'm sure that something must have been amiss in my sphinx.conf. If someone else has this issue, let me know here and I'll try to update this answer accordingly.
In any case you can use the exceptions file to specify any word you may want to include in your searches. Remember to reindex whenever you change the file.
You can read the details here: http://sphinxsearch.com/docs/1.10/conf-exceptions.html
I have to hack a content management system to support fulltext search for a language that contains special characters. These are stored in the database as html entities. Out of the box, the CMS doesn't support it. The bug was reported long time ago, but apparently it has no priority. I'm stick to this CMS, the customer is awaiting my solution, so I have to hack it. Damn...
Ok... the CMS stores it's content by translating special characters into html entities (this is actualy done by the bundled editor). So the german word "möchten" gets "möchten" in the DB. The CMS creates a query string like
SELECT * FROM `SiteTree` WHERE MATCH( Content ) AGAINST (<SEARCH_STRING> IN BOOLEAN MODE);
The table is of type MyISAM, the field has a FULLTEXT index.
If you use "möchten" as search string, MySQL will match every page, as & is a operator that will do crazy things if it's present in the search string. The search will not work.
Next idea is to replace the special character by an * as placeholder. But this will also match several words, as soon as you have anything starting with an "m" and another following word ending with an "chten". I don't know why, but replacing only the ampersand with an asterisk (so searching for "m*ouml;chten") will also lead to similar results.
The same problem was described here.
Ok, folks, I need your help! Any ideas?
Edit: Converting the content to UTF-8 is no option.
Thanks!
craesh
Why you're using html entities? Just switch to utf8.
Otherwise try to quote your search string once again like ('"search"').
Unfortunately won't work - http://bugs.mysql.com/bug.php?id=26265 there is a long hanging bug. I guess the only approach is:
And last approach is to store additional column just for search purpose with all accents replaced.
You can use a full-text-search engine. Apache Lucene is powerful, but a bit hard to learn. Apache Solr is much easier to learn, and can be quite useful. Sphinx is known for its easy integration with MySQL. I believe all of them handle internationalization well.